Hello everybody and welcome back to our ongoing series! After taking a closer look into how you set up the æternity JS SDK, we’re back again taking a deeper dive into how you can make your smart contracts call other contracts.
Getting smart contracts to call other contracts is an important technique, seeing as how this allows you to interconnect a swatch of various different contracts. This could be quite crucial towards making a system like, for example, a decentralized finance one.
For more info, check out this awesome video right here:
In order for a contract to call another one, it first needs to know some things about it. This is done by providing a contract interface, right above the code of your actual contract. This provides your contract with the information about the other contract, like what functions you want to call, their parameter types, and their return data types. No function logic info is needed – your main contract has no need to know any of it.
Note, however, that the syntax is slightly different when calling interfaces.
The function in your other contract needs to be denominated as a public one and defined as an entry point, in order for this to work. Also, keep in mind that you have to state if that function is stateful, payable, both, or none.
Watch out though and make sure that, when you’re writing interfaces, they always correspond to the signature of the function in the other contract that you’re trying to call (naming, parameter types, return data types). This is important seeing as how the compiler cannot correct this for you because it doesn’t know anything about the other contract you are trying to call.
To call another contract, the other contract needs to have at least one of the functions that you defined in your interface. As a parameter, you pass the address of the other contract. The parameter type for these is not addressed, however, but the name you gave the interface.
Now, just make sure that your remote contract is deployed, grab its address, deploy your main contract, and get it to call your remote contracts function.
Since the Iris fork, æternity blockchain provides you with a way to handle failed intercontract calls. Simply, you wrap the remote contract call in a switch statement. In case of remote contract calls, still, you have to take into account two syntactical additions: to provide a named argument called “protected” and set it to “true” and deem the return type to be an option of the actual return type.
Remember, checking an option with a switch statement can result in some or none data that you can further work with. This allows you to use Sophia’s pattern matching to check if the call succeeded or not. If “none” matches, the call failed. “Some” means that it worked and that you can bind the return data to a variable named any way you wish!
Once you passed an address for an external contract, you can retrieve it as an address inside your code!
If you wish to pass Æ and/or limit the gas amount you wish to provide to your intercontract call, you can use named arguments.
Finally, keep in mind that, in Sophia, “call.caller” always refers to the entity calling the contract. But, if you send a transaction to contract X, and then call a function from contract Y – for contract Y “call.caller” will always refer to contract X, not you who initially sent this transaction.
If you need any further imput you can check out this awesome video made by æternity’s very own Nikita! Also, you are free to hop on to the aeternity forum as well as the telegram group – all of us are more than welcome!
P.S. Don’t forget, æternity made an entire playlist on Sophia on YouTube!