Getting Started with Solidity|Lecture 22: Call

律动

I’ve recently been re-learning solidity, consolidating the details, and writing a “Solidity Minimalist Primer” for beginners to use (programming guys can find another tutorial), updated 1-3 times a week.

All code and tutorials are open source on GitHub: github.com/AmazingAng/WTFSolidity

In Lecture 17: Sending ETH, we talked about using call to send ETH, and in this lecture we will show you how to use it to call contracts.

Call

call is a low-level member function of the address type, which is used to interact with other contracts. It returns (bool, data), which corresponds to the success of the call and the return value of the objective function, respectively.

call is the officially recommended method of sending ETH by triggering the fallback or receive functions by solidity. It is not recommended to call another contract with a call, because when you call the function of an insecure contract, you give it the initiative. The recommended method is still to call the function after declaring the contract variable, see Lecture 19: Calling Other Contracts. If we don’t know the source code or ABI of the other party’s contract, we can’t generate contract variables, but we can still call the other party’s contract functions through call.

Rules for the use of call

The rules for using call are as follows:

The binary encoding uses the structured encoding function abi.encodeWithSignature to obtain:

The function signature is “Function Name (comma-separated parameter type)”. For example, abi.encodeWithSignature(“f(uint256,address)”, _x, _addr).

In addition, when calling the contract, you can specify the amount of ETH and gas to be sent by the transaction:

It seems a bit complicated, so let’s take an example of a call application.

Target contract

Let’s start by writing a simple target contract, OtherContract, and deploying it, the code is basically the same as in Lecture 19, except with the addition of a fallback function.

This contract contains a state variable x, an event log that is triggered when ETH is received, and three functions:

getBalance(): Returns the ETH balance of the contract. setX(): external payable function, which can set the value of x and send ETH to the contract. getX(): Reads the value of x.

Use call to call the target contract

1. Response event

Let’s write a Call contract to call the target contract function. First of all, write a definition of a Response event, and output the success and data returned by the call, so that we can observe the return value.

2. Call the setX function

We define the callSetX function to call setX() of the target contract, transfer the amount of ETH to msg.value, and release the Response event to output success and data:

Next, we call callSetX to change the state variable _x to 5, and the parameters are the OtherContract address and 5, because the objective function setX() does not return a value, so the data output of the Response event is 0x, which is empty.

3. Call the getX function

Let’s call the getX() function, which will return the value of the target contract _x, of type uint256. We can use abi.decode to decode the return value of the call, data, and read out the value.

From the output of the Response event, we can see that the data is 0x0000000000000000000000000000000000000000000000000000000000000005. After abi.decode, the final return value is 5.

4. Call a function that doesn’t exist

If the function we input to the call does not exist in the target contract, then the fallback function of the target contract will be triggered.

In the example above, we called the non-existent foo function. The call can still be executed successfully and return success, but it is actually the fallback function of the target contract called.

Summary

In this talk, we showed how to use the low-level function call to call other contracts. call is not the recommended method for calling a contract because it is not secure. But it’s useful to let us call the target contract without knowing the source code and ABI.

Disclaimer: The information on this page may come from third parties and does not represent the views or opinions of Gate. The content displayed on this page is for reference only and does not constitute any financial, investment, or legal advice. Gate does not guarantee the accuracy or completeness of the information and shall not be liable for any losses arising from the use of this information. Virtual asset investments carry high risks and are subject to significant price volatility. You may lose all of your invested principal. Please fully understand the relevant risks and make prudent decisions based on your own financial situation and risk tolerance. For details, please refer to Disclaimer.
Comment
0/400
No comments