Soroban Quest - Reverse Engineer
Tags: soroban, stellar, tutorial
Published: 2022-11-26 12:31:02

The Auth Store Quest we solved on the [last post](https://dev.to/altug/soroban-quest-auth-store-1aea) was quite the feat! We will now tackle the next quest: Reverse Engineer.

## Understanding `README.md`

As always, let's open the `README.md` file in the `3-reverse-engineer` folder and take a look.

![README](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27j6i4tv01fff6ch1qbi.png)

This quest is quite different! We are tasked with finding the contract ID of the already deployed contract. We have an important tip though, we are given the deployer account's public key, which is `GAC7HE4PQWI7H34JQN6QLQ7Y7NTAUZDWJZ4SJ6GXVC4K2DN7N65K5NLI`.

> #### The Concept of Public Ledgers
>
> Since we are transacting on a blockchain, all of our transactions are fully inspectable by anyone! Aside from privacy chains (Monero, Zcash, etc.), all of the transactions, meaning contract deployments, coin transfers, account creations are all easily inspectable! This is the case, as the validators should check the integrity of all the data that the blockchain has processed to achieve consensus between all nodes. Of course, there are some other ways such as [zk-proofs](https://en.wikipedia.org/wiki/Zero-knowledge_proof), which hide the details of the transactions while making them still verifiable!
>
> The so called "privacy" components of the blockchains comes from the idea that we do not know who the public key's owner is. This can be quite handy for privacy, but is also not the exact solution to the privacy problem as the transactions of a user can be mapped to a person with enough information, such as IP addresses, their social media sharings and so on.

## Setting Up Our Stellar Quest Account

As always, use `sq login` if you haven't, and use `sq play 2` to start questing. Don't forget to fund your account!

## Examining the Contract

Let's check out the `lib.rs` file in the `src` folder. The contract is quite short, but has some different concepts than previous contracts. Let's check it out.

```rust
pub struct ReverseEngineerContract;

const SECRET : Symbol = symbol!("dancinRaph");

#[contractimpl]
impl ReverseEngineerContract {
    pub fn submit(_: Env, secret: Symbol) -> bool{
        secret == SECRET
    }
}
```

We see that there is only one function, `submit`, which takes the argument `secret` of type `Symbol`. If you remember, the `Symbol` type can be thought as a `string` with a maximum length of 10.

Focus on the following line:

```rust
const SECRET : Symbol = symbol!("dancinRaph");
```

We can see that a constant value is defined here, which is not modifiable by any means using any functions in the contract, or elsewhere. The `SECRET` constant is also of type `Symbol`, and has the value of `"dancinRaph"`.

> #### Constants and Secrets in Blockchains
>
> Since the blockchain ledgers are actually public, we can't have secret values by just naming them "SECRET" and not telling anyone. Having the source code of course makes guessing the value trivial, but anyone can *reverse engineer* any contract's source code, and with some simple bytecode translations, view all of your values.
>
> There are some ways of putting actual secret data on blockchains, such as hashing the values off-chain, and then submitting them. We can also check if another supplied value is correct, we can hash them on-chain, and compare the results. The wonders of cryptography!

## Examining the Test

We only have one test function for this quest.

```rust
#[test]
fn test_q3() {
    let env = Env::default();
    let contract_id = env.register_contract(None, ReverseEngineerContract);
    let client = ReverseEngineerContractClient::new(&env, &contract_id);

    assert_eq!(client.submit(&symbol!("wrong")), false);
    assert_eq!(client.submit(&SECRET), true);
}
```

What this test does is quite simple. It checks the output value by giving it a false input, and checks it again by giving it the correct input. We did not expect the contract to panic when we supply an invalid value, as it just simply returns the false value.

## Solving the Quest

To even attempt solving the quest, we should first find the contract ID of the quest contract. After finding the contract ID, we should supply the *secret* keyword that we found as the `secret` argument of the submit function, and solve the quest.

> #### Stellar Laboratory
>
> The [Stellar Laboratory](https://laboratory.stellar.org/) is a place for everything Stellar! You can check out all the endpoints of any Stellar network, even custom ones, and Build, Sign, and Decode transactions!
>
> The Laboratory is definitely a very helpful place, but since we are programmers, and programmers are lazy, we don't want to leave our cozy terminal to solve the quests! Jokes aside, do check out the [Stellar Laboratory](https://laboratory.stellar.org/) to learn more about the Horizon API and other Stellar concepts.

### Finding the Contract ID

Since the only information we have about the contract is the deployer account, let's check what the deployer account has done on the Futurenet. Let's communicate with the Horizon API from our terminal. Use

```bash
curl https://horizon-futurenet.stellar.org/accounts/GAC7HE4PQWI7H34JQN6QLQ7Y7NTAUZDWJZ4SJ6GXVC4K2DN7N65K5NLI/operations
```

To get some information about the deployer account. The output is quite large, but the interesting part of the JSON response is as follows.

```json
{
  --snip--

  "transaction_successful": true,
  "source_account": "GAC7HE4PQWI7H34JQN6QLQ7Y7NTAUZDWJZ4SJ6GXVC4K2DN7N65K5NLI",

  --snip--

  "transaction_hash": "b4ead070088ad86a32c341907d9944a4f3def6c7f1e42cd6e1789d10ca344c38",

  --snip--

  "function": "HostFunctionHostFnCreateContractWithSourceAccount",
  "footprint": "AAAAAAAAAAEAAAAGTNbD4mfKK1nhwm9oUMF+GpFYPmEFgv/ujOvINx6UVzoAAAADAAAAAw=="
}
```

We see that the account `GAC7HE4PQWI7H34JQN6QLQ7Y7NTAUZDWJZ4SJ6GXVC4K2DN7N65K5NLI` has used the function `HostFunctionHostFnCreateContractWithSourceAccount`, which means that they successfully deployed a contract on the Soroban network. If we inspect the footprint using the `soroban` CLI, we can get more information about the transaction.

```bash
soroban xdr dec \
--type LedgerFootprint \
--xdr AAAAAAAAAAEAAAAGTNbD4mfKK1nhwm9oUMF+GpFYPmEFgv/ujOvINx6UVzoAAAADAAAAAw== \
--output json | grep contractId
```

We got the contract ID!

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

> #### XDR Types
>
> eXternal Data Representation (XDR) is a format that is quite compact, reliable, and rich. Stellar ledger uses XDR formatted data to communicate with clients and store all kinds of data. They are shown base64 encoded, which compresses the data even more when communicating with clients. Check out [Stellar Docs on XDR](https://developers.stellar.org/docs/encyclopedia/xdr) for more information.

### Invoking the `submit` Function

Now that we have found the contract ID, we can call the `submit` function on the `ReverseEngineerContract`.

```bash
soroban invoke \
--id 4cd6c3e267ca2b59e1c26f6850c17e1a91583e610582ffee8cebc8371e94573a \
--fn submit --arg dancinRaph
```

![Submit Function Call](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6fgjwukjistv8b83tlc.png)

Success! Since we got true as the response, we know that we supplied the correct parameter as an argument. Use `sq check 3` to claim your reward 🎉!