深入解析以太坊浏览器中 Data 字段的编码方式

博主:neragonerago 2026-10-01 00:51:26 3

在以太坊浏览器(如 Etherscan)中查看交易详情时,我们经常会看到一个名为 Input Data(输入数据)的字段,也就是通常所说的 data 字段,对于普通转账交易,这个字段通常为空;但对于与智能合约交互的交易,data 字段承载着最核心的信息——调用哪个函数、传递什么参数。

这串看似杂乱的十六进制数据是如何编码的?本文将带你彻底理解它。


Data 字段的基本结构

一笔合约调用的 data 字段由两大部分组成:

0x + 函数选择器(4字节) + 参数编码数据(每段32字节对齐)
  • 函数选择器(Function Selector):data 的前 8 个十六进制字符(4 字节),用于标识要调用的函数
  • 参数编码区域:函数的实参,按照 ABI 编码规则依次排列

例如在 Etherscan 中点击 "View Input As" 切换到 "Original",你会看到类似:

0xa9059cbb
0000000000000000000000005b38da6a701c568545dcfcb03fcb875f56beddc4
00000000000000000000000000000000000000000000000000000000000003e8

函数选择器的生成

函数选择器是函数签名的 Keccak-256 哈希值的前 4 字节,函数签名格式为:函数名(参数类型1,参数类型2,...)

以 ERC-20 的转账函数为例:

函数签名:transfer(address,uint256)
Keccak256 哈希:a9059cbb2ab09d683bdeb2f04730bcf0e9760b5e...
选择器取前4字节:0xa9059cbb

这就是为什么你在 Etherscan 中看到大量代币转账交易都以 0xa9059cbb 开头——它们调用的都是同一个标准化的 transfer 函数。


参数的 ABI 编码规则

以太坊使用 ABI 编码(Application Binary Interface Encoding) 对参数进行序列化,核心规则是所有数据按 32 字节(64 个十六进制字符)为一组进行对齐。

静态类型编码

静态类型的大小是固定的,直接编码并补齐到 32 字节:

类型 编码规则
uint256 / int256 大端序,左侧补零至 32 字节
address 20 字节地址,左侧补零至 32 字节
bool false = 全零,true = 1
bytes32 右侧补零至 32 字节

示例:transfer(0x5B38Da6a...eddC4, 1000)

  • 地址左侧补零:..0000 + 5b38da6a701c568545dcfcb03fcb875f56beddc4
  • 数值 1000 的十六进制是 0x3e8,左侧补零后:..03e8

动态类型编码

对于长度不确定的类型(string、bytes、动态数组等),采用“偏移量 + 长度 + 数据” 的三级结构:

示例:setName("Alice")

函数选择器:        c47f0027
偏移量(32):     0000...0020   ← 参数数据相对参数区的起始位置
长度(5):        0000...0005   ← 字符串长度
数据:            416c696365... ← "Alice" 的 UTF-8 十六进制,右侧补零

416c696365 正是 "Alice" 各字符的 ASCII/UTF-8 编码:41=A,6c=l,69=i,63=c,65=e。

The End

发布于:2026-10-01,除非注明,否则均为区块链社区- 欧亿APP下载原创文章,转载请注明出处。