Cross Contract Calls using AssemblyScript SDK
Tags: soroban, stellar, smartcontract, assemblyscript
Published: 2023-03-31 01:40:18

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**:
```TypeScript
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.

```json
{
    "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:

```json
{
  "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**:
```TypeScript
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:
```json
{
    "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:
```bash
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 :
```bash
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:
```bash
soroban contract invoke --wasm build/release.wasm --id 1 --fn callc
```
You should get this output:
```
6
```

![Cross Contract](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b2n765a1sp7gxgsp3n64.png)

##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!