深入解析以太坊浏览器中 Data 字段的编码方式
在以太坊浏览器(如 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,除非注明,否则均为原创文章,转载请注明出处。
