> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross Contract Calls

> Call a smart contract from another smart contract.

The [cross contract call example] demonstrates how to call a contract from another contract.

[![Open in Codespaces](https://github.com/codespaces/badge.svg)][open-in-github-codespaces]

[![Open in Codeanywhere](https://codeanywhere.com/img/open-in-codeanywhere-btn.svg)][open-in-code-anywhere]

> [!NOTE]
>
> In this example there are two contracts that are compiled separately, deployed separately, and then tested together. There are a variety of ways to develop and test contracts with dependencies on other contracts, and the Soroban SDK and tooling is still building out the tools to support these workflows. Feedback appreciated [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose).

[open-in-github-codespaces]: https://github.com/codespaces/new?repo=stellar/soroban-examples&editor=web

[open-in-code-anywhere]: https://app.codeanywhere.com/#https://github.com/stellar/soroban-examples

[cross contract call example]: https://github.com/stellar/soroban-examples/tree/v23.0.0/cross_contract

## Run the Example

First go through the [Setup] process to get your development environment configured, then clone the `v23.0.0` tag of `soroban-examples` repository:

[setup]: /docs/build/smart-contracts/getting-started/setup.md

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
git clone -b v23.0.0 https://github.com/stellar/soroban-examples
```

Or, skip the development environment setup and open this example in [GitHub Codespaces][open-in-github-codespaces] or [Code Anywhere][open-in-code-anywhere].

To run the tests for the example, first build Contract A (the contract to be called) and then run `cargo test` from Contract B's directory. Build Contract A by navigating to the `cross_contract/contract_a` directory and use the `stellar contract build` build command:

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd cross_contract/contract_a
stellar contract build
```

When Contract A has been built, navigate to the `cross_contract/contract_b` directory, and use `cargo test`.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd ../contract_b
cargo test
```

You should see the output:

```
running 1 test
test test::test ... ok
```

## Code

```rust title="cross_contract/contract_a/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contract]
pub struct ContractA;

#[contractimpl]
impl ContractA {
    pub fn add(x: u32, y: u32) -> u32 {
        x.checked_add(y).expect("no overflow")
    }
}
```

```rust title="cross_contract/contract_b/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
mod contract_a {
    soroban_sdk::contractimport!(
        file = "../contract_a/target/wasm32v1-none/release/soroban_cross_contract_a_contract.wasm"
    );
}

#[contract]
pub struct ContractB;

#[contractimpl]
impl ContractB {
    pub fn add_with(env: Env, contract: Address, x: u32, y: u32) -> u32 {
        let client = contract_a::Client::new(&env, &contract);
        client.add(&x, &y)
    }
}
```

Ref: [https://github.com/stellar/soroban-examples/tree/v23.0.0/cross\_contract](https://github.com/stellar/soroban-examples/tree/v23.0.0/cross_contract)

## How it Works

Cross contract calls are made by invoking another contract by its contract ID.

Contracts to invoke can be imported into your contract with the use of `contractimport!(file = "...")`. The import will code generate:

* A `ContractClient` type that can be used to invoke functions on the contract.
* Any types in the contract that were annotated with `#[contracttype]`.

> [!TIP]
>
> The `contractimport!` macro will generate the types in the module it is used, so it's a good idea to use the macro inside a `mod { ... }` block, or inside its own file, so that the names of generated types don't collide with names of types in your own contract.

Open the files above to follow along.

### Contract A: The Contract to be Called

The contract to be called is Contract A. It is a simple contract that accepts `x` and `y` parameters, adds them together and returns the result.

```rust title="cross_contract/contract_a/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[contract]
pub struct ContractA;

#[contractimpl]
impl ContractA {
    pub fn add(x: u32, y: u32) -> u32 {
        x.checked_add(y).expect("no overflow")
    }
}
```

> [!TIP]
>
> The contract uses the `checked_add` method to ensure that there is no overflow, and if there is overflow, panics rather than returning an overflowed value. Rust's primitive integer types all have checked operations available as functions with the prefix `checked_`.

### Contract B: The Contract doing the Calling

The contract that does the calling is Contract B. It accepts a contract ID that it will call, as well as the same parameters to pass through. In many contracts the contract to call might have been stored as contract data and be retrieved, but in this simple example it is being passed in as a parameter each time.

The contract imports Contract A into the `contract_a` module.

The `contract_a::Client` is constructed pointing at the contract ID passed in.

The client is used to execute the `add` function with the `x` and `y` parameters on Contract A.

```rust title="cross_contract/contract_b/src/lib.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
mod contract_a {
    soroban_sdk::contractimport!(
        file = "../contract_a/target/wasm32v1-none/release/soroban_cross_contract_a_contract.wasm"
    );
}

#[contract]
pub struct ContractB;

#[contractimpl]
impl ContractB {
    pub fn add_with(env: Env, contract: Address, x: u32, y: u32) -> u32 {
        let client = contract_a::Client::new(&env, &contract);
        client.add(&x, &y)
    }
}
```

### Tests

Open the `cross_contract/contract_b/src/test.rs` file to follow along.

```rust title="cross_contract/contract_b/src/test.rs" theme={"theme":{"light":"github-light","dark":"github-dark"}}
#[test]
fn test() {
    let env = Env::default();

    // Register contract A using the imported WASM.
    let contract_a_id = env.register(contract_a::WASM, ());

    // Register contract B defined in this crate.
    let contract_b_id = env.register(ContractB, ());

    // Create a client for calling contract B.
    let client = ContractBClient::new(&env, &contract_b_id);

    // Invoke contract B via its client. Contract B will invoke contract A.
    let sum = client.add_with(&contract_a_id, &5, &7);
    assert_eq!(sum, 12);
}
```

In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let env = Env::default();
```

Contract A is registered with the environment using the imported Wasm.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let contract_a_id = env.register(contract_a::WASM, ());
```

Contract B is registered with the environment using the contract type and the contract instance is compiled into the Rust binary.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let contract_b_id = env.register(ContractB, ());
```

All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `ContractB`, and the client is named `ContractBClient`. The client can be constructed and used in the same way that client generated for Contract A can be.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let client = ContractBClient::new(&env, &contract_b_id);
```

The client is used to invoke the `add_with` function on Contract B. Contract B will invoke Contract A, and the result will be returned.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
let sum = client.add_with(&contract_a_id, &5, &7);
```

The test asserts that the result that is returned is as we expect.

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}}
assert_eq!(sum, 12);
```

## Build the Contracts

To build the contract into a `.wasm` file, use the `stellar contract build` command. Both `contract_call/contract_a` and `contract_call/contract_b` must be built, with `contract_a` being built first.

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract build
```

Both `.wasm` files should be found in both contract `target` directories after building both contracts:

```
target/wasm32v1-none/release/soroban_cross_contract_a_contract.wasm
```

```
target/wasm32v1-none/release/soroban_cross_contract_b_contract.wasm
```

## Run the Contract

If you have [`stellar-cli`] installed, you can invoke contract functions. Both contracts must be deployed.

**macOS/Linux**

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy \
    --wasm target/wasm32v1-none/release/soroban_cross_contract_a_contract.wasm \
    --alias cross_contract_a_example \
    --source-account alice \
    --network testnet
```

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy \
    --wasm target/wasm32v1-none/release/soroban_cross_contract_b_contract.wasm \
    --alias cross_contract_b_example \
    --source-account alice \
    --network testnet
```

**Windows (PowerShell)**

```powershell theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy `
    --wasm target/wasm32v1-none/release/soroban_cross_contract_a_contract.wasm `
    --alias cross_contract_a_example `
    --source-account alice `
    --network testnet
```

```powershell theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract deploy `
    --wasm target/wasm32v1-none/release/soroban_cross_contract_b_contract.wasm `
    --alias cross_contract_b_example `
    --source-account alice `
    --network testnet
```

Invoke Contract B's `add_with` function, passing in values for `x` and `y` (e.g. as `5` and `7`), and then pass in the contract ID or alias of Contract A.

**macOS/Linux**

```sh theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke \
    --id cross_contract_b_example \
    --source-account alice \
    --network testnet \
    -- \
    add_with \
    --contract cross_contract_a_example \
    --x 5 \
    --y 7
```

**Windows (PowerShell)**

```powershell theme={"theme":{"light":"github-light","dark":"github-dark"}}
stellar contract invoke `
    --id cross_contract_b_example `
    --source-account alice `
    --network testnet `
    -- `
    add_with `
    --contract cross_contract_a_example `
    --x 5 `
    --y 7
```

The following output should occur using the code above.

```
12
```

Contract B's `add_with` function invoked Contract A's `add` function to do the addition.

[`stellar-cli`]: ../getting-started/setup#install-the-stellar-cli
