以太坊 eth_call 返回填充地址

Posted

技术标签:

【中文标题】以太坊 eth_call 返回填充地址【英文标题】:Ethereum eth_call returns padded address 【发布时间】:2022-01-03 10:04:08 【问题描述】:

这是我的合同 ABI


 abi:[
      "inputs": [],
      "name": "owner",
      "outputs": [
        
          "internalType": "address",
          "name": "",
          "type": "address"
        
      ],
      "stateMutability": "view",
      "type": "function",
      "constant": true
    ]

当我尝试使用 ethereum.request(...) 的 eth_call 方法获取所有者的地址时,它给了我填充物地址而不是真实地址,

得到0x000000000000000000000000ed3a7bb89eb3e355bed8975c5ff03e39d1c91c75 而不是0xed3a7bb89eb3e355bed8975c5ff03e39d1c91c75

如何将方法调用的输出转换为以太坊地址??

【问题讨论】:

【参考方案1】:

以太坊地址长 20 个字节(40 个十六进制字符)。但每个 EVM 存储槽的容量为 32 字节(64 个十六进制字符)。

eth_call 从存储槽返回原始数据,不针对数据类型大小进行调整。这就是为什么有填充。


可以使用web3decodeParameter()函数解析地址:

// returns "0xed3a7bb89eB3e355beD8975c5Ff03e39D1C91C75"
const address = web3.eth.abi.decodeParameter(
    'address',
    '0x000000000000000000000000ed3a7bb89eb3e355bed8975c5ff03e39d1c91c75'
);

而且由于地址和存储槽的大小都是固定的,所以还可以使用常规的 JS 函数 slice() 来解析子字符串(从第 26 位开始,包括前导 0x)。

// returns "0xed3a7bb89eB3e355beD8975c5Ff03e39D1C91C75"
const address = '0x' + '0x000000000000000000000000ed3a7bb89eb3e355bed8975c5ff03e39d1c91c75'.slice(26);

【讨论】:

【参考方案2】:

得到更好的解决方案

您可以根据 ABI.json 解码所有数据

const output= window.ethereum.eth.request(method: "eth_call",params: [tx]);
let outputsTypes = this.contract.methods[method](...args)._method.outputs;
const result= window.ethereum.eth.abi.decodeParameters(outputsTypes, output);

【讨论】:

以上是关于以太坊 eth_call 返回填充地址的主要内容,如果未能解决你的问题,请参考以下文章

以太坊合约 ABI 的最大字符串大小

以太坊合约地址错误是怎么回事

如何判断一个以太坊地址是合约还是普通账户?

以太坊钱包地址在哪里 如何买卖以太坊

以太坊的ABI编码

以太坊实战视频教程