Soroban Quest : Custom Types
Tags: sorobanquest, soroban, stellar, smartcontract
Published: 2023-03-26 18:14:48

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 5th quest is called "Custom Types". This quest will give you lesson how custom types implemented in Soroban.

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

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

##Examining `README.md`
After examining `README.md`, i found that this quest is very different than all quest before, we will "write" some code ourselves. The tasks for 5th quest is to :
- Define several custom types with its defined types and its fields in `types.rs` file

> Rectangle struct
Animal enum
User struct
RGB tuple enum
Color tuple enum
Paticipant enum
RoyalCard enum 

- Build the contract
- Deploy the contract
- Invoke each of the functions with valid argument for each custom types

Seems like a lot of work, but dont worries i will guide you through this quest!

- Invoke `verify` function from `dcc02a65c6904c285aca78c456ac30fd66ceb2236c65972177ea60ef9cde3569` contract ID, supply our deployed contract's contractID as `--contract_id` argument to verify our contract

##The Contract Code
```rust
#![no_std]

use soroban_sdk::{contractimpl, Env};
use types::*;

pub struct TypesContract;

#[contractimpl]
impl TypesContract {
    pub fn c_rect(_env: Env, _rect: Rectangle) {}
    pub fn c_animal(_env: Env, _animal: Animal) {}
    pub fn c_user(_env: Env, _user: User) {}
    pub fn c_rgb(_env: Env, _rgb: RGB) {}
    pub fn c_color(_env: Env, _val: Color) {}
    pub fn c_part(_env: Env, _participant: Participant) {}
    pub fn c_card(_env: Env, _card: RoyalCard) {}
}

mod test;
mod types;
```
The contract is located in `lib.rs` and contains 7 function that we're gonna invoke later after we defined all the custom types. These functions don't do anything with the arguments passed to them. They are simply placeholders that can be used to test the custom types that defined.

##Defining Custom Types
The custom types definition located in `types.rs` file. We will define each custom types with its defined types and its fields.
There are some example located in `types.rs`, you can read the comments for the explanation. We will define the rest ourselves with condition that i write before in "Examining `README.MD` section, Let's go!

- `Rectangle` Type

`Rectangle` struct with two fields, width and height, both in a u32 value
```rust
pub struct Rectangle {
    pub width: u32,
    pub height: u32,
}
```

- `Animal` Type

`Animal` enum with two variations, Cat and Dog. 
```rust
pub enum Animal {
    Dog,
    Cat
}
```
- `User` Type

`User` struct with `name`, `age`, and `pet` fields, corresponding to `Bytes`, `u32`, and `Animal` values, respectively.
```rust
pub struct User {
    pub name: Bytes,
    pub age: u32,
    pub pet: Animal,
}
```
- `RGB` Type

`RGB` tuple struct type made with a tuple of 3 `u32` values.
```rust
pub struct RGB(
    pub u32,
    pub u32,
    pub u32
);
```
- `Color` Type

`Color` tuple enum type with a variant named "RGB" and an instance of the `RGB` type.
```rust
pub enum Color {
    RGB(RGB)
}
```
- `Participant` Type

`Participant` enum with single-value tuple variants, including an `Account` variant with an `Address` type and a `Contract` variant with a `BytesN<32>` type
```rust
pub enum Participant {
    Account(Address),
    Contract(BytesN<32>)
}
```

- `RoyalCard` Type

`RoyalCard` enum containing three `u32` integer variations: "Jack" with a value of 11, "Queen" with a value of 12, and "King" with a value of 13
```rust
pub enum RoyalCard {
    Jack = 11,
    Queen = 12,
    King = 13
}
```
Fill `types.rs` file with above codes and save it.

##Testing the Contract
We already defined every custom types by ourselves, to check everything is right, we could test the contract using this command :
```bash
cd quests/5-custom-types
cargo test
```
If everything is right you will see this as result :

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

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```

##Building the Contract
To build the contract, use the following command:
```bash
cargo build --target wasm32-unknown-unknown --release
```
This should output a .wasm file in the ../target directory:
```bash
../target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm
```

##Deploying the Contract
To deploy the contract, use the following command:
```bash
soroban contract deploy --wasm /workspace/soroban-quest/target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm
```
From this command you will get a Contract ID, save this for invoking it later.

##Invoking the Contract Functions
There is 7 function that we are about to invoke as we can see in "The Contract Code" section before, i will guide you to invoke every function.

- Invoking `c_rect`

To invoke `c_rect` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_rect --_rect '{"width":<widthvalue>,"height":<heightcalue>}'
```

![c_rect](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fap1lz05802xtl6w8079.png)

- Invoking `c_animal`

To invoke `c_animal` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_animal --_animal <Dog/Cat>
```

![c_animal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/60jzlfbj8eupa1grvf8x.png)

- Invoking `c_user`

To invoke `c_user` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_user --_user '{"name":"<NameInHex>","age":<age>,"pet":"<Cat/Dog>"}'
```

![c_user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdnwm2r68ksq37g27m9f.png)

- Invoking `c_rgb`

To invoke `c_rgb` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_rgb --_rgb '[<u32-int>,<u32-int>,<u32-int>]'
```

![c_rgb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tvhavhsq1jxprqgp65vk.png)

- Invoking `c_color`

To invoke `c_color` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_color --_val '{"RGB":<RGB-Value>}'
```

![c_color](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5kybod802xy1tnutu1w.png)

- Invoking `c_part`

You need to invoke `c_part` twice, first for create an account `Participant`, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_part --_participant '{"Account":"<QuestPublicKey>"}'
```

![Account](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf8yyahteervai44gt5f.png)
And one more, invoke `c_part` function for create an contract `Participant`, use this command format

```bash
soroban contract invoke --id <YourContracID> --fn c_part -- --_participant '{"Contract":"<YourContractID>"}'
```

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

- Invoking `c_card`

To invoke `c_card` function, use this command format :

```bash
soroban contract invoke --id <YourContracID> -- c_card --_card <11/12/13>
```

![c_card](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xu075zft86vzbuwl3dqd.png)

##Invoke `verify` Function From Specific ContractID
Last task to complete this quest is to invoke `verify` function from this specific `dcc02a65c6904c285aca78c456ac30fd66ceb2236c65972177ea60ef9cde3569` contract ID, and supply our deployed contract's contractID as `--contract_id` argument to verify our contract. The command format is :

```bash
soroban contract invoke --id dcc02a65c6904c285aca78c456ac30fd66ceb2236c65972177ea60ef9cde3569 -- verify --contract_id <YourContractID>
```

##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 5
```
Congratulations! You have already completed 5 out of 6 quests. You have 1 last more to go.