Web3.py中无ABI调用智能合约:能否用原始调用数据调用代理回退函数?
问题解答
完全可以直接用构造好的原始调用数据发送交易,根本不需要依赖ABI。
- 以太坊交易里的调用数据(calldata)本质就是函数methodId + 按规则编码后的参数,只要你能拼出合法的这串数据,就能直接发起调用,和有没有ABI半毛钱关系都没有。
- 你已经知道目标函数的methodId,也清楚三个参数的类型(address、uint256、address),只需要按照以太坊的ABI编码规则,把修改后的参数编码成32字节的格式,再把methodId和编码后的参数按顺序拼接,就能得到有效的调用数据。
- 代理合约的fallback函数会自动把接收到的calldata转发给实现合约,你不用特意去调用fallback——只要你的calldata里带了正确的methodId,代理会自动把请求路由到实现合约对应的函数上。
编码的时候注意这几点:
- address类型要补成32字节长度的十六进制字符串(比如短地址
0x123要补成0x0000000000000000000000000000000000000000000000000000000000000123) - uint256类型本身就是32字节,直接把数值转成十六进制即可(注意要补前导零到64位)
- 参数必须按函数定义的顺序拼接在methodId后面
举个实际的拼接例子:
假设目标函数的methodId是0x12345678,修改后的参数是0xabcdef1234...(address)、1000000(uint256转十六进制是0x00000000000000000000000000000000000000000000000000000000000f4240)、0x1234abcd...(address),最终的calldata就是:0x12345678 + 填充后的第一个address + 填充后的uint256 + 填充后的第二个address
你可以用工具手动编码参数,也可以用ethers.js里的ethers.utils.defaultAbiCoder.encode(['address', 'uint256', 'address'], [修改后的地址1, 数值, 修改后的地址2])来生成参数编码部分,再和methodId拼起来就行。
发起交易的时候,只需要指定代理合约的地址,把这串拼好的calldata放到交易的data字段里发送,完全不需要用ABI来生成交易数据。
内容的提问来源于stack exchange,提问作者Samuel Alibien
相关产品推荐
相关产品推荐

