【问题标题】:Ethereum eth_call returns padded address以太坊 eth_call 返回填充地址
【发布时间】: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

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

【问题讨论】:

    标签: ethereum web3


    【解决方案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);
      

      【讨论】:

        猜你喜欢
        • 2020-01-27
        • 1970-01-01
        • 2022-06-18
        • 2018-02-03
        • 2021-11-29
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多