Skip to content
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

fix crossword tutorial #1673

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docs/3.tutorials/crosswords/01-basics/01-set-up-skeleton.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 2
sidebar_label: "Set up Rust and a contract skeleton"
title: "Set up Rust, get a NEAR testnet account, NEAR CLI, and get a basic smart contract skeleton ready"
---
import {Github} from "@site/src/components/codetabs"

# Getting started

Expand Down Expand Up @@ -91,9 +92,7 @@ By changing the `name` here, we'll be changing the compiled Wasm file's name aft

Now let's look at our main file, in `src/lib.rs`:

```rust reference
https://github.com/near/boilerplate-template-rs/blob/f1edeead98a9ec12c3f6db311f62025305f57874/contract/src/lib.rs#L8-L44
```
<Github language="rust" start="8" end="44" url="https://github.com/near/boilerplate-template-rs/blob/f1edeead98a9ec12c3f6db311f62025305f57874/contract/src/lib.rs" />

As you can see, this is a stub that's ready to be filled in. Let's pause and point out a few items:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 3
sidebar_label: "Add basic code, create a subaccount, and call methods"
title: "Alter the smart contract, learning about basics of development"
---
import {Github} from "@site/src/components/codetabs"

import teachingDeployment from '/docs/assets/crosswords/teaching--jeheycell.near--artcultureac.jpeg';
import createAccount from '/docs/assets/crosswords/creating account with text--seanpineda.near--_seanpineda.png';
Expand All @@ -16,9 +17,7 @@ This section will modify the smart contract skeleton from the previous section.

Let's modify the contract to be:

```rust reference
https://github.com/near-examples/crossword-snippets/blob/00223633f3e6b5b7137097e996b0aee90d632b0f/src/lib.rs#L1-L29
```
<Github language="rust" start="1" end="29" url="https://github.com/near-examples/crossword-snippets/blob/00223633f3e6b5b7137097e996b0aee90d632b0f/src/lib.rs" />

We've done a few things here:
1. Set a constant for the puzzle number.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 4
sidebar_label: "Hash the solution, unit tests, and an init method"
title: "Introduction to basic hashing and adding unit tests"
---
import {Github} from "@site/src/components/codetabs"

import batchCookieTray from '/docs/assets/crosswords/batch-of-actions--dobulyo.near--w_artsu.jpg';

Expand All @@ -26,9 +27,7 @@ As mentioned in the first section of this **Basics** chapter, our smart contract

We'll add a dependency to the [hex crate](https://crates.io/crates/hex) to make things easier. As you may remember, dependencies live in the manifest file.

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/481a83f0c90398f3234ce8006af4e232d6c779d7/contract/Cargo.toml#L10-L12
```
<Github language="rust" start="10" end="12" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/481a83f0c90398f3234ce8006af4e232d6c779d7/contract/Cargo.toml" />

Let's write a unit test that acts as a helper during development. This unit test will sha256 hash the input **"near nomicon ref finance"** and print it in a human-readable, hex format. (We'll typically put unit tests at the bottom of the `lib.rs` file.)

Expand Down Expand Up @@ -59,7 +58,9 @@ Take a look at different formatting traits that are covered in the [`std` Rust d

Run the unit tests with the command:

cargo test -- --nocapture
```
cargo test -- --nocapture
```

You'll see this output:

Expand All @@ -72,13 +73,15 @@ test tests::debug_get_hash ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
```

This means when you sha256 the input "near nomicon ref finance" it produces the hash:
This means when you sha256 the input **"near nomicon ref finance"** it produces the hash:
`69c2feb084439956193f4c21936025f14a5a5a78979d67ae34762e18a7206a0f`

:::tip Note on the test flags
You may also run tests using:

cargo test
```
cargo test
```

Note that the test command we ran had additional flags. Those flags told Rust *not to hide the output* from the tests. You can read more about this in [the cargo docs](https://doc.rust-lang.org/cargo/commands/cargo-test.html#display-options). Go ahead and try running the tests using the command above, without the additional flags, and note that we won't see the debug message.
:::
Expand All @@ -89,9 +92,7 @@ The unit test above is meant for debugging and quickly running snippets of code.

Let's add this unit test (inside the `mod tests {}` block, under our previous unit test) and analyze it:

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/d7699cf35092024fe11719b68788436c82fe82af/contract/src/lib.rs#L63-L93
```
<Github language="rust" start="63" end="93" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/5bce1c2a604fcb179e9789de1f299063f91abb4d/contract/src/lib.rs" />

The first few lines of code will be used commonly when writing unit tests. It uses the `VMContextBuilder` to create some basic context for a transaction, then sets up the testing environment.

Expand All @@ -103,12 +104,17 @@ This unit test uses the [`assert_eq!`](https://doc.rust-lang.org/std/macro.asser

Again, we can run all the unit tests with:

cargo test -- --nocapture
```
cargo test -- --nocapture
```

:::tip Run only one test
To only run this latest test, use the command:

cargo test check_guess_solution -- --nocapture
```
cargo test check_guess_solution -- --nocapture
```

:::

## Modifying `set_solution`
Expand All @@ -119,9 +125,7 @@ Let's have the solution be set once, right after deploying the smart contract.

Here we'll use the [`#[near_bindgen]` macro](https://docs.rs/near-sdk/latest/near_sdk/attr.near_bindgen.html) on a function called `new`, which is a common pattern.

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/94f42e75cf70ed2aafb9c29a1faa1e21f079a49e/contract/src/lib.rs#L10-L17
```
<Github language="rust" start="10" end="17" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/94f42e75cf70ed2aafb9c29a1faa1e21f079a49e/contract/src/lib.rs" />

Let's call this method on a fresh contract.

Expand Down Expand Up @@ -156,9 +160,7 @@ This is close to what we want, but what if a person deploys their smart contract
Batch Actions are common in this instance, where we want to deploy and call an initialization function. They're also common when using a factory pattern, where a subaccount is created, a smart contract is deployed to it, a key is added, and a function is called.

Here's a truncated snippet from a useful (though somewhat advanced) repository with a wealth of useful code:
```rust reference
https://github.com/near/core-contracts/blob/1720c0cfee238974ebeae8ad43076abeb951504f/staking-pool-factory/src/lib.rs#L172-L177
```
<Github language="rust" start="172" end="177" url="https://github.com/near/core-contracts/blob/1720c0cfee238974ebeae8ad43076abeb951504f/staking-pool-factory/src/lib.rs" />

We'll get into Actions later in this tutorial, but in the meantime here's a handy [reference from the spec](https://nomicon.io/RuntimeSpec/Actions.html).
:::
Expand Down Expand Up @@ -192,12 +194,12 @@ In the next section we'll add a simple frontend for our single, hardcoded crossw

We'll also modify our `guess_solution` to return a boolean value, which will also make things easier for our frontend.

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/94f42e75cf70ed2aafb9c29a1faa1e21f079a49e/contract/src/lib.rs#L19-L34
```
<Github language="rust" start="19" end="34" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/94f42e75cf70ed2aafb9c29a1faa1e21f079a49e/contract/src/lib.rs" />

The `get_solution` method can be called with:

near view crossword.friend.testnet get_solution
```
near view crossword.friend.testnet get_solution
```

In the next section we'll add a simple frontend. Following chapters will illustrate more NEAR concepts built on top of this idea.
21 changes: 6 additions & 15 deletions docs/3.tutorials/crosswords/01-basics/04-simple-frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 5
sidebar_label: "Add simple frontend"
title: "Add a simple frontend to the crossword puzzle that checks the solution's hash"
---
import {Github} from "@site/src/components/codetabs"

import nearReactFriends from '/docs/assets/crosswords/near-and-react--dakila.near--rodolf_dtbbx.png';

Expand All @@ -25,9 +26,7 @@ There will be three main files we'll be working with:

We'll go over a pattern that may look familiar to folks who have surveyed the [NEAR examples site](https://github.com/near-examples). We'll start with an asynchronous JavaScript function that sets up desired logic, then pass that to the React app.

```js reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/index.js#L3-L22
```
<Github language="js" start="3" end="22" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/index.js" />

Let's talk through the code above, starting with the imports.

Expand All @@ -45,9 +44,7 @@ Lastly, we'll call `initCrossword` and, when everything is complete, pass data t

Here's a large portion of the `App.js` file, which will make use of a fork of a React crossword library by Jared Reisinger.

```js reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/App.js#L3-L54
```
<Github language="js" start="3" end="54" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/App.js" />

We'll discuss a few key points in the code above, but seeing as we're here to focus on a frontend connection to the blockchain, will brush over other parts that are library-specific.

Expand Down Expand Up @@ -79,9 +76,7 @@ We'll be using two utility functions here:

We'll only focus on the second method:

```js reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/utils.js#L8-L12
```
<Github language="js" start="8" end="12" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/utils.js" />

This API doesn't look warm and friendly yet. You caught us! We'd love some help to improve our API as [detailed in this issue](https://github.com/near/near-api-js/issues/612), but for now, this is a concise way to get data from a view-only method.

Expand Down Expand Up @@ -114,14 +109,10 @@ env CONTRACT_NAME=crossword.friend.testnet npm run start

The last line sends the environment variable `CONTRACT_NAME` into the NodeJS script. This is picked up in the `config.js` file that's used to set up the contract account and network configuration:

```js reference
https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/config.js#L1
```
<Github language="js" start="1" end="2" url="https://github.com/near-examples/crossword-tutorial-chapter-1/blob/3e497b4815600b8382614f76c7812520710f704d/src/config.js" />

After running the last command to start the React app, you'll be given a link to a local website, like `https://localhost:1234`. When you visit the site you'll see the simple frontend that interacts with our smart contract:

![Crossword puzzle frontend showing a filled out puzzle with clues on the right sidebar](/docs/assets/crosswords/basics-final-frontend.png)

Again, the full code for this chapter is available at:

https://github.com/near-examples/crossword-tutorial-chapter-1
Again, the full code for this chapter is [available here](https://github.com/near-examples/crossword-tutorial-chapter-1).
13 changes: 4 additions & 9 deletions docs/3.tutorials/crosswords/02-beginner/01-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 2
sidebar_label: "Store multiple puzzles"
title: "Store multiple crossword puzzles using a specialized collection in NEAR called a LookupMap"
---
import {Github} from "@site/src/components/codetabs"

import bookPagination from '/docs/assets/crosswords/paging-through-hashes-swing--pierced_staggg.near--pierced_stag.jpg';
import guardsAroundContract from '/docs/assets/crosswords/guards-contract-permissions--connoisseur_dane.near--connoisseurdane.png';
Expand Down Expand Up @@ -51,19 +52,15 @@ The name of the struct doesn't matter and there's nothing special about naming i

Here's how our struct will look with the iterable and non-iterable NEAR collections:

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/276217ad82c64c610148e998ec926942ba910a12/contract/src/lib.rs#L73-L79
```
<Github language="rust" start="73" end="79" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/276217ad82c64c610148e998ec926942ba910a12/contract/src/lib.rs" />

Above, we have the `puzzles` and `unsolved_puzzles` fields which are collections.

We also have an `owner_id` so we can exercise a common pattern in smart contract development: implementing a rudimentary permission system which can restrict access to certain functions. We'll expand on this thought in a moment.

The snippet below shows the first method in the implementation of the `Crossword` struct, where the `new` function sets up these two specialized collections.

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/276217ad82c64c610148e998ec926942ba910a12/contract/src/lib.rs#L81-L90
```
<Github language="rust" start="81" end="90" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/276217ad82c64c610148e998ec926942ba910a12/contract/src/lib.rs" />

So during the initialization function (`new`) we're setting the `owner_id`. For our purposes the owner will likely be the contract itself, but there can be several reasons to have it be a DAO or another user. Next, let's look at the `b"c"` and `b"u"` bits for the collection fields.

Expand All @@ -75,9 +72,7 @@ Let's take a peek at how we'll add a new crossword puzzle. Note that there will

Unlike the previous chapter where there was only one crossword puzzle, we'll be inserting into our new collections, so let's create a `new_puzzle` method.

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/8ec941c82539e6eafa4971444e1da9e4819330d3/contract/src/lib.rs#L147-L163
```
<Github language="rust" start="147" end="163" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/8ec941c82539e6eafa4971444e1da9e4819330d3/contract/src/lib.rs" />

Now we're set up to store multiple puzzles!

Expand Down
9 changes: 3 additions & 6 deletions docs/3.tutorials/crosswords/02-beginner/03-actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 4
sidebar_label: "Actions and sending NEAR"
title: "There are several Actions an account can do, including sending the winner of the crossword puzzle NEAR using the Transfer Action"
---
import {Github} from "@site/src/components/codetabs"

import allActions from '/docs/assets/crosswords/crossword-actions.png';
import transferNEAR from '/docs/assets/crosswords/transfer-brand-blue--qiqi04.near--blankworl.png';
Expand Down Expand Up @@ -49,9 +50,7 @@ Let's make it simple and hardcode the prize amount. This is how much NEAR will b

At the top of the `lib.rs` file we'll add this constant:

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/1909630a10291081cb00b2780c1ae8889d98f620/contract/src/lib.rs#L10-L11
```
<Github language="rust" start="10" end="11" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/1909630a10291081cb00b2780c1ae8889d98f620/contract/src/lib.rs" />

As the code comment mentions, this is 5 NEAR, but look at all those zeroes in the code!

Expand All @@ -66,9 +65,7 @@ That's the value in yoctoNEAR. This concept is similar to other blockchains. Bit

In the last chapter we had a simple function called `guess_solution` that returned `true` if the solution was correct, and `false` otherwise. We'll be replacing that function with `submit_solution` as shown below:

```rust reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/83d4d8925e6d30e04e8e4cb5e9a0a6d3763fce40/contract/src/lib.rs#L92-L124
```
<Github language="rust" start="92" end="124" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/83d4d8925e6d30e04e8e4cb5e9a0a6d3763fce40/contract/src/lib.rs" />

Note the last line in this function, which sends NEAR to the predecessor.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 6
sidebar_label: "Access keys and login 2/2"
title: "Implementing the login button"
---
import {Github} from "@site/src/components/codetabs"

import loggingIn from '/docs/assets/crosswords/logging-in.png';
import explorerTransfer from '/docs/assets/crosswords/chapter-2-explorer-transfer.jpg';
Expand Down Expand Up @@ -32,9 +33,7 @@ We won't go over every change, but instead point to the new logic.

First we set up a `WalletConnection` object from our JavaScript library:

```js reference
https://github.com/near-examples/crossword-tutorial-chapter-2/blob/1d64bf29c3376a18c71e5c5a075e29824d7a55f5/src/index.js#L12-L20
```
<Github language="js" start="12" end="20" url="https://github.com/near-examples/crossword-tutorial-chapter-2/blob/1d64bf29c3376a18c71e5c5a075e29824d7a55f5/src/index.js" />

It's then used in React:

Expand Down
13 changes: 4 additions & 9 deletions docs/3.tutorials/crosswords/03-intermediate/03-linkdrop.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ sidebar_position: 4
sidebar_label: "Linkdrop contract"
title: "Introducing the linkdrop contract we can use"
---
import {Github} from "@site/src/components/codetabs"

import createMainnetAccount from '/docs/assets/crosswords/create-mainnet-account.png';
import createTestnetAccount from '/docs/assets/crosswords/create-testnet-wallet-account.png';
Expand Down Expand Up @@ -51,9 +52,7 @@ We'll want to write a smart contract that calls that same method. However, thing

Here, we'll show the implementation of the `create_account` method. Note the `#[payable]` macro, which allows this function to accept an attached deposit. (Remember in the CLI command we were attaching 15 Ⓝ.)

```rust reference
https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs#L125-L149
```
<Github language="rust" start="125" end="149" url="https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs" />

The most important part of the snippet above is around the middle where there's:

Expand Down Expand Up @@ -88,15 +87,11 @@ In other programming languages promises might work like this, but we must use ca

Now let's look at the callback:

```rust reference
https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs#L151-L164
```
<Github language="rust" start="151" end="164" url="https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs" />

This calls the private helper method `is_promise_success`, which basically checks to see that there was only one promise result, because we only attempted one Promise:

```rust reference
https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs#L32-L42
```
<Github language="rust" start="32" end="42" url="https://github.com/near/near-linkdrop/blob/ba94a9c7292d3b48a0a8ba380fb0e7ff6b24efc6/src/lib.rs" />

Note that the callback returns a boolean. This means when we modify our crossword puzzle to call the linkdrop contract on `testnet`, we'll be able to determine if the account creation succeeded or failed.

Expand Down
Loading
Loading