ethereum - 如何将 ETH 合约输出十六进制解码为字符串?

标签 ethereum smartcontracts rpc abi

当我对 Eth 主网上的 Usdt 智能合约进行 eth_call 时,我得到一个 96 字节的十六进制输出。

0000000000000000000000000000000000000000000000000000000000000020 // What is this?
000000000000000000000000000000000000000000000000000000000000000a // Size of the output
5465746865722055534400000000000000000000000000000000000000000000 // Output ("Tether USD")

据我所知,第三个 32 字节包含带有右填充的实际字符串输出,第二个 32 字节包含带有左填充的输出大小(以字节为单位)。第一个 32 字节包含什么?

RPC 调用

{"jsonrpc":"2.0","method":"eth_call","params":[{"To":"0xdAC17F958D2ee523a2206206994597C13D831ec7","Data":"0x06fdde03"},"latest"],"id":1}

最佳答案

第一个 32 字节槽是指向长度槽的偏移量,紧随其后的是包含实际参数值的槽。

当函数返回多个动态长度数组(字符串表示为动态长度字节数组)时,偏移量非常有用,如下例所示:

pragma solidity ^0.8;

contract MyContract {
    function foo() external pure returns (string memory, string memory) {
        return ("Tether USD", "Ethereum");
    }
}

返回数据:

# offset pointing to the length of the 1st param
0x0000000000000000000000000000000000000000000000000000000000000040

# offset pointing to the length of the 2nd param
0x0000000000000000000000000000000000000000000000000000000000000080

# 1st param length
0x000000000000000000000000000000000000000000000000000000000000000a

# followed by 1st param value
0x5465746865722055534400000000000000000000000000000000000000000000

# 2nd param length
0x0000000000000000000000000000000000000000000000000000000000000008

# followed by 2nd param value
0x457468657265756d000000000000000000000000000000000000000000000000

如果这两者之间有一个固定长度的参数,则返回的数据结构将如下所示:

  1. 第一个参数长度的偏移量
  2. (固定长度)第二个参数实际值
  3. 第三个参数长度的偏移量
  4. 其余同上

文档:https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types

关于ethereum - 如何将 ETH 合约输出十六进制解码为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74127504/

相关文章:

php - 如何在 PHP 中验证以太坊地址

ethereum - RangeError : private key length is invalid: secp256k1. sign(msgHash, privateKey);

ethereum - 为什么在同一个智能合约中调用同一个函数时,Gas Used By Txn 不一样?

blockchain - 所需的gas超过限额或总是在Geth私有(private)区 block 链上失败,但在其他区 block 链上运行良好

storage - Solidity 访问私有(private)变量

java - Webservice客户端创建方法

web-services - Web服务和RPC有什么区别?

java - golang jsonrpc调用java json rpc

ethereum - 从 Metamask 获取所有以太坊账户

stack - CompilerError : Stack too deep, 尝试删除局部变量