Soroban Quest : Cross Contract
Tags: sorobanquest, soroban, stellar, smartcontract
Published: 2023-03-26 15:22:07

Hi there! Welcome to my "Soroban Quest" blog post series. [Soroban Quest](https://quest.stellar.org/soroban) is a gamified educational course where you’ll learn Soroban (new smart contract platform by Stellar Foundation) and earn badge rewards!. In this series, i will explain steps to complete every soroban quest and help you understand more about soroban smart contract itself.

The 4th quest is called "Cross Contract". This quest will give you lesson how cross contract call works in Soroban.

##Joining The Quest
To join the quest and get a Quest Account, use this command:

```bash
sq play 4
```
And dont forget to fund the quest account right away.

##Examining `README.md`
After examining `README.md`, I found that the tasks for the 4th quest is to:

- Deploy `DataStore` contract from the 2nd quest using 4th quest account
- Invoke `put` function from the deployed contract to store some data
- Build `CrossContractCall`contract, and deploy it
- Invoke `inv_get` function from the deployed `CrossContractCall` contract to retrieve the data that you previously stored on the deployed `DataStore` contract

Lets read the contract code to get some more knowledge to do all that.

##The Contract Code
```rust
#![no_std]
use soroban_sdk::{contractimpl, Address, Bytes, BytesN, Env};

/// We import the compiled binary from our auth store contract in Quest 2,
/// allowing us to use that contract's types and client in this contract.
mod storage_contract {
    // We do this inside a `mod{}` block to avoid collisions between type names
    soroban_sdk::contractimport!(file = "./soroban_auth_store_contract.wasm");
}

/// We define a `trait` which can be used to create shared behavior between
/// types, and can be used to group together signatures for related functions.
pub trait StorageCallTrait {
    // We define in this trait that the `inv_get()` function will accept:
    // - `store_id`: the other contract we are going to invoke
    // - `owner`: the `Address` that was used to `put` data to that contract
    // This funtion will return the data that was stored, in `Bytes`
    fn inv_get(env: Env, store_id: BytesN<32>, owner: Address) -> Bytes;
}

pub struct CrossContractCallContract;

/// The `CrossContractCall` contract implements the trait we defined earlier,
/// and fleshes out what the `inv_get()` function should do with it arguments
/// and how it should create the value to return.
#[contractimpl]
impl StorageCallTrait for CrossContractCallContract {
    /// The `inv_get()` function will create a new client to the auth store
    /// contract, and cross-invoke the `get` function, supplying the `owner`
    /// argument we provide when we invoked `inv_get`.
    fn inv_get(env: Env, store_id: BytesN<32>, owner: Address) -> Bytes {
        let storage_client = storage_contract::Client::new(&env, &store_id);
        storage_client.get(&owner)
    }
}

mod test;

```
The contract is located in `lib.rs` and contains one function:

- `inv_get()` - Retrieves data by calling `get` function on an instance of the `auth_store_contract`, passing in an `owner` address

The contract also imports the compiled code of another contract (auth_store_contract) using `contractimport`. This allows it to use that other contract's types and client within this contract.So in summary, this contract can be used to invoke the get method on an instance of the `auth_store_contract`, passing in an `owner` address. It will return the data stored for that owner in the other contract.
This allows contracts to build on and compose other contracts, reusing their functionality. Contracts don't have to be self-contained, but can interact with and use other contracts.

##Building The Contract

To build the contract, use the following command:
```bash
cd quests/4-cross-contract
cargo build --target wasm32-unknown-unknown --release
```
This should output a .wasm file in the ../target directory:
```bash
../target/wasm32-unknown-unknown/release/soroban_cross_contract_call_contract.wasm
```

##Deploying The Contracts
We need to deploy `DataStoreContract` contract and `CrossContractCall` contract, to deploy `DataStoreContract` contract use this following command :

```bash 
soroban contract deploy --wasm /workspace/soroban-quest/quests/4-cross-contract/soroban_auth_store_contract.wasm
```
Save the contract ID for later.
Next is to deploy `DataStoreContract` contract, usig this command :

```bash
soroban contract deploy --wasm /workspace/soroban-quest/target/wasm32-unknown-unknown/release/soroban_cross_contract_call_contract.wasm
```
Save the contract ID for later.

##Storing Data using Deployed `DataStoreContract` Contract
To store data we will invoke `put` function from the deployed `DataStoreContract`, using this command format :

```bash
soroban contract invoke --id <DeployedDataStoreContractID> -- put --user <QuestPublicKey> --value '<StoredDataInHex>'
```
> Note : To convert string to hex use `echo "YourString" | xxd -p`

![StoreData](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4hr4oajxt9a133vg9qr2.png)


##Retrieving Stored Data using deployed `CrossContractCall` Contract

To retrieve the data that we stored earlier, we will invoke `inv_get` function from the deployed `CrossContractCall`, using this command format :
```bash
soroban contract invoke --id <DeployedCrossContractCallContractID> -- inv_get --store_id '<DeployedDataStoreContractID>' --owner <QuestPublicKey>   
```
![Cross Contract Call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fbb1ocl2nugy6lti5kbh.png)

##Checking the Quest
We already completed every step to complete the quest and this is the last thing you need to do. Check your quest and claim your badge reward. To check use the following command :
```
sq check 4
```

Congratulations! You have already completed 4 out of 6 quests. You have 2 more to go.