You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update tutorial to match frontend tutorial branch (#344)
* Clean up tutorial to match frontend tutorial branch
* Tweaks to adding-payments
* Apply formatter updates
* Make ADMIN_KEY private because it doesn't need to be public in tutorial
* A few more tweaks to be the same as the tutorial code
Copy file name to clipboardExpand all lines: website/docs/tutorial/01-getting-started.md
+16-11Lines changed: 16 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -225,13 +225,15 @@ In this case `#[contract]` is an [attribute macro](https://doc.rust-lang.org/ref
225
225
Here we're defining a [struct](https://doc.rust-lang.org/book/ch05-01-defining-structs.html) (a "structure" to hold values) and applying attributes of a Stellar smart contract. A `struct` also allows defining methods. In this case the structs holds no values but we will still define methods on it.
Now the most important part of our contract: the number! This line creates a key for storing and retrieving contract data. A `Symbol` is a short string type (max 32 characters) that is more optimized for use on the blockchain. And we're using the `symbol_short` macro for an even smaller key (max 9 characters). As a contract author, you want to use tricks like this to lower costs as much as you can.
233
233
234
-
The second line creates a key for storing the address of this contract's administrator. It's almost the same code as storing our number, but uses the `&` which is called a [reference](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html). Instead of the value, it's a pointer to where the value lives.
234
+
The second line creates a key for storing the address of this contract's administrator.
235
+
236
+
Both of these keys use the `&` which is called a [reference](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html). Instead of the value, it's a pointer to where the value lives.
235
237
236
238
```rust
237
239
#[contractimpl]
@@ -241,7 +243,7 @@ impl GuessTheNumber {
241
243
Let's `impl`ement our contract's functionality.
242
244
243
245
```rust
244
-
pubfn__constructor(env:&Env, admin:&Address) {
246
+
pubfn__constructor(env:&Env, admin:Address) {
245
247
Self::set_admin(env, admin);
246
248
}
247
249
```
@@ -253,20 +255,20 @@ A contract's `constructor` runs when it is deployed. In this case, we're saying
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.
261
263
262
264
```rust
263
-
/// Guess a number from 1 to 10
265
+
/// Guess a number between 1 and 10
264
266
pubfnguess(env:&Env, a_number:u64) ->bool {
265
267
a_number
266
268
==env
267
269
.storage()
268
270
.instance()
269
-
.get::<_, u64>(&THE_NUMBER)
271
+
.get::<_, u64>(THE_NUMBER)
270
272
.expect("no number set")
271
273
}
272
274
```
@@ -277,7 +279,7 @@ Finally, we add the `guess` function which accepts a number as the guess and com
277
279
modtest;
278
280
```
279
281
280
-
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)]`.
282
+
This line makes sure to include the test module in the 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)]`.
281
283
282
284
```rust
283
285
#[cfg(test)]
@@ -297,7 +299,7 @@ The docstring for our `guess` function says to guess a number "between 1 and 10"
297
299
pubfnguess(env:&Env, a_number:u64) ->bool {
298
300
```
299
301
300
-
Save the file and watch your terminal output. The contracts get rebuilt, redeployed, and clients for them get regenerated for your frontend. Then Vite hot-reloads your app and you should see the change in the contract explorer in your browser.
302
+
Save the file and watch your terminal output. The contracts get rebuilt, redeployed, and clients for them get regenerated for your frontend. Then Vite hot-reloads your app and you should see the change in the Debugger in your browser.
301
303
302
304
Tada!
303
305
@@ -324,8 +326,11 @@ We're storing some state for tracking the input's value and whether the guess wa
324
326
325
327
```ts
326
328
const submitGuess =async () => {
327
-
if (!theGuess) return;
328
-
const { result } =awaitgame.guess({ a_number: BigInt(theGuess) });
Copy file name to clipboardExpand all lines: website/docs/tutorial/02-making-improvements.md
+21-20Lines changed: 21 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -154,7 +154,7 @@ Let's walk through this line by line:
154
154
1. The Wasm gets uploaded to the blockchain, so that many contracts could use it.
155
155
2. A contract gets deployed (aka "instantiated", in the current parlance of this output) so that there is an actual smart contract that refers to, or points to, that Wasm.
156
156
157
-
-`after_deploy`: calls to the contract to make after it gets deployed. Kind of like the `constructor_args`, these are specified using _only_ the part that comes after the `--`. The setting above tells Scaffold CLI to make the following call, after deploying the contract:
157
+
-`after_deploy`: method calls to make to the contract after it gets deployed. Kind of like the `constructor_args`, but, these are specified using _only_ the part that comes after the `--`. The setting above tells Scaffold CLI to make call the `reset` method, after deploying the contract:
158
158
159
159
```bash
160
160
stellar contract deploy \
@@ -192,9 +192,9 @@ If you already tried re-running the `guess` logic in the app, you'll see...
192
192
193
193
Nothing. Nothing happens. At least not yet.
194
194
195
-
The contract didn't change, so Scaffold CLI didn't re-deploy the contract. You're still using the one that had the `reset` method called right after deploy.
195
+
The contract didn't change, so Scaffold CLI didn't re-deploy the contract. You're still using the instance that had the `reset` method called right after deploy.
196
196
197
-
Once [theahaco/scaffold-stellar#259](https://github.com/theahaco/scaffold-stellar/issues/259) is complete, you will be able to run `stellar scaffold reset`. Until then, you can remove the alias that Scaffold Stellar uses to keep track of this contract. Stop the `npm run start` process, then run:
197
+
Once [theahaco/scaffold-stellar#259](https://github.com/theahaco/scaffold-stellar/issues/259) is complete, you will be able to run `stellar scaffold reset`. Until then, you can remove the alias that Scaffold Stellar uses to keep track of this contract, which allows us to re-deploy a new `guess_the_number` contract. Stop the `npm run start` process, then run:
198
198
199
199
```bash
200
200
stellar contract alias remove guess_the_number --network local
@@ -242,7 +242,7 @@ impl GuessTheNumber {
242
242
/// Private helper function to generate and store a new random number
@@ -261,7 +261,7 @@ Notice that this function doesn't have `pub` in front of it - this makes it priv
261
261
Now let's modify the `__constructor` to set an initial number when the contract is deployed:
262
262
263
263
```rust
264
-
pubfn__constructor(env:&Env, admin:&Address) {
264
+
pubfn__constructor(env:&Env, admin:Address) {
265
265
Self::set_admin(env, admin);
266
266
Self::set_random_number(env); // Add this line
267
267
}
@@ -291,7 +291,7 @@ Much cleaner! The logic is now centralized in our helper function. Note that thi
291
291
$ npm start
292
292
```
293
293
294
-
Click over to `</> Debugger` if you're not there already and select the `guess_the_number` contract. You'll see that `reset` is listed here, but `set_random_number` is not.
294
+
Click over to the Debugger if you're not there already and select the `guess_the_number` contract. You'll see that `reset` is listed here, but `set_random_number` is not.
295
295
296
296
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` keyword. Our `set_random_number` is private by default, it's not visible to the outside world. It's not listed in the Contract Explorer. It's not listed in the CLI help either:
Nope! Just because we made it public, we still require authentication so only admins can call it. Rust's idea of public vs private handles "where" the functions can be called. You still need to handle "who" calls it. That's why we set the contract admin in it's constructor method and check it with `Self::require_admin(env);`.
317
317
318
-
You can try this out by invoking it from the Contract Explorer in your browser. The admin is `me`, but you didn't import that account into your browser wallet. Go ahead and hit `Submit` on the `reset` function.
318
+
You can try this out by invoking it from the Debugger in your browser. The admin is `me`, but you didn't import that account into your browser wallet. Go ahead and hit `Submit` on the `reset` function. You should see the transaction fail.
319
319
320
320
You could also try this out in the CLI. Create a non-admin identity to see how it fails:
321
321
@@ -383,12 +383,13 @@ use soroban_sdk::{contract, contractimpl, symbol_short, Address, BytesN, Env, Sy
/// Upgrade the contract to new wasm. Only callable by admin.
@@ -428,13 +429,13 @@ impl GuessTheNumber {
428
429
env.storage().instance().get(ADMIN_KEY)
429
430
}
430
431
431
-
///Set a new admin. Only callable by admin.
432
-
fnset_admin(env:&Env, admin:&Address) {
433
-
//Check if admin is already set
434
-
ifenv.storage().instance().has(ADMIN_KEY) {
432
+
///set a new admin. only callable by admin.
433
+
pubfnset_admin(env:&env, admin:address) {
434
+
//check if admin is already set
435
+
ifenv.storage().instance().has(admin_key) {
435
436
panic!("admin already set");
436
437
}
437
-
env.storage().instance().set(ADMIN_KEY, admin);
438
+
env.storage().instance().set(admin_key, &admin);
438
439
}
439
440
440
441
/// Private helper function to require auth from the admin
@@ -454,7 +455,7 @@ Let's test that our improvements work. You should still have the `npm start` pro
454
455
1.`stellar scaffold watch --build-clients`: watches for any changes in your `contracts/` folders, then rebuilds and redeploys them
455
456
2.`vite`: watches for any changes in your `src/` folder and hot-reloads the UI
456
457
457
-
That means any time you add a method, tweak arguments, or even add documentation, everything is immediately reflected on the local network, your application in the browser, and in the Contract Explorer. Let's add some info to the `guess` method's documentation:
458
+
That means any time you add a method, tweak arguments, or even add documentation, everything is immediately reflected on the local network, your application in the browser, and in the Debugger. Let's add some info to the `guess` method's documentation:
458
459
459
460
```rust
460
461
/// Guess a number between 1 and 10, inclusive. Returns a boolean.
@@ -465,7 +466,7 @@ As soon as you hit save, watch the Contract Explorer reload with the new text. N
Copy file name to clipboardExpand all lines: website/docs/tutorial/03-adding-payments.md
+9-15Lines changed: 9 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,16 +25,16 @@ This creates real stakes and makes the game much more engaging!
25
25
26
26
## Step 1: 🪙 Add Asset Import
27
27
28
-
First, we need the `import_asset` macro from Stellar Registry. Add the following to your imports at the top of `lib.rs`:
28
+
First, we need the `import_asset` macro from Stellar Registry. Add the following to your imports at the top of your contract `lib.rs` file:
29
29
30
30
```diff
31
31
#![no_std]
32
32
use soroban_sdk::{contract, contractimpl, symbol_short, Address, BytesN, Env, Symbol};
33
33
+use stellar_registry::import_asset;
34
-
+import_asset!(xlm);
34
+
+import_asset!("xlm");
35
35
```
36
36
37
-
Stellar Registry integrates with Scaffold Stellar, giving names & versions to contracts & contract Wasms. It also provides helpers like `import_asset` to make it easier to work with [Stellar Asset Contracts](https://developers.stellar.org/docs/tokens/stellar-asset-contract).
37
+
Stellar Registry integrates with Scaffold Stellar, giving names and versions to contracts and contract Wasms. It also provides helpers like `import_asset` to make it easier to work with [Stellar Asset Contracts](https://developers.stellar.org/docs/tokens/stellar-asset-contract).
38
38
39
39
## Step 2: 💰 Add Funds to the Contract
40
40
@@ -46,9 +46,9 @@ Whenever the admin resets the number, we need to transfer some funds to the cont
0 commit comments