bargst / pyethoff

Python Ethereum Offline
MIT License
10 stars 4 forks source link

why the chainId is not defined before signing transaction for Ethereum? #5

Open gbalabasquer opened 6 years ago

bargst commented 6 years ago

Because at the time I developed this soft, chainID was not required I thinks ! Maybe it is time to update this project ...

gbalabasquer commented 6 years ago

Yeah, I've realized later that the chainID was added in EIP155.

gbalabasquer commented 6 years ago

I made it to work: Instead of using

tx = Transaction(
    tx.nonce, tx.gasprice, tx.startgas, tx.to, tx.value, tx.data
)
tx.sign(k)

Use:

tx = Transaction(
    nonce=tx.nonce, gasprice=tx.gasprice, startgas=tx.startgas, to=tx.to, value=tx.value, data=tx.data, v=chainId, r=0, s=0
)
rawhash = utils.sha3(rlp.encode(tx))

if len(k) == 64:
    # we need a binary key
    k = encode_privkey(k, 'bin')

pk = PrivateKey(k, raw=True)
signature = pk.ecdsa_recoverable_serialize(
    pk.ecdsa_sign_recoverable(rawhash, raw=True)
)
signature = signature[0] + utils.bytearray_to_bytestr([signature[1]])
tx.v = utils.safe_ord(signature[64]) + 27
tx.r = big_endian_to_int(signature[0:32])
tx.s = big_endian_to_int(signature[32:64])

tx.v += int(web3.version.network) * 2 + 8

tx.sender = utils.privtoaddr(key)

I'm not sending the PR as I'm working on a different project, but that piece of code should work for yours.