2

I'm working on an Ethereum wallet as part of a school project. I am currently trying to sign this example transaction: 0xec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080018080.

This is my code:

from Crypto.Hash import keccak
import rlp
import codecs
import ecdsa

# my ethereum address
addr = "0x1d67D36D8f7c2BBB600DE227E564f0cA5925544F"

# my private key (don't worry, it's just for testing)
pk_bytes = codecs.decode('23a3f8b9e35cc26bb70306ab313bcbbd3804e9d18bcb2f51a9b137bb8fe543e5', 'hex_codec')
sk = ecdsa.SigningKey.from_string(pk_bytes, curve=ecdsa.SECP256k1)

# the data i want to sign
rlp_bytes = codecs.decode('ec098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a764000080018080', 'hex_codec')

# keccak hashing the data
k = keccak.new(digest_bits=256)
k.update(rlp_bytes)
txHash = k.digest()

# getting the signature
sig = sk.sign(txHash)

# extracting r and s
r = int(sig[:32].hex(), 16)
s = int(sig[32:].hex(), 16)

# eip-2: If s is larger than secp256k1n / 2, set s = -s % secp256k1n
secp256k1n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
if s > secp256k1n / 2:
    s = secp256k1n - s
    v = 35 + 1 * 2 + 1  # mainnet chain id = 1
else:
    v = 35 + 1 * 2 + 0

# build signed transaction
signedTx = rlp.decode(rlp_bytes)
signedTx[6] = v.to_bytes(1, byteorder='big')
signedTx[7] = r.to_bytes(32, byteorder='big')
signedTx[8] = s.to_bytes(32, byteorder='big')

# rlp encode to get raw transaction
signedTxEncoded = rlp.encode(signedTx)
print("Raw transaction: 0x" + codecs.encode(signedTxEncoded, 'hex_codec').decode())

When we use an online tool to decode the resulting transactions (such as 0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a7640000802da00d5f27bbc8b38f04523f26f4e86e18e8b61126a55c23b11e615266a02017b8afa06193f48e5925fc9cbfdc8b0f651b3c8a118a0bd0054766522211cf819bc11b75), the tool displays an incorrect sender address. If I attempt to submit it to the blockchain, the transaction is rejected due to "insufficient funds" (because the random sender address doesn't own any eth). Since we're using a library for the ECDSA signing, we believe the issue might be with data formatting.

What am I doing wrong?

(I am not looking for recommendations of web3 or other Ethereum libraries; I have to do this the "hard" way).

1

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.