Python

如何在 Python 中解碼原始交易?

  • November 24, 2021

我有一個十六進制格式的 raw_tx,我將通過eth_sendrawtransactionJSON-RPC 方法進行廣播。

我想通過在欄位上解碼來檢查這個 raw_tx:gas、gas_price、nonce、value 等。

幾年前,我已經在 JavaScript 中做到了。Python中有沒有可以做到這一點的庫?

我認為可以通過這個庫來做到這一點: https ://github.com/ethereum/pyrlp

但我還沒有找到乙太坊 tx 對象的結構。

程式碼:

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()

輸出:

{'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}

引用自:https://ethereum.stackexchange.com/questions/83802