Tags: Blockchain.
Categories: notes.

calldata

调用智能合约的本质,是向目标合约发送了一段calldata

为了便于理解,这里用一个简单的合约做示例

1
2
3
4
5
6
7
8
9
10
11
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Add {
uint public c;

function cal(uint a, uint b) public returns(uint) {
c = a * b;
return c;
}
}

部署合约后,为cal函数传入2和3两个参数,calldata如下:

1
0xdc2e7b3300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003

一段calldata可被分为两个部分:前4字节和后32字节。

  • 前四字节为函数选择器(selector):0xdc2e7b33

  • 后32字节为输入的参数:0x00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003

msg.data是solidity中的一个全局变量,值为完整的calldata。calldata实际上就是告诉目标合约,我要调用哪个函数,以及参数是什么

method id

method id定义为函数签名的Keccak256哈希后的前四个字节,当method id和selector匹配上时,代表调用该函数

计算示例里的函数签名

image-20240203194113088

前四字节为0xdc2e7b33

在函数签名中,uint 和 int 要写成 uint256 和 int256

使用 selector 调用目标函数时,只用将目标函数的 method id 作为 selector 和参数打包,用abi.encodeWithSelector编码,传给 call 函数