diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7cf7ae4..30cc761 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -9,6 +9,8 @@ - [Final Code](./counter/final_code.md) - [Using RAEN](./counter/working_with_contract.md) - [RAEN Admin](./counter/admin.md) + - [Updating the contract](./counter/updating.md) + - [Summary](./counter/summary.md) - [Status Message](./status-message/intro.md) - [Defining the data](./status-message/simple/simple.md) diff --git a/src/counter/summary.md b/src/counter/summary.md new file mode 100644 index 0000000..378fb50 --- /dev/null +++ b/src/counter/summary.md @@ -0,0 +1,9 @@ +# Counter Summary + +In this chapter we saw our first Rust code, a simple NEAR smart contract that implements a counter. Anyone can call `get_num` to see the current value, and anyone can sign in and call change methods to change the number. + +We saw how RAEN Admin makes it easy to interact with contracts built with RAEN. We dug deeper and saw how we can change the contract, re-deploy, and see that RAEN Admin will automatically show the latest version of the contract. + +We even investigated some more advanced Rust features, such as changing settings in `Cargo.toml` and implementing a custom `Default` rather than deriving it. + +Overall, this Counter was a good way to learn some Rust and NEAR basics, but pretty silly as a real contract. Next, let's take a look at an example that does something more useful, storing different information for every user who calls the contract. diff --git a/src/counter/updating.md b/src/counter/updating.md new file mode 100644 index 0000000..ae95dc8 --- /dev/null +++ b/src/counter/updating.md @@ -0,0 +1,96 @@ +# Updating the contract + +[Earlier](./first_steps.md) we said that if an `i8` is currently `127` and you increment it again, it will _overflow_, becoming `-128`. Likewise, it can _underflow_ if currently `-128` and you decrement. + +Let's see if we can make `val` overflow! And then let's see how to prevent this. + +# Method 1: mash `increment` 128 times + +With the existing contract, you could use the RAEN Admin panel and mash the Submit button on the `increment` form 128 times. + +This could take a while, though! Let's see if we can improve the code to make it easier. + +# Method 2: new `default` + +If you're following along with your own contract, you can change the default value of `val` to start at `127` rather than `0`. This is a good way to learn about where the default of `0` currently comes from. + +If you get stuck while following along, you can see this method and the following all implemented on [this branch](https://github.com/raendev/examples/pull/4/files). + +Above `pub struct Counter`, change the `derive` macro by removing the `Default` trait: + +```diff +-#[derive(Default, BorshDeserialize, BorshSerialize)] ++#[derive(BorshDeserialize, BorshSerialize)] +``` + +Now, below the closing bracket of `pub struct Counter`, you can implement `default` manually: + +```rust +pub struct Counter { + val: i8, +} + +impl Default for Counter { + fn default() -> Self { + Self { val: 127 } + } +} +``` + +## If you're following along + +If you're following along with your own code, you can build and re-deploy to see the new default: + +```bash +raen build --release -q | xargs -I {} near dev-deploy --wasmFile {} +``` + +(This [uses xargs to](https://stackoverflow.com/a/42631216/249801) pipe the output of `raen build` to the `wasmFile` argument of `near dev-deploy`.) + +If you've already incremented or decremented the number, though, you'll see that this made no change. Which is what you'd expect! It only changes the _default_. That is, the value that is shown if you didn't actually change it and store the new value. + +To see this default in action, you can delete the `neardev` folder and run the `dev-deploy` command again. This will create a brand new NEAR testnet account before deploying your contract. + +Paste this new account name into RAEN Admin, check `get_num`, and see the number you set as a default! Call `increment` (you'll need to sign in again, since this is a new contract.) + +## If you're not + +The contract deployed at [counter.raendev.testnet](https://raen.dev/admin/#/counter.raendev.testnet) already has a value for `val` saved to contract storage. It will not make use of a new default. + +Let's try a different way. + +# Method 3: new `set_num` + +See if you can write your own `set_num` method based on the code for `increment` and `decrement` in the contract. If you need a hint, [here's what it looks like](https://github.com/raendev/examples/pull/4/files). + +## If you're following along + +Save your file with new `set_num`, then build and re-deploy: + +```bash +raen build --release -q | xargs -I {} near dev-deploy --wasmFile {} +``` + +Unlike Method 2, you don't need to create a new testnet account. Just refresh the RAEN Admin panel and see the `set_num` method appear under Change Methods. Go ahead and try it out! + +## If you're not + +The [reference code](https://github.com/raendev/examples/pull/4/files) has been deployed to [v2.counter.raendev.testnet](https://raen.dev/admin/#/v2.counter.raendev.testnet) for you to play with. + +Note that this code already fixed the overflow issue. If you want to see the overflow in action, you'll have to follow along with your own code. + +# Fixing that overflow + +Now you can call `increment` and see that the number goes from `127` to `-128`. Oops! How do we fix it? + +Open up the `Cargo.toml` file. [Cargo.toml](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html) is to Rust what `package.json` is to NodeJS. You'll see sections for `dependencies` and `dev-dependencies` and more generic information about this package/contract/crate. + +See those lines with `overflow-checks = false`? Change them to `overflow-checks = true`. Now rebuild and redeploy: + +```bash +raen build --release -q | xargs -I {} near dev-deploy --wasmFile {} +``` + +You'll see that this takes longer to build than when you make changes to your contract itself. Rust needs to recompile all of your dependencies using the new setting. + +Refresh your admin panel, set the number back to `127`, and call `increment`. You'll see an error message. This means the contract panicked rather than allowing the integer overflow. It worked!