Hi! In this post, we will explore an example of a cross-contract call using the AssemblyScript SDK in the Soroban Smart Contract Platform.
A cross-contract call occurs when one contract calls a function on another contract. In this example, we will use two contracts: Contract A and Contract B. Contract A will contain the function that will be called, and Contract B will be the contract that calls the function from Contract A.
The Contract Code
Contract A Code:
import * as val from 'as-soroban-sdk/lib/value';
export function double(num: val.RawVal): val.RawVal {
let numi32 = val.toI32(num);
return (val.fromI32(numi32 *2));
}
A quick explanation, this contract contain double() function that takes a single parameter, num, of type val.RawVal and will double the input value. The function returns a val.RawVal.
Next, create contract.json file in your project directory, this file contains metadata for the contract.
{
"name": "Contract A",
"version": "0.1.0",
"description": "Example",
"host_functions_version": 29,
"functions": [
{
"name" : "double",
"arguments": [
{"name": "num", "type": "i32"}
],
"returns" : "i32"
}
]
}
Before compiling the contract, we need to edit the asconfig.json file of your project. Replace its content with the following:
{
"extends": "as-soroban-sdk/sdkasconfig",
"targets": {
"release": {
"outFile": "build/release.wasm",
"textFile": "build/release.wat"
},
"debug": {
"outFile": "build/debug.wasm",
"textFile": "build/debug.wat"
}
}
}
The asconfig.json file is used by the AssemblyScript compiler (asc) to define the configuration for your project.
Contract B Code:
import * as val from 'as-soroban-sdk/lib/value';
import { Vec } from "as-soroban-sdk/lib/vec";
import * as contract from "as-soroban-sdk/lib/contract";
export function callc(): val.RawVal {
let contractId = "80863e58acf6d02f12bb0c5ecd0a046f66a171c22070bd31242d9cff7c027b84";
let func = "double";
let args = new Vec();
args.pushBack(val.fromI32(3));
return contract.callContractById(contractId, func, args.getHostObject());
}
The callc function imports the val and Vec modules from the Soroban SDK, as well as the contract module. It also defines a function called callc that takes no parameters and returns a val.RawVal.
The purpose of this function is to call a function called double in another contract using its contract ID. The contractId variable stores the ID of the contract that we want to call, and the func variable stores the name of the function that we want to call in the other contract.
In the next line, we create a new Vec called args and add an argument to it using args.pushBack(val.fromI32(3)). This creates a vector of arguments that we will pass to the double function in the other contract when we make the cross-contract call.
Finally, we make the cross-contract call using the contract.callContractById function. This function takes the contract ID, the name of the function we want to call, and the arguments vector as parameters. The getHostObject function is used to convert the args vector to an object that can be passed as a parameter to the callContractById function.
The callc function returns the result of the cross-contract call as a val.RawVal.
Next you know the drill, create contract.json file:
{
"name": "CrossContract",
"version": "0.1.0",
"description": "cross contract example",
"host_functions_version": 29,
"functions": [
{
"name" : "callc",
"arguments": [],
"returns" : "i32"
}
]
}
Edit asconfig.json same as Contract A.
Compiling The Contract
You need to compile both contracts from each contract directory using this command:
npx asc assembly/index.ts --target release
Now you should see two new files in each contract build/ directory: release.wasm and release.wat.
Run The Contract
First, we will deploy Contract A wasm file, using this command :
soroban contract deploy --wasm build/release.wasm
You will get contract ID from your deployed contract, similar to this:
80863e58acf6d02f12bb0c5ecd0a046f66a171c22070bd31242d9cff7c027b84
This contract ID should be put in Contract B contractID value, after you put it there, compile the contract again.
Next, we will invoke Contract B wasm file from contract b directory, using this command:
soroban contract invoke --wasm build/release.wasm --id 1 --fn callc
You should get this output:
6
Closing
Overall, this code provides a simple example of how Cross Contract Calls works using the AssemblyScript SDK. By using the contract.callContractById function. Happy Sorobaning!

Top comments (0)