-
Notifications
You must be signed in to change notification settings - Fork 20
feat: first draft of tutorial #193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
caa3df1 to
2399b61
Compare
There was a problem hiding this 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"); |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
- 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>
There was a problem hiding this 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.
Co-authored-by: Willem Wyndham <willem@ahalabs.dev>
There was a problem hiding this 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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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! |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
| 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)]`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording confuses me.
| 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)]`. |
TODOs: