1

I have a raw_tx in hex format which I'm going to broadcast via eth_sendrawtransaction JSON-RPC method.

I want to check this raw_tx by decoding it on fields: gas, gas_price, nonce, value, etc.

Some years ago I already did it in JavaScript. Are there any libraries in Python which can do it?

I think it's possible to do it via this library: https://github.com/ethereum/pyrlp

But I haven't found there a structure of Ethereum tx object.

0

Code:

from dataclasses import asdict, dataclass
from pprint import pprint
from typing import Optional

import rlp
from eth_typing import HexStr
from eth_utils import keccak, to_bytes
from rlp.sedes import Binary, big_endian_int, binary
from web3 import Web3
from web3.auto import w3


class Transaction(rlp.Serializable):
    fields = [
        ("nonce", big_endian_int),
        ("gas_price", big_endian_int),
        ("gas", big_endian_int),
        ("to", Binary.fixed_length(20, allow_empty=True)),
        ("value", big_endian_int),
        ("data", binary),
        ("v", big_endian_int),
        ("r", big_endian_int),
        ("s", big_endian_int),
    ]


@dataclass
class DecodedTx:
    hash_tx: str
    from_: str
    to: Optional[str]
    nonce: int
    gas: int
    gas_price: int
    value: int
    data: str
    chain_id: int
    r: str
    s: str
    v: int


def hex_to_bytes(data: str) -> bytes:
    return to_bytes(hexstr=HexStr(data))


def decode_raw_tx(raw_tx: str):
    tx = rlp.decode(hex_to_bytes(raw_tx), Transaction)
    hash_tx = Web3.toHex(keccak(hex_to_bytes(raw_tx)))
    from_ = w3.eth.account.recover_transaction(raw_tx)
    to = w3.toChecksumAddress(tx.to) if tx.to else None
    data = w3.toHex(tx.data)
    r = hex(tx.r)
    s = hex(tx.s)
    chain_id = (tx.v - 35) // 2 if tx.v % 2 else (tx.v - 36) // 2
    return DecodedTx(hash_tx, from_, to, tx.nonce, tx.gas, tx.gas_price, tx.value, data, chain_id, r, s, tx.v)


def main():
    raw_tx = "0xf8a910850684ee180082e48694a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4880b844a9059cbb000000000000000000000000b8b59a7bc828e6074a4dd00fa422ee6b92703f9200000000000000000000000000000000000000000000000000000000010366401ba0e2a4093875682ac6a1da94cdcc0a783fe61a7273d98e1ebfe77ace9cab91a120a00f553e48f3496b7329a7c0008b3531dd29490c517ad28b0e6c1fba03b79a1dee"  # noqa
    res = decode_raw_tx(raw_tx)
    pprint(asdict(res))


if __name__ == "__main__":
    main()

Outputs:

{'chain_id': -4,
 'data': '0xa9059cbb000000000000000000000000b8b59a7bc828e6074a4dd00fa422ee6b92703f920000000000000000000000000000000000000000000000000000000001036640',
 'from_': '0xD8cE57B469962b6Ea944d28b741312Fb7E78cfaF',
 'gas': 58502,
 'gas_price': 28000000000,
 'hash_tx': '0xb808400bd5a1dd9c37960c515d2493c380b829c5a592e499ed0d5d9913a6a446',
 'nonce': 16,
 'r': '0xe2a4093875682ac6a1da94cdcc0a783fe61a7273d98e1ebfe77ace9cab91a120',
 's': '0xf553e48f3496b7329a7c0008b3531dd29490c517ad28b0e6c1fba03b79a1dee',
 'to': '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
 'v': 27,
 'value': 0}

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.