结构体参数在call中使用方式
若自定义结构体如下:
struct User{
uint8 userType;
uint8 age;
}
在使用call调用方法时,结构体参数需要写成
(uint8,uint8)
以下为一个示例,含结构体数组,其中也包含staticcall 与 call 的使用
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
struct User{
uint8 userType;
uint8 age;
}
contract Test {
User[] public users;
address[] public addrs;
bytes public payloadBytes;
function testCall() external {
User memory user = User(1,25);
User[] memory users0 = new User[](1);
users0[0] = user;
addrs.push(0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc);
bytes memory payload = abi.encodeWithSignature("testCalled(address[],(uint8,uint8)[])", addrs, users0);
payloadBytes = payload;
(bool success, ) = address(this).call(payload);
require(success, "call fail.");
}
function testCalled(address[] memory _addr, User[] memory _user) external{
require(_addr.length == _user.length, "Len is not the same.");
for (uint8 i = 0; i < _user.length; i++) {
addrs.push(_addr[i]);
users.push(_user[i]);
}
}
function testStaticcall() external {
User memory user = User(1,25);
User[] memory users0 = new User[](1);
users0[0] = user;
addrs.push(0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc);
bytes memory payload = abi.encodeWithSignature("testStaticcalled(address[],(uint8,uint8)[])", addrs, users0);
payloadBytes = payload;
(bool success, ) = address(this).staticcall(payload);
require(success, "staticcall fail.");
}
function testStaticcalled(
address[] memory _addrs,
User[] memory _users
) external view returns (uint256, uint256, address[] memory, User[] memory) {
return (_addrs.length, _users.length, addrs, users);
}
}
staticcall 与 call 的区别
使用
call
函数调用,可以修改合约中的状态变量。但是,如果您只是想查询外部合约的状态而不修改它,则应使用staticcall
函数调用,不能修改合约中的状态变量,所以如果想查询而不修改外部合约的状态变量则使用staticcall。