Skip to content

Conversation

@zachfedor
Copy link
Contributor

@zachfedor zachfedor commented Sep 23, 2025

TODOs:

  • complete 01-getting-started with build and deploy to local net
  • add running UI to first section of 02-making-improvements and show Contract Explorer
    • this is a good time to show the new private function doesn't show up
    • side by side w/ CLI
    • invoke via alias
  • changing above contract function requires changing react component
  • finish final step of obfuscating the number

Copy link
Member

@chadoh chadoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bundle of comments!


```rust
const THE_NUMBER: Symbol = symbol_short!("n");
pub const ADMIN_KEY: &Symbol = &symbol_short!("ADMIN");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I always prefer & here since you always refer to them as references, I say we stick with one or the other. Perhaps the value as to not introduce references at this point.


Our `reset` method is available to be called by code _outside_ our contract because we opted in to it being a public method with the `pub`. Our `set_random_number` is private by default, it's not even visible to the outside world. It's not listed in the Contract Explorer. It's not listed in the CLI help either:

```bash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should get a little more explanation. Unless I messed where invoking with the CLI was introduced.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we need to do this here, wdyt @zachfedor

chadoh and others added 6 commits October 28, 2025 14:03
- remove `environments.toml` walkthrough from step 1
- add it to step 2, as part of finding the line to change to break
  things
- remove `unwrap` vs `expect` considerations, since both result in
  identical & terrible errors in Soroban context
- explain `unsafe` bonus  step
- clean up outdated references to `alice` and such
also

- update code to more closely match expected final state
- add frontend-update section (it's a stub for now)
…vements.md

Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
Copy link
Member

@chadoh chadoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks good through Step 2, and Step 3 has a good start. I'd like to see the TODO items in Step 3 cleaned up a bit (like, the headings jump from Step 4 to Step 7 for some reason), but then I think we could merge as-is. We don't need to finish it to merge, but the "TODOs" and in-progress nature of it should make sense, and potentially help a motivated hackathoner send us improvements where they expand stub sections and implement our TODO items.

@chadoh chadoh marked this pull request as ready for review October 30, 2025 17:04
Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
Copy link
Member

@tupui tupui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 🙌

For now I just reviewed 00 and 01. I will try to finish later today or this WE.

If you just want to get up and running quickly, check out the [Quick Start](/docs/quick-start.mdx) guide.
:::

Before jumping in, you should have a basic understanding of the command line and of general programming concepts, but we'll walk through all the code together so don't worry if you're new to Stellar, Rust, or dApp development. We'll link out to [The Rust Programming Language book](https://doc.rust-lang.org/stable/book/) to explain concepts if you want to dive deeper.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also link to the official docs here and recommend people to take some time there https://developers.stellar.org

pub struct GuessTheNumber;
```

The `#[...]` syntax in Rust is called an [attribute](https://doc.rust-lang.org/reference/attributes.html). It's a way to label code for the compiler to handle it with special instructions. *Inner* attributes (with the `#!`) apply to the scope they're within (meaning `!#[no_std]` applies to the whole file/module), and *Outer* attributes (just the `#`) apply to the next line.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo? We have !# and #! in the text. But IMO the explanation might be going too deep into Rust for a tutorial. I think it's enough to stick to saying it's a macro and does stuff for you. We already have some explanations about no_std above and most people won't do much more than that.

<a id="init"></a>
## 🏗️ Initialize Your Project

Our smart contract will be a Guess The Number game. You (the admin) can deploy the contract, randomly select a number between 1 and 10, and seed the contract with a prize. Users can make guesses and win the prize if they're correct!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should put this in the overview or in its own section as it's the problem statement. This should stand out a bit more.

/// Update the number. Only callable by admin.
pub fn reset(env: &Env) {
Self::require_admin(env);
let new_number: u64 = env.prng().gen_range(1..=10);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are inconsistent with the type here

}
```

And here is the reset function. Note that we use `require_admin()` here so only you can run this function. It generates a random number between 1 and 10 and uses our key to store it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a "custom" function. I am not sure if we should discuss this here or later. I think when we introduce no_std, it's would be a good place to say that we "augmented" the SDK with these.

```

Finally, we add the `guess` function which accepts a number as the guess and compares it to the stored number, returning the result. Notice we're using our defined key (that small Symbol) to find stored data that may or may not be there. That's why we need [`unwrap()`](https://doc.rust-lang.org/rust-by-example/error/option_unwrap.html), but we'll talk more about `Option` values later in the tutorial.
Finally, we add the `guess` function which accepts a number as the guess and compares it to the stored number, returning the result. Notice we're using our defined key (that small Symbol) to find stored data that may or may not be there. The thing returned from `get` is a Rust [Option](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#the-option-enum-and-its-advantages-over-null-values), which is Rust's improvement over the `null` type. An `Option` can be `Some` or `None`. We use [`expect()`](https://doc.rust-lang.org/std/option/enum.Option.html#method.expect) to return the value contained in the `Some` or to panic with the "no number set" message if `None`. We'll talk more about `Option` values later in the tutorial.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should go into details

Suggested change
Finally, we add the `guess` function which accepts a number as the guess and compares it to the stored number, returning the result. Notice we're using our defined key (that small Symbol) to find stored data that may or may not be there. The thing returned from `get` is a Rust [Option](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#the-option-enum-and-its-advantages-over-null-values), which is Rust's improvement over the `null` type. An `Option` can be `Some` or `None`. We use [`expect()`](https://doc.rust-lang.org/std/option/enum.Option.html#method.expect) to return the value contained in the `Some` or to panic with the "no number set" message if `None`. We'll talk more about `Option` values later in the tutorial.
Finally, we add the `guess` function which accepts a number as the guess and compares it to the stored number, returning the result. Notice we're using our defined key (that small Symbol) to find stored data that may or may not be there. The thing returned from `get` is a Rust [Option](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html#the-option-enum-and-its-advantages-over-null-values). An `Option` can be `Some` or `None`. We use [`expect()`](https://doc.rust-lang.org/std/option/enum.Option.html#method.expect) to return the value contained in the `Some` or to panic with the "no number set" message if `None`. We'll talk more about `Option` values later in the tutorial.

```

Post Script: this last line includes the test module into this file. It's handy to write unit tests for our code in a separate file (`contracts/guess-the-number/src/test.rs`), but you could also write them inline if you want.
Post Script: this last line includes the test module into this file. It's handy to write unit tests for our code in a separate file (`contracts/guess-the-number/src/test.rs`), but you could also write them inline if you want by defining the module. Note you also need to tell the compile that this is a test module, which is at the top of our file `#![cfg(test)]`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording confuses me.

Suggested change
Post Script: this last line includes the test module into this file. It's handy to write unit tests for our code in a separate file (`contracts/guess-the-number/src/test.rs`), but you could also write them inline if you want by defining the module. Note you also need to tell the compile that this is a test module, which is at the top of our file `#![cfg(test)]`.
This last line includes the test module into this file. It's handy to write unit tests for our code in a separate file (`contracts/guess-the-number/src/test.rs`), but you could also write them inline if you want by defining the module. Note you also need to tell the compile that this is a test module, which is at the top of our file `#![cfg(test)]`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants