I am trying to construct the raw transaction data based on a signed EIP-1559 transaction according to the EIP-1559 spec. However, it is not matching the value returned by web3py when signing a transaction. Below is a script I used to recreate the issue.
compute_raw_tx.py:
from web3 import Web3
import rlp
w3 = Web3(Web3.HTTPProvider(NODE_URL))
tx = {
'from': PUBLIC_KEY,
'nonce': w3.eth.get_transaction_count(PUBLIC_KEY),
'to': '0x0000000000000000000000000000000000000000',
'value': Web3.toWei(0.01, 'ether'),
'chainId': 5,
'gas': 50000,
'maxFeePerGas': Web3.toWei(500, 'gwei'),
'maxPriorityFeePerGas': Web3.toWei(200, 'gwei'),
'data': '0x0'
}
signed_tx = w3.eth.account.sign_transaction(tx, PRIVATE_KEY)
print(signed_tx)
encoded = rlp.encode([
hex(tx['chainId']),
hex(tx['nonce']),
hex(tx['maxPriorityFeePerGas']),
hex(tx['maxFeePerGas']),
hex(tx['gas']),
tx['to'],
hex(tx['value']),
tx['data'],
[],
hex(signed_tx['v']),
hex(signed_tx['r']),
hex(signed_tx['s'])
])
print(f'0x02{encoded.hex()}')
According to this post, I didn't quite have the correct types for all the values. Here is the working solution:
encoded = rlp.encode([
tx['chainId'],
tx['nonce'],
tx['maxPriorityFeePerGas'],
tx['maxFeePerGas'],
tx['gas'],
to_bytes(hexstr=tx["to"]),
tx['value'],
HexBytes(tx['data']),
[],
signed_tx['v'],
HexBytes(signed_tx['r']),
HexBytes(signed_tx['s'])
])
reconstructed_raw_transaction = f'0x02{encoded.hex()}'