DEV Community

darkvallen
darkvallen

Posted on

Cross Contract Calls using AssemblyScript SDK

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));
}
Enter fullscreen mode Exit fullscreen mode

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"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

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"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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());

}
Enter fullscreen mode Exit fullscreen mode

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"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You will get contract ID from your deployed contract, similar to this:

80863e58acf6d02f12bb0c5ecd0a046f66a171c22070bd31242d9cff7c027b84
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should get this output:

6
Enter fullscreen mode Exit fullscreen mode

Cross Contract

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)