Hello,
I’m a computer science student, I need to use HSM6 to sign transactions on Ethereum (on Rinkeby) in Python. Currently, I’m able to derive the keys according to the derivation path m/44’/60’/0’/0, but when I sign the transaction with the zymkey.client.sign() function to retrieve the VRS values to encode and send the transaction with the Web3 library, I get an error that tells me that the account has no funds. When I’m checking with the recover_transaction() function of the eth_account.account library before sending the transaction with web3, I get a different source address each time I run the program. Do you have any idea of a detail I might have missed?
Thanks,
Pedro
def ECDSA_Sign(Unsigned_Transaction: bytes, slot_key: int) -> Tuple[int, int, int]:
sha256 = hashlib.sha256()
transaction_hash = Unsigned_Transaction.hash()
sha256.update(transaction_hash.hex().encode("utf-8"))
flag = True
while(flag):
signed_tx, V_Data = zymkey.client.sign(transaction_hash.hex(), slot_key, True)
S: int = int.from_bytes(signed_tx[32:64], "big")
if(S < ((SECP256K1_SIZE)/2)):
flag = False
R: int = int.from_bytes(signed_tx[0:32], "big")
S: int = int.from_bytes(signed_tx[32:64], "big")
V: int = V_Data.value + 27
return R, S, V
def Sign_Transaction(UTransaction, Slot_Key: int) -> SignedTransaction:
r, s, v = ECDSA_Sign(UTransaction, Slot_Key)
encoded_transaction = encode_transaction(UTransaction, vrs=(v, r, s))
return SignedTransaction(
rawTransaction=HexBytes(encoded_transaction),
hash=HexBytes(UTransaction.hash()),
r=r,
s=s,
v=v,
)
if __name__ == "__main__":
web3: Web3 = Web3(Web3.HTTPProvider(URL))
Eth_Addr: str = Web3.toChecksumAddress(pubkey_to_addr(zymkey.client.get_public_key(CHILD_SLOT)))
print("Wallet address :", Eth_Addr)
unsigned_transaction = Create_Transaction(web3, Eth_Addr, ADDRESS_1, 0.0001, 2000000)
signed_transaction = Sign_Transaction(unsigned_transaction, CHILD_SLOT)
RecoverAdd = eth_account.account.Account.recover_transaction(signed_transaction.rawTransaction)
print("Transaction from " + RecoverAdd + " to " + ADDRESS_1)
tx_hash = web3.eth.sendRawTransaction(signed_transaction.rawTransaction)
print("\nTransaction Hash :\n", web3.toHex(tx_hash))