Soroban Quest : Auth Store
Tags: soroban, sorobanathon, sorobanquest, stellar
Published: 2023-03-25 18:13:15

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.

We already completed the first quest in the previous post. The second quest is called "Auth Store". This quest will give you lesson how to store and retrieve data from contract storage using simple authentication.

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

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

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

- Build auth data store contract
- Deploy auth data store contract to the futurenet
- Invoke `put` function from the deployed contract to store some data
- Invoke `get` function from the deployed contract to retrieve that data

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

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

pub struct DataStoreContract;

#[contractimpl]
impl DataStoreContract {
  
    pub fn put(env: Env, user: Address, value: Bytes) -> Result<(), ContractError> {

        user.require_auth();
        if value.len() <= 10 {
            panic_with_error!(&env, ContractError::InputValueTooShort)
        }

that was passed,

        env.storage().set(&user, &value);

        Ok(()) // return ok if function call succeeded
    }

    pub fn get(env: Env, owner: Address) -> Bytes {
        env.storage()
            .get(&owner)
            .unwrap_or_else(|| Ok(bytes!(&env))) // This uses `unwrap_or_else` and closure which only evaluates Bytes(0) when necessary.
            .unwrap()
    }
}

mod error;
mod test;

```
The contract is located in `lib.rs` and contains two functions:

- `put()` - Stores data associated with an address if the address has authorized the write
- `get()` - Retrieves data associated with an address

The contract also includes an error module (error.rs) defining the ContractError type for error handling. The contract uses `panic_with_error!()` to panic with a custom `ContractError` if invalid input is provided to `put()`. This demonstrates panicking with a custom error type to provide more detailed error information.

###`put()` function

> Accepts an address (user), data (value - in hex) 
> Requires the address to have authorized the write by calling user.require_auth()
> Checks that the data is at least 11 bytes long and panics if not
> Stores the data associated with the address by calling `env.storage().set()`
> Returns Ok if successful

This will store data to the storage based on specific address.

###`get()` Function
- Accepts an address (owner) and contract environment (env) as parameters
- Retrieves the data associated with the address by calling env.storage().get()
- Returns the data or bytes of length 0 if no data is associated with the address

This allows retrieval of stored data associated with an address.

##Building the Contract
To build the contract, use the following command:
```bash
cd 
cargo build --target wasm32-unknown-unknown --release
```
This should output a .wasm file in the ../target directory:
```bash
../target/wasm32-unknown-unknown/release/soroban_auth_store_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_auth_store_contract.wasm
```
From this command you will get a Contract ID, save this for invoking it later.

##Invoking the Contract
First we need to invoke `put` function to store data using this command format :
```bash
soroban contract invoke --id <AuthContractID> --fn put -- --user <QuestPublicKey> --value '<StoredDataInHex>'
```
> Note : To convert string to hex use `echo "YourString" | xxd -p`
Next we will retrieve the stored data by invoking `get` function using this command :
```bash
soroban contract invoke --id <AuthContractID> -- get --owner <QuestPublicKey> 
```
By running that command you should get your stored data(in hex).

##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 2
```

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