仅供教育参考,不构成投资、法律或安全建议。解码和模拟可以减少歧义,但不能保证授权、执行、资产安全或最终性。
直接答案
Calldata 是作为输入传给以太坊顶层交易或内部消息调用的不可变字节串。常规 Solidity 函数调用以一个 4-byte 选择器开头,后接 ABI 编码参数,但 calldata 并非自描述格式:对于不同的运行时代码、代理实现或模式,同一组字节可能具有不同含义。回退函数、原始汇编以及非 Solidity 协议也完全不必遵循常规函数 ABI。
因此,钱包展示的内容不应止于候选函数名称。稳妥的复核应把这些字节与 chainId、具体区块、from、to、原生资产 value、运行时 codeHash、当前实现合约和可信 ABI 绑定;严格解码每一层嵌套调用;区分链上 calldata 与 EIP-712 签名;在明确的状态下模拟;并在交易入块后对实际回执和状态变化进行核对。
0 / 5
0 项已核查; 5 项仍未解决
完成核查不代表资产、交易或系统已经安全。
运作机制
- 固定签名信封和观察时点:
chainId、区块号与区块哈希、from、to、原生资产value、输入字节、nonce 和费用字段。保留钱包或 RPC 数据来源;来自另一条链或另一时点的解码结果并非同一项判断。 - 解码前先判定对象类型。交易、EIP-712 类型化数据请求、ERC-2612 许可、ERC-4337 UserOperation 和原始 personal-sign 消息使用不同的域与模式;不能全部强行套用交易 ABI。
- 在固定区块解析目标。读取运行时字节码和
codeHash;识别适用的代理、信标或实现合约;记录实现与管理员存储槽;并取得与该确切代码版本匹配的 ABI。选择器登记库只能提供候选项,不能作为权威依据。 - 严格解码。选择器是规范函数签名经 Keccak-256 哈希后的前
4 bytes,不含返回类型。静态值占用32-byte字;动态参数头保存相对于选择器之后参数区起点的偏移量。遇到截断数据、越界偏移量、不可能的长度、无效填充或无法解释的尾随字节,应拒绝签名。 - 递归展开 multicall、嵌套 calldata 和委托执行。逐项列明子调用的目标、原生资产价值、选择器、参数、调用类型及任何
allowFailure标志。使用delegatecall时,实现合约代码在调用方的地址、余额与存储上下文中运行,同时保留msg.sender和msg.value。 - 分别建立权限账本和价值账本,再进行模拟。记录收款方、spender、NFT 操作员、代币原始单位、decimals、截止时间、滑点边界与原生资产价值。用确切区块、发送方和价值进行模拟,但应把结果视为条件性快照,因为状态、价格、时间、代码和交易排序都可能改变。
- 签名前确认每一个重要字段。入块后检查回执状态、日志、可用的调用轨迹,以及余额、授权额度和操作员状态变化;区分被捕获的子调用失败与顶层调用成功;即使交易回滚也要计入 gas;等待所需最终性;若失败原因无法解释,应停止操作而不是盲目重新签名。
计算示例
- 静态 ERC-20 转账。
transfer(address,uint256)通常使用选择器0xa9059cbb。一个选择器加两个 ABI 字共4 + 2 * 32 = 68 bytes。原始数量1,500,000对于已独立核实采用6 decimals的代币显示为1.5 tokens。decimals 属于外部合约元数据,并未编码在这些参数中;选择器本身也无法唯一识别合约或函数。 - 动态字节偏移量。 对于
f(address,bytes),若载荷为3-byte,两个字组成的参数头占64 bytes。动态偏移量为0x40,从参数区起点计量,不包括选择器。参数尾包含一个32-byte长度字和一个32-byte填充数据字,因此 calldata 总长为4 + 64 + 32 + 32 = 132 bytes。若把偏移量误当成从第零字节起算,位置会向后错四个字节。 - 批量调用中的价值处理取决于实现。 外层调用携带
1.00 ETH;三个已解码子调用明确请求0.20 ETH、0.30 ETH和0.10 ETH,合计0.60 ETH。剩余0.40 ETH可能被退回、留存、继续转发,或导致回滚,具体取决于批量调用代码。如果第三个子调用失败且设置了allowFailure=true,此前子调用可能仍然生效;原子式实现则可能回滚全部操作。 - 许可签名并不是签名时中继者的 calldata。 一名持有
1,000 USDC的所有者签署额度为300 USDC、nonce 为41的 ERC-2612 许可。签名本身既不改变余额,也不改变授权额度。中继者成功提交后,nonce 变为42,授权额度变为300;spender 随后使用180,余额为820,剩余授权额度为120。断开网站连接并不会撤销这项权限。
风险
- 按错误的链、分叉、区块标签或交易信封解码。
- 为伪造域名、目标地址或收款地址签名。
- 尽管可能发生碰撞,仍把
4-byte选择器视为唯一标识。 - 使用猜测、过时或未经正确验证的 ABI。
- 只相信源码已验证标签,却没有匹配当前运行时
codeHash。 - 漏掉复核与执行之间发生的实现、信标或管理员升级。
- 忽略代理合约自身函数与实现合约发生的选择器冲突。
- 忘记
delegatecall会在调用方的存储上下文中写入状态。 - 接受畸形的动态偏移量、长度、填充或尾随字节。
- 未展开隐藏目标、价值或权限的嵌套批量调用。
- 在实现会捕获或容许子调用失败时仍假定调用具备原子性。
- 因代币参数看似无害而忽略顶层原生资产
value。 - 使用错误的 decimals,或假定转账收费和变基代币遵循标准 ERC-20 行为。
- 授予无限 ERC-20 授权额度,或错误处理授权额度更新竞态。
- 忽略 NFT
setApprovalForAll覆盖整个系列的权限范围。 - 把 EIP-712 类型化数据或 ERC-2612 许可误当作交易 calldata。
- 漏查 nonce、截止时间、验证合约、链域或重放边界。
- 在预言机、时间戳、待处理状态、MEV 或代码变化下仍把模拟视为稳定结果。
- 把回执状态、日志或服务商调用轨迹当成完整的经济状态证明。
- 通过已被攻陷的界面盲目重新签名,或忽略入块、重组和最终性风险。
常见误区
- 函数选择器可以唯一标识合约将执行的操作。
- 已验证的前端摘要与正在签署的字节及当前实现完全相同。
value=0的交易无法转移代币、NFT 或已委托资产。- 模拟成功或回执成功可以证明安全性和预期经济结果。
- 断开 dapp 连接会撤销授权、许可和 NFT 操作员权限。
相关主题
来源
- Contract ABI Specification - Solidity Documentation(查阅日期:2026-08-12)
- Introduction to Smart Contracts - Solidity Documentation(查阅日期:2026-08-12)
- Transactions - Ethereum.org(查阅日期:2026-08-12)
- ERC-20: Token Standard - Ethereum Improvement Proposals(查阅日期:2026-08-12)
- EIP-712: Typed structured data hashing and signing - Ethereum Improvement Proposals(查阅日期:2026-08-12)
- ERC-2612: Permit Extension for EIP-20 Signed Approvals - Ethereum Improvement Proposals(查阅日期:2026-08-12)
- ERC-721: Non-Fungible Token Standard - Ethereum Improvement Proposals(查阅日期:2026-08-12)
- ERC-1967: Proxy Storage Slots - Ethereum Improvement Proposals(查阅日期:2026-08-12)