You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

构建已签名EIP-1559交易载荷:与web3py结果不符问题排查

问题原因与修复方案

你手动构造EIP-1559交易原始数据时,核心错误在于RLP编码时传入了hex字符串而非原始数值/字节数据——RLP会把字符串本身当作编码对象,而非对应数值的字节形式,导致最终结果和web3py生成的不一致。

修复后的代码

from web3 import Web3
import rlp
from eth_utils import to_bytes

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)

# 正确的RLP编码字段:使用原始整数或字节,而非hex字符串
encoded = rlp.encode([
    tx['chainId'],  # 直接传入整数chainId
    tx['nonce'],    # 传入整数nonce
    tx['maxPriorityFeePerGas'],  # 传入整数优先级手续费
    tx['maxFeePerGas'],  # 传入整数最大手续费
    tx['gas'],  # 传入整数gas限制
    bytes.fromhex(tx['to'][2:]) if tx['to'] else b'',  # 地址转字节(去掉0x前缀)
    tx['value'],  # 传入整数转账金额
    bytes.fromhex(tx['data'][2:]) if tx['data'] else b'',  # 数据转字节
    [],  # 空的accessList
    signed_tx['v'],  # 直接使用整数v值
    to_bytes(hexstr=signed_tx['r']),  # r转字节对象
    to_bytes(hexstr=signed_tx['s'])   # s转字节对象
])

# 拼接交易类型前缀0x02
manual_raw_tx = f'0x02{encoded.hex()}'
print(manual_raw_tx)
# 验证是否和web3py的结果一致
print(f"是否匹配: {manual_raw_tx == signed_tx.rawTransaction.hex()}")

关键修复点说明

  • 字段类型匹配要求:RLP编码EIP-1559交易时,chainId、nonce、gas、各类手续费、value必须传入原始整数,不能用hex字符串;地址、data需转换为字节对象(去掉0x前缀后通过bytes.fromhex()转换)。
  • 签名字段正确处理:signed_tx返回的r、s是十六进制字符串,要通过to_bytes(hexstr=...)转为字节对象后再参与RLP编码;v值直接使用整数即可。
  • 交易类型前缀保留:EIP-1559交易类型标识0x02需要拼接在RLP编码结果的十六进制字符串前,这部分你之前的逻辑是正确的。

内容的提问来源于stack exchange,提问作者user22244332

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 15:19:57