How to call on contracts from other contracts in Solidity
Overview
When we have the address of another smart contract, we can call its functions in multiple different ways:
contract One {
function foo() external {}
}
contract Two {
function a(address _address) external {
One(_address).foo();
}
function b(One _address) external {
_address.foo();
}
function c(address _address) external {
_address.call(abi.encodeWithSignature("foo()"));
}
function d(address _address) external {
_address.call(abi.encodeWithSelector(One.test.selector));
}
}
Pass the address into the contract, and then call a function on the contract:
address _address;
One(_address).foo();
Directly call the function on the address:
One _address;
_address.foo();
Using call
Use the low level call
function.
To reference the function we want to call, we can:
Encode with signature
Use abi.encodeWithSignature
and pass the function signature including its parameter types.
_address.call(
abi.encodeWithSignature(
"foo(string,uint256)",
"some string",
42
)
);
Note that we don’t use spaces to separate parameter types in the encoding.
Also we don’t use type aliases, instead of uint
we definitely declare uint256
.
Encode with selector
_address.call(
abi.encodeWithSelector(
One.foo.selector,
"some string",
42
)
);
This way we do not have to manually define the function parameters types.
Return values
We will get back a boolean indicating success/failure and the output of the function.
(bool success, bytes memory data) = _address.call("");
Pass ether with function call
One _address;
_address.foo{value: 1 ether}();
Join the garden
Finally
enjoy quality-first content.
'cause low-quality sucks