From 26f3132bbb400e830343095a54f914035b68aef6 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 15:47:12 +0200 Subject: [PATCH 01/15] Updates on README. --- README.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3883265..f595ea9 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,33 @@ This book is about writing Smart Contracts using [Sylvia](https://github.com/CosmWasm/sylvia) framework. -To learn about CosmWasm on which Sylvia rely check [The Cosmwasm Book](https://book.cosmwasm.com/index.html) +To learn about CosmWasm, on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html) ## About -This repo contains source code for [The Sylvia Book](https://cosmwasm.github.io/sylvia-book/). +This repo contains a source code for [The Sylvia Book](https://cosmwasm.github.io/sylvia-book/). ## Building -The book is built using [mdbook](https://github.com/rust-lang/mdBook). - +The book is built using [mdBook](https://github.com/rust-lang/mdBook). To build it, you must first install [Rust](https://www.rust-lang.org/tools/install). -Then install `mdbook` using cargo: +Having Rust installed, install `mdBook` using cargo: ```bash $ cargo install mdbook ``` -and build the book from this directory: +and then build the book from this repository: + +```bash +$ mdbook build +``` + +To serve the book locally, run: ```bash -mdbook build +$ mdbook serve ``` -For more info about using mdbook read its own [book](https://rust-lang.github.io/mdBook/index.html). +To learn more about using `mdBook`, read its own [book](https://rust-lang.github.io/mdBook/index.html). From a1917bc021f4aabd9cbf9e6328b772cdf938b7dd Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 15:53:00 +0200 Subject: [PATCH 02/15] Fixed typo. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f595ea9..ec2ae6b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This book is about writing Smart Contracts using [Sylvia](https://github.com/CosmWasm/sylvia) framework. -To learn about CosmWasm, on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html) +To learn about CosmWasm, on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html). ## About From 5cdec040d27a4273cfdf981d60c625b390984d27 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 15:54:09 +0200 Subject: [PATCH 03/15] Added link to CosmWasm repo. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec2ae6b..f27a5e4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ This book is about writing Smart Contracts using [Sylvia](https://github.com/CosmWasm/sylvia) framework. -To learn about CosmWasm, on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html). +To learn about [CosmWasm](https://github.com/CosmWasm), +on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html). ## About From 6c9e391243c01424fedbfe51c6d6cc83f19f121d Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 15:56:06 +0200 Subject: [PATCH 04/15] Highlighted smart contract. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f27a5e4..abfeda3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # The Sylvia Book -This book is about writing Smart Contracts using [Sylvia](https://github.com/CosmWasm/sylvia) framework. +This book is about writing **Smart Contracts** using [Sylvia](https://github.com/CosmWasm/sylvia) framework. To learn about [CosmWasm](https://github.com/CosmWasm), on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html). From d16defc9835359b756f7a5575d550bc4b6f731e1 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 15:58:52 +0200 Subject: [PATCH 05/15] Removed PlantUML preprocessor. --- book.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/book.toml b/book.toml index 80cf242..7bf88ce 100644 --- a/book.toml +++ b/book.toml @@ -8,6 +8,3 @@ description = "Guide to building CosmWasm smart contracts" [rust] edition = "2021" - -[preprocessor.plantuml] -plantuml-cmd = "plantuml" \ No newline at end of file From d441eb2ff7e878e4586bc0c13863e83aff7ce529 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 16:11:47 +0200 Subject: [PATCH 06/15] Added links. --- README.md | 2 +- src/README.md | 37 +++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index abfeda3..3763ab4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This book is about writing **Smart Contracts** using [Sylvia](https://github.com/CosmWasm/sylvia) framework. To learn about [CosmWasm](https://github.com/CosmWasm), -on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com/index.html). +on which Sylvia relies, please check [The CosmWasm Book](https://book.cosmwasm.com). ## About diff --git a/src/README.md b/src/README.md index 8b4a61a..64fece4 100644 --- a/src/README.md +++ b/src/README.md @@ -1,29 +1,29 @@ # Introduction -This book is a guide for creating CosmWasm smart contracts with the Sylvia framework. -It will lead you step by step and explain relevant topics from easiest to trickiest. +This book is a guide for creating [CosmWasm](https://github.com/CosmWasm) **smart contracts** +using [Sylvia](https://github.com/CosmWasm/sylvia) framework. +It will guide you step by step, explaining relevant topics from the easiest to the trickiest ones. The idea of the book is not only to tell you about smart contract development but also to show you how to do it clean and maintainable. I will show you some good practices -for using `sylvia`. +for using [Sylvia](https://github.com/CosmWasm/sylvia). -This book is not meant to teach you about the `CosmWasm`. To learn about that, I recommend reading -[the cosmwasm-book](https://book.cosmwasm.com/). +This book is not meant to teach you about the [CosmWasm](https://github.com/CosmWasm). +To learn about that, read [The CosmWasm Book](https://book.cosmwasm.com). -This book covers `sylvia` in version 0.7.0. +This book covers [Sylvia](https://github.com/CosmWasm/sylvia) in version 0.7.0. -## Prerequirements +## Prerequisites -This book explores CosmWasm smart contracts. It is not a Rust tutorial, and it -assumes basic Rust knowledge. As you will probably learn it alongside this -book, I recommend first grasping the language. You can find -great resources to start with Rust on [Learn -Rust](https://www.rust-lang.org/learn) page. +This book explores [CosmWasm](https://github.com/CosmWasm) **smart contracts**. +It is not intended to be a Rust tutorial, and it assumes a basic Rust knowledge. +As you will probably learn it alongside this book, I recommend first grasping the language. +You can find great resources to start with Rust on [Learn Rust](https://www.rust-lang.org/learn) page. ## CosmWasm API documentation -This is the guide-like documentation. If you are looking for the API -documentation, you may be interested in checking one of the following: +This is the guide-like documentation. If you are looking for the API documentation, +you may be interested in checking one of the following: - [cosmwasm-std](https://crates.io/crates/cosmwasm-std) - [cw-storage-plus](https://crates.io/crates/cw-storage-plus) @@ -33,10 +33,11 @@ documentation, you may be interested in checking one of the following: ## Contributing to the book -This book is maintained on [Github](https://github.com/CosmWasm/sylvia-book) and auto -deployed from there. Please create an -[issue](https://github.com/CosmWasm/sylvia-book/issues) or pull request if you find -any mistakes, bugs, or ambiguities. +This book is maintained on [GitHub](https://github.com/CosmWasm/sylvia-book) +and auto deployed from there. +Please create an [issue](https://github.com/CosmWasm/sylvia-book/issues) +or pull request if you find any mistakes, bugs, or ambiguities. ## Warning + This book is still under construction, so be aware that, in some places, it might feel disjointed. From 1675c49b16f6a707ea338d4de56ee28e25daf0a7 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 16:32:14 +0200 Subject: [PATCH 07/15] Minor corrections. --- src/setting-up-env.md | 59 +++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/src/setting-up-env.md b/src/setting-up-env.md index ccda68f..42213be 100644 --- a/src/setting-up-env.md +++ b/src/setting-up-env.md @@ -1,16 +1,16 @@ # Setting up the environment -To work with CosmWasm smart contract, you will need rust installed on your -machine. If you don't have one, you can find installation instructions on [the -Rust website](https://www.rust-lang.org/tools/install). +To work with CosmWasm smart contract, you will need Rust installed on your machine. +If you don't have one, you can find installation instructions on +[the Rust website](https://www.rust-lang.org/tools/install). I assume you are working with a stable Rust channel in this book. -Additionally, you will need the Wasm rust compiler backend installed to build +Additionally, you will need the **Wasm** Rust compiler backend installed to build Wasm binaries. To install it, run the following: -``` -rustup target add wasm32-unknown-unknown +```shell +$ rustup target add wasm32-unknown-unknown ``` ## Check contract utility @@ -19,15 +19,15 @@ An additional helpful tool for building smart contracts is the `cosmwasm-check` utility. It allows you to check if the wasm binary is a proper smart contract ready to upload into the blockchain. You can install it using cargo: -``` +```shell $ cargo install cosmwasm-check ``` If the installation succeeds, you can execute the utility from your command line. -``` +```shell $ cosmwasm-check --version -Contract checking 1.3.1 +Contract checking 1.4.1 ``` ## Verifying the installation @@ -36,33 +36,34 @@ To guarantee you are ready to build your smart contracts, you must ensure you ca Checkout the [sylvia](https://github.com/CosmWasm/sylvia) repository and run the testing command in its folder: -``` -$ git clone git@github.com:CosmWasm/sylvia.git -$ cd ./sylvia -sylvia $ cargo test +```shell +$ git clone https://github.com/CosmWasm/sylvia.git +$ cd sylvia +[sylvia]$ cargo test ``` You should see that everything in the repository gets compiled and all tests pass. -`sylvia` framework contains some examples of contracts. To find them go to `examples/contracts` -directory. These contracts are maintained by CosmWasm creators, so contracts in there should follow +[Sylvia](https://github.com/CosmWasm/sylvia) framework contains some examples of contracts. +To find them go to `examples/contracts` directory. +These contracts are maintained by CosmWasm creators, so contracts in there should follow good practices. -To verify the `cosmwasm-check` utility, first, you need to build a smart contract. Go to some -contract directory, for example, `examples/contracts/cw1-whitelist`, and call `cargo wasm`: +To verify contract using the `cosmwasm-check` utility, first you need to build a smart contract. +Go to some contract directory, for example, `examples/contracts/cw1-whitelist`, and run the following commands: -``` -sylvia $ cd examples/contracts/cw1-whitelist -sylvia/examples/contracts/cw1-whitelist $ cargo wasm +```shell +[sylvia]$ cd examples/contracts/cw1-whitelist +[sylvia/examples/contracts/cw1-whitelist]$ cargo wasm ``` -`wasm` is an alias for `"build --release --target wasm32-unknown-unknown --lib"`. +`wasm` is a cargo alias for `build --release --target wasm32-unknown-unknown --lib`. You should be able to find your output binary in the `examples/target/wasm32-unknown-unknown/release/` -of the root repo directory - not in the contract directory itself! Now you can check if contract -validation passes: +of the root repo directory, not in the contract directory itself! +Now you can check if contract validation passes: -``` -sylvia $ cosmwasm-check examples/target/wasm32-unknown-unknown/release/cw1_whitelist.wasm +```shell +[sylvia]$ cosmwasm-check examples/target/wasm32-unknown-unknown/release/cw1_whitelist.wasm Available capabilities: {"cosmwasm_1_2", "cosmwasm_1_3", "staking", "iterator", "stargate", "cosmwasm_1_1"} @@ -77,5 +78,9 @@ Sylvia generates a lot of code for us, which is not visible in the code. To see with it, go to `examples/contracts/cw1-whitelist/src/contract.rs`. In VSCode you can click on `#[contract]`, do `shift+p` and then type: `rust analyzer: Expand macro recursively`. This will open a window with a fully expanded macro, which you can browse. In Vim you can consider installing -the [`rust-tools`](https://github.com/simrat39/rust-tools.nvim) plugin. You can also use -`cargo expand` tool from CLI for this. +the [rust-tools](https://github.com/simrat39/rust-tools.nvim) plugin. +You can also use `cargo expand` tool from CLI, like this: + +```shell +[sylvia/examples/contracts/cw1-whitelist]$ cargo expand --lib +``` From 0964c6fbbd242d6a57b5ae7cd118c91bd3410ccf Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 16:34:46 +0200 Subject: [PATCH 08/15] Added link. --- src/basics.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/basics.md b/src/basics.md index 2bfba7a..f990964 100644 --- a/src/basics.md +++ b/src/basics.md @@ -1,4 +1,5 @@ # Basics -This chapter will go through creating basic smart contract step by step. -I will explain the core features of `sylvia` and some good practices. +This chapter will guide you through creating basic smart contract, step by step. +I will explain the core features of [Sylvia](https://github.com/CosmWasm/sylvia) +framework and some good practices. From b78541cfd00b53b4526c7b0dd1b6fea249d313c3 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 16:45:49 +0200 Subject: [PATCH 09/15] Style corrections. --- src/basics/create-project.md | 40 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/basics/create-project.md b/src/basics/create-project.md index bda583b..b931fdc 100644 --- a/src/basics/create-project.md +++ b/src/basics/create-project.md @@ -1,13 +1,13 @@ # Create a Rust project -As smart contracts are Rust library crates, we will start with creating one: +Smart contracts are Rust library crates. We will start with creating one: -``` +```shell $ cargo new --lib ./contract ``` -You created a simple Rust library, but it is not yet ready to be a smart contract. The first thing -to do is to update the `Cargo.toml` file: +You created a simple Rust library, but it is not yet ready to be a smart contract. +The first thing to do is to update the `Cargo.toml` file: ```toml [package] @@ -26,26 +26,28 @@ cosmwasm-schema = "1.3.1" serde = "1.0.180" ``` -As you can see, I added a `crate-type` field for the library section. Generating the -[`cdylib`](https://doc.rust-lang.org/reference/linkage.html) is -required to create a proper web assembly binary. The downside of this is that such a library cannot -be used as a dependency for other Rust crates - for now, it is not needed, but later we will show +As you can see, I added a `crate-type` field for the library section. +Generating the [`cdylib`](https://doc.rust-lang.org/reference/linkage.html) is +required to create a proper web assembly binary. +The downside of this is that such a library cannot be used as a dependency +for other Rust crates - for now, it is not needed, but later we will show how to approach reusing contracts as dependencies. Additionally, we added some core dependencies for smart contracts: -- [`cosmwasm-std`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/). This crate is a +- [`cosmwasm-std`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/) - Crate that is a standard library for smart contracts. It provides essential utilities for communication with the outside world, helper functions, and types. Every smart contract we will build will use this dependency. -- [`sylvia`](https://docs.rs/sylvia/0.7.0/sylvia/) - the crate we will learn in this -book. It provides us with three procedural macros: `entry_points`, `contract` and `interface`. I -will expand on them later in the book. -- [`schemars`](https://docs.rs/schemars/0.8.12/schemars/index.html) - crate used to create JSON -schema documents for our contracts. It is automatically derived on types -generated by `sylvia` and will be later used to provide nice API blockchain users who might not be -rust devs. -- [`cosmwasm-schema`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/) - similiar -to schemars. This crate expands on `schemars` and provides us with trait +- [`sylvia`](https://docs.rs/sylvia/0.7.0/sylvia/) - Crate, we will learn in this +book. It provides us with three procedural macros: `entry_points`, `contract` and `interface`. +I will expand on them later in the book. +- [`schemars`](https://docs.rs/schemars/0.8.12/schemars/index.html) - Crate used to create JSON +schema documents for our contracts. It is automatically derived on types generated by +[sylvia](https://github.com/CosmWasm/sylvia) and will be later used to provide concise API +for blockchain users, who might not be Rust developers. +- [`cosmwasm-schema`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/) - Similar to `schemars`. +This crate expands on `schemars` and provides us with trait [`QueryResponses`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/trait.QueryResponses.html) which ties query variants to their responses. I will expand on that later in the book. -- [`serde`](https://docs.rs/serde/1.0.180/serde/) - +- [`serde`](https://docs.rs/serde/1.0.180/serde/) - Framework for serializing and deserializing +Rust data structures efficiently and generically. From c84683adacdd53beae21ce98ce45cf2ac1f45d3c Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 17:00:26 +0200 Subject: [PATCH 10/15] Bolded that now this contact is not ready yet. --- src/basics/first-messages.md | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/basics/first-messages.md b/src/basics/first-messages.md index a08f154..a4b58c2 100644 --- a/src/basics/first-messages.md +++ b/src/basics/first-messages.md @@ -38,16 +38,19 @@ impl CounterContract { } ``` -So what is going on here? First, we define the CounterContract struct. It is empty right now but +So what is going on here? + +First, we define the CounterContract struct. It is empty right now but later when we learn about states, we will use its fields to store them. We mark the `impl` block with [`contract`](https://docs.rs/sylvia/0.7.0/sylvia/attr.contract.html) attribute macro. It will parse every method inside the `impl` block marked with the `[msg(...)]` attribute and create proper messages and utilities like `multitest helpers` for them. More on them later. -`CosmWasm` contract requires only the `instantiate` `entry_point`, and it is mandatory to specify -it for the `contract` macro. We have to provide it with the proper context type +[CosmWasm](https://github.com/CosmWasm) contract requires only the `instantiate` entry point, +and it is mandatory to specify it for the `contract` macro. We have to provide it with the proper context type [`InstantiateCtx`](https://docs.rs/sylvia/0.7.0/sylvia/types/struct.InstantiateCtx.html). + Context gives us access to the blockchain state, information about our contract, and the sender of the message. We return the [`StdResult`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/type.StdResult.html) which uses standard `CosmWasm` error @@ -55,16 +58,27 @@ which uses standard `CosmWasm` error It's generic over [`Response`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/struct.Response.html). For now, we will return the `default` value of it. -I recommend expanding the macro now and seeing what `sylvia` generates. It might be overwhelming -as there will be a lot of things generated that seem not relevant to our code, so for the bare -minimum check the `InstantiateMsg` and its impl block. +I recommend expanding the macro now and seeing what [Sylvia](https://github.com/CosmWasm/sylvia) generates. +It might be overwhelming, as there will be a lot of things generated that seem not relevant to our code, +so for the bare minimum check the `InstantiateMsg` and its `impl` block. ## Next step -If we will build our contract with `cargo build --release --target wasm32-unknown-unknown --lib` -and run the `cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm`, it will fail with +If we build our contract with command: + +```shell +$ cargo build --release --target wasm32-unknown-unknown --lib +``` + +and the run: + +```shell +$ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm ``` -contract & cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm + +it will **fail**: + +```shell Available capabilities: {"cosmwasm_1_2", "iterator", "staking", "stargate", "cosmwasm_1_1", "cosmwasm_1_3"} target/wasm32-unknown-unknown/release/contract.wasm: failure @@ -73,5 +87,5 @@ Error during static Wasm validation: Wasm contract doesn't have required export: Passes: 0, failures: 1 ``` -This is because our contract is not yet complete. We defined the message that could be sent to it but -didn't provide any `entry_point`. In the next chapter, we will finally make it the proper contract. +This is because our contract is **not yet complete**. We defined the message that could be sent to it but +didn't provide any `entry_point`. In the next chapter, we will finally make it a proper contract. From 9258b22e20091391d951d8edee0ce2241db36596 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Wed, 18 Oct 2023 17:02:43 +0200 Subject: [PATCH 11/15] Bolded more. --- src/basics/first-messages.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/basics/first-messages.md b/src/basics/first-messages.md index a4b58c2..5786131 100644 --- a/src/basics/first-messages.md +++ b/src/basics/first-messages.md @@ -70,13 +70,13 @@ If we build our contract with command: $ cargo build --release --target wasm32-unknown-unknown --lib ``` -and the run: +and then run: ```shell $ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm ``` -it will **fail**: +**IT WILL FAIL** with message: ```shell Available capabilities: {"cosmwasm_1_2", "iterator", "staking", "stargate", "cosmwasm_1_1", "cosmwasm_1_3"} @@ -87,5 +87,5 @@ Error during static Wasm validation: Wasm contract doesn't have required export: Passes: 0, failures: 1 ``` -This is because our contract is **not yet complete**. We defined the message that could be sent to it but +This is because our contract **IS NOT YET COMPLETE**. We defined the message that could be sent to it but didn't provide any `entry_point`. In the next chapter, we will finally make it a proper contract. From d30fad4629737e6c9a568d8d4244a02cecbf86f6 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Thu, 19 Oct 2023 12:18:01 +0200 Subject: [PATCH 12/15] Minro changes, fixed code highlighting. --- src/basics/entry-points.md | 46 ++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/basics/entry-points.md b/src/basics/entry-points.md index 0f03a44..7b9cdad 100644 --- a/src/basics/entry-points.md +++ b/src/basics/entry-points.md @@ -2,28 +2,29 @@ Typical Rust application starts with the `fn main()` function called by the operating system. Smart contracts are not significantly different. When the message is sent to the contract, a -function called "entry point" is called. Unlike native applications, which have only a single -`main` entry point, smart contracts have a couple corresponding to different message types: -`instantiate`, `execute`, `query`, `sudo`, `migrate` and more. +function called "entry point" is executed. Unlike native applications, which have only a single +`main` entry point, smart contracts have a couple of them, each corresponding to different +message type: `instantiate`, `execute`, `query`, `sudo`, `migrate` and more. To start, we will go with three basic entry points: -- `instantiate` is called once per smart contract lifetime - you can think about it as +- **`instantiate`** is called once per smart contract lifetime; you can think about it as a constructor or initializer of a contract. -- `execute` for handling messages which can modify contract state - they are used to +- **`execute`** for handling messages which can modify contract state; they are used to perform some actual actions. -- `query` for handling messages requesting some information from a contract; unlike `execute`, - they can never affect any contract state, and are used just like database queries. +- **`query`** for handling messages requesting some information from a contract; unlike **`execute`**, + they can never alter any contract state, and are used in a similar manner to database queries. ## Generate entry points -`Sylvia` provides us with [`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html) -attribute macro. In most cases, your entry point will just dispatch received messages to the handler, +[Sylvia](https://github.com/CosmWasm/sylvia) provides an attribute macro named +**[`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html)**. +In most cases, your entry point will just dispatch received messages to the handler, so it's not necessary to manually create them, and we can rely on a macro to do that for us. -Let's add the attribute macro to our contract: +Let's add the **`entry_points`** attribute macro to our contract: -``` +```rust,noplayground use cosmwasm_std::{Response, StdResult}; use sylvia::types::InstantiateCtx; use sylvia::{contract, entry_points}; @@ -44,25 +45,26 @@ impl CounterContract { } ``` -Note that `#[entry_points]` is added above the `#[contract]`. This is because `contract` removes -the attributes such as `#[msg(...)]` on which both those macros rely. Remember to always place -`#[entry_points]` first. +Note that **`#[entry_points]`** is added above the **`#[contract]`**. +It is because **`#[contract]`** removes attributes like **`#[msg(...)]`** on which both these macros rely. + +Always remember to place **`#[entry_points]`** first. -`Sylvia` generates the entry_points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) -attribute macro. Its purpose is to wrap the whole entry point to the form Wasm runtime understands. +[Sylvia](https://github.com/CosmWasm/sylvia) generates entry points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) +attribute macro. Its purpose is to wrap the whole entry point to the form the Wasm runtime understands. The proper Wasm entry points can use only basic types supported natively by Wasm specification, and Rust structures and enums are not in this set. Working with such entry points would be overcomplicated, so CosmWasm creators delivered the `entry_point` macro. It creates the raw Wasm entry point, calling the decorated function internally and doing all the magic required to build our high-level Rust arguments from arguments passed by Wasm runtime. -Now that our contract has a proper `entry point` let's build it and check if it's properly defined. +Now, when our contract has a proper entry point, let's build it and check if it's correctly defined: -``` -contract $ cargo build --release --target wasm32-unknown-unknown --lib +```shell +[contract]$ cargo build --release --target wasm32-unknown-unknown --lib Finished release [optimized] target(s) in 0.03s -contract $ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm +[contract]$ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm Available capabilities: {"stargate", "cosmwasm_1_3", "cosmwasm_1_1", "cosmwasm_1_2", "staking", "iterator"} target/wasm32-unknown-unknown/release/contract.wasm: pass @@ -72,5 +74,5 @@ All contracts (1) passed checks! ## Next step -Nice! We have a proper `CosmWasm` contract. Now let's add some state to it so it will actually be -able to do something. +Well done! We have now a proper [CosmWasm](https://github.com/CosmWasm) contract. +Let's add some state to it, so it will actually be able to do something. From b9cea2616d583d3bf0a659de1912a760e7e59bd1 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Thu, 19 Oct 2023 12:33:40 +0200 Subject: [PATCH 13/15] Updates. --- src/basics/building-contract.md | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/basics/building-contract.md b/src/basics/building-contract.md index 7db6213..724b78b 100644 --- a/src/basics/building-contract.md +++ b/src/basics/building-contract.md @@ -1,17 +1,17 @@ # Building the contract -Now that our contract correctly compiles into wasm, let's digest our build command. +Now that our contract correctly compiles into Wasm, let's digest our build command. -``` +```shell $ cargo build --target wasm32-unknown-unknown --release --lib ``` -The `--target` argument tells cargo to perform cross-compilation for a given target instead of -building a native binary for an OS, it is running on - in this case, `wasm32-unknown-unknown`, +The `--target` argument tells cargo to perform cross-compilation for a given target, instead of +building a native binary for an OS it is running on. In this case the target is `wasm32-unknown-unknown`, which is a fancy name for Wasm target. -Contract would be properly created without `--lib`, but later, when we add `query`, it will be -needed so adding this argument from the beginning is a good idea. +Our contract would be also properly compiled without `--lib` flag, but later, when we add `query`, +this flag will be required, so using it from the beginning is a good habit. Additionally, I passed the `--release` argument to the command - it is not required, but in most cases, debug information is not very useful while running @@ -19,15 +19,15 @@ on-chain. It is crucial to reduce the uploaded binary size for gas cost minimization. It is worth knowing that there is a [CosmWasm Rust Optimizer](https://github.com/CosmWasm/rust-optimizer) tool that takes care of building even smaller binaries. For production, all the contracts should be compiled using this -tool, but it is not an essential thing to do for learning purposes. +tool, but it is now not essential for learning purposes. ## Aliasing build command Now I see you are disappointed in building your contracts with some overcomplicated command instead of simple `cargo build`. Hopefully, it is not the case. The common practice is to alias -the building command to make it as simple as building a native app. +the building command, to make it as simple as building a native application. -Let's create the `.cargo/config` file in your contract project directory with the following content: +Let's create `.cargo/config` file in your contract project directory with the following content: ```toml [alias] @@ -35,17 +35,21 @@ wasm = "build --target wasm32-unknown-unknown --release --lib" wasm-debug = "build --target wasm32-unknown-unknown --lib" ``` -Building your Wasm binary is as easy as executing `cargo wasm`. We also added the additional -`wasm-debug` command for rare cases when we want to build the wasm binary, including debug information. +Building your Wasm binary is now as easy as executing `cargo wasm`. We also added the additional +`wasm-debug` command for rare cases, when we want to build the Wasm binary with debug information included. ## Checking contract validity -When the contract is built, the last step is to ensure it is a valid CosmWasm contract is to call -`cosmwasm-check` on it: +When the contract is built, the last step to ensure that it is a valid [CosmWasm](https://github.com/CosmWasm) +contract, is to call `cosmwasm-check` on it: -``` +```shell $ cargo wasm -... + . + . (compilation messages) + . + Finished release [optimized] target(s) in 0.03s + $ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm Available capabilities: {"cosmwasm_1_1", "iterator", "staking", "stargate"} From 48e689db279ed40122248bae9fbb096df8fc57d9 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Thu, 19 Oct 2023 13:01:28 +0200 Subject: [PATCH 14/15] Minor updates. --- src/basics/state.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/basics/state.md b/src/basics/state.md index 212366a..c68d839 100644 --- a/src/basics/state.md +++ b/src/basics/state.md @@ -1,17 +1,17 @@ # Contract state We can instantiate our contract, but it doesn't do anything afterward. -Let's make it more complex. In this chapter, we will introduce the contracts state. +Let's make it more usable. In this chapter, we will introduce the contract's state. ## Adding contract state The name of our contract is a little spoiler. We will add the `counter` state. It's not a real world -usage of smart contracts, but it allows us to see the usage of `sylvia` without getting into -business logic. +usage of smart contracts, but it helps to see the usage of [Sylvia](https://github.com/CosmWasm/sylvia) +without getting into business logic. -The first thing to do is to update `Cargo.toml` with yet another dependency - the +The first thing to do, is to update `Cargo.toml` with yet another dependency - the [`storage-plus`](https://crates.io/crates/cw-storage-plus) crate with high-level bindings for -CosmWasm smart contracts state management: +[CosmWasm](https://github.com/CosmWasm) smart contracts state management: ```toml [package] @@ -31,7 +31,7 @@ serde = "1.0.180" cw-storage-plus = "1.1.0" ``` -Now add the state as a field in your contract and instantiate it in the `new` method. +Now add state as a field in your contract and instantiate it in the `new` function (constructor): ```rust,noplayground use cosmwasm_std::{Response, StdResult}; @@ -62,17 +62,18 @@ impl CounterContract { New type: - [`Item<_>`](https://docs.rs/cw-storage-plus/1.1.0/cw_storage_plus/struct.Item.html) - this is -just an accessor allowing us to read a state stored on the blockchain via the key "count" in our -case. It doesn't store the state by itself. +just an **accessor** that allows to read a state stored on the blockchain via the key **"count"** +in our case. It doesn't hold any state by itself. -In CosmWasm, the blockchain state is just massive key-value storage. The keys are prefixed with -metainformation pointing to the contract which owns them (so no other contract can alter them), -but even after removing the prefixes, the single contract state is a smaller key-value pair. +In [CosmWasm](https://github.com/CosmWasm), the blockchain state is just a massive key-value storage. +The keys are prefixed with metainformation, pointing to the contract which owns them +(so no other contract can alter them), but even after removing the prefixes, +the single contract state is a smaller key-value pair. ## Initializing the state -Now that the state field has been added, we can improve our instantiate. We will make it possible for -a user to add new admins at contract instantiation. +Now that the state field has been added, we can improve the instantiation of our contract. +We make it possible for a user to add an initial counter value at contract instantiation. ```rust,noplayground use cosmwasm_std::{Response, StdResult}; @@ -105,8 +106,9 @@ Having data to store, we use the [`save`](https://docs.rs/cw-storage-plus/1.1.0/cw_storage_plus/struct.Item.html#method.save) function to write it into the contract state. Note that the first argument of `save` is [`&mut Storage`](https://docs.rs/cosmwasm-std/1.1.0/cosmwasm_std/trait.Storage.html), which is -actual blockchain storage. As emphasized, the `Item` object stores nothing and is an accessor. -It determines how to store the data in the storage given to it. +actual blockchain storage. As emphasized, the `Item` object holds no state by itself, +and is just an accessor to blockchain's storage. `Item` only determines how to store +the data in the storage given to it. Now let's expand the `contract` macro and see what changed. @@ -136,11 +138,12 @@ impl InstantiateMsg { ``` First, adding parameter to the `instantiate` method added it as a field to the `InstantiateMsg`. -It also caused `dispatch` to pass this field to the `instantiate` method. Thanks to sylvia we don't -have to tweak every function, entry point or message and are actions are limited only to modifying -the method. +It also caused `dispatch` to pass this field to the `instantiate` method. +Thanks to [Sylvia](https://github.com/CosmWasm/sylvia) we don't have to tweak every function, +entry point or message, and all we need to do, is just to modify the `instantiate` function. ## Next step -Nice, we now have the state initialized on our contract, but we can't validate if the data is -stored correctly. Let's change it in the next chapter, in which we will introduce `query`. +Well, now we have the state initialized for our contract, but we still can't validate, +if the data we passed during instantiation is stored correctly. +Let's add it in the next chapter, in which we introduce **`query`**. From b14271706f6c87250e1f78e6e53fa98db87ee212 Mon Sep 17 00:00:00 2001 From: Dariusz Depta Date: Tue, 31 Oct 2023 10:48:16 +0100 Subject: [PATCH 15/15] Changes after review. --- src/README.md | 13 ++++++------- src/basics.md | 3 +-- src/basics/building-contract.md | 4 ++-- src/basics/create-project.md | 3 +-- src/basics/entry-points.md | 11 +++++------ src/basics/first-messages.md | 14 ++++++-------- src/basics/state.md | 18 ++++++++---------- src/setting-up-env.md | 15 +++++++-------- 8 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/README.md b/src/README.md index 64fece4..1b6a298 100644 --- a/src/README.md +++ b/src/README.md @@ -1,21 +1,20 @@ # Introduction -This book is a guide for creating [CosmWasm](https://github.com/CosmWasm) **smart contracts** -using [Sylvia](https://github.com/CosmWasm/sylvia) framework. -It will guide you step by step, explaining relevant topics from the easiest to the trickiest ones. +This book is a guide for creating CosmWasm smart contracts with the Sylvia framework. +It will lead you step by step and explain relevant topics from easiest to trickiest. The idea of the book is not only to tell you about smart contract development but also to show you how to do it clean and maintainable. I will show you some good practices -for using [Sylvia](https://github.com/CosmWasm/sylvia). +for using `Sylvia`. -This book is not meant to teach you about the [CosmWasm](https://github.com/CosmWasm). +This book is not meant to teach you about the `CosmWasm`. To learn about that, read [The CosmWasm Book](https://book.cosmwasm.com). -This book covers [Sylvia](https://github.com/CosmWasm/sylvia) in version 0.7.0. +This book covers `Sylvia` in version 0.7.0. ## Prerequisites -This book explores [CosmWasm](https://github.com/CosmWasm) **smart contracts**. +This book explores CosmWasm smart contracts. It is not intended to be a Rust tutorial, and it assumes a basic Rust knowledge. As you will probably learn it alongside this book, I recommend first grasping the language. You can find great resources to start with Rust on [Learn Rust](https://www.rust-lang.org/learn) page. diff --git a/src/basics.md b/src/basics.md index f990964..6a1caff 100644 --- a/src/basics.md +++ b/src/basics.md @@ -1,5 +1,4 @@ # Basics This chapter will guide you through creating basic smart contract, step by step. -I will explain the core features of [Sylvia](https://github.com/CosmWasm/sylvia) -framework and some good practices. +I will explain the core features of `Sylvia` framework and some good practices. diff --git a/src/basics/building-contract.md b/src/basics/building-contract.md index 724b78b..6e9acd1 100644 --- a/src/basics/building-contract.md +++ b/src/basics/building-contract.md @@ -40,8 +40,8 @@ Building your Wasm binary is now as easy as executing `cargo wasm`. We also adde ## Checking contract validity -When the contract is built, the last step to ensure that it is a valid [CosmWasm](https://github.com/CosmWasm) -contract, is to call `cosmwasm-check` on it: +When the contract is built, the last step to ensure that it is a valid CosmWasm contract +is to call `cosmwasm-check` on it: ```shell $ cargo wasm diff --git a/src/basics/create-project.md b/src/basics/create-project.md index b931fdc..2e9e97f 100644 --- a/src/basics/create-project.md +++ b/src/basics/create-project.md @@ -43,8 +43,7 @@ book. It provides us with three procedural macros: `entry_points`, `contract` an I will expand on them later in the book. - [`schemars`](https://docs.rs/schemars/0.8.12/schemars/index.html) - Crate used to create JSON schema documents for our contracts. It is automatically derived on types generated by -[sylvia](https://github.com/CosmWasm/sylvia) and will be later used to provide concise API -for blockchain users, who might not be Rust developers. +`sylvia` and will be later used to provide concise API for blockchain users, who might not be Rust developers. - [`cosmwasm-schema`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/) - Similar to `schemars`. This crate expands on `schemars` and provides us with trait [`QueryResponses`](https://docs.rs/cosmwasm-schema/1.3.1/cosmwasm_schema/trait.QueryResponses.html) diff --git a/src/basics/entry-points.md b/src/basics/entry-points.md index 7b9cdad..b15724c 100644 --- a/src/basics/entry-points.md +++ b/src/basics/entry-points.md @@ -17,8 +17,7 @@ To start, we will go with three basic entry points: ## Generate entry points -[Sylvia](https://github.com/CosmWasm/sylvia) provides an attribute macro named -**[`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html)**. +`Sylvia` provides an attribute macro named [`entry_points`](https://docs.rs/sylvia/0.7.0/sylvia/attr.entry_points.html). In most cases, your entry point will just dispatch received messages to the handler, so it's not necessary to manually create them, and we can rely on a macro to do that for us. @@ -50,7 +49,7 @@ It is because **`#[contract]`** removes attributes like **`#[msg(...)]`** on whi Always remember to place **`#[entry_points]`** first. -[Sylvia](https://github.com/CosmWasm/sylvia) generates entry points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) +`Sylvia` generates entry points with [`#[entry_point]`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/attr.entry_point.html) attribute macro. Its purpose is to wrap the whole entry point to the form the Wasm runtime understands. The proper Wasm entry points can use only basic types supported natively by Wasm specification, and Rust structures and enums are not in this set. Working with such entry points would be @@ -61,10 +60,10 @@ high-level Rust arguments from arguments passed by Wasm runtime. Now, when our contract has a proper entry point, let's build it and check if it's correctly defined: ```shell -[contract]$ cargo build --release --target wasm32-unknown-unknown --lib +contract $ cargo build --release --target wasm32-unknown-unknown --lib Finished release [optimized] target(s) in 0.03s -[contract]$ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm +contract $ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm Available capabilities: {"stargate", "cosmwasm_1_3", "cosmwasm_1_1", "cosmwasm_1_2", "staking", "iterator"} target/wasm32-unknown-unknown/release/contract.wasm: pass @@ -74,5 +73,5 @@ All contracts (1) passed checks! ## Next step -Well done! We have now a proper [CosmWasm](https://github.com/CosmWasm) contract. +Well done! We have now a proper `CosmWasm` contract. Let's add some state to it, so it will actually be able to do something. diff --git a/src/basics/first-messages.md b/src/basics/first-messages.md index 5786131..5b2bc4f 100644 --- a/src/basics/first-messages.md +++ b/src/basics/first-messages.md @@ -38,17 +38,15 @@ impl CounterContract { } ``` -So what is going on here? - -First, we define the CounterContract struct. It is empty right now but +So what is going on here? First, we define the CounterContract struct. It is empty right now but later when we learn about states, we will use its fields to store them. We mark the `impl` block with [`contract`](https://docs.rs/sylvia/0.7.0/sylvia/attr.contract.html) attribute macro. It will parse every method inside the `impl` block marked with the `[msg(...)]` attribute and create proper messages and utilities like `multitest helpers` for them. More on them later. -[CosmWasm](https://github.com/CosmWasm) contract requires only the `instantiate` entry point, -and it is mandatory to specify it for the `contract` macro. We have to provide it with the proper context type +`CosmWasm` contract requires only the `instantiate` entry point, and it is mandatory to specify +it for the `contract` macro. We have to provide it with the proper context type [`InstantiateCtx`](https://docs.rs/sylvia/0.7.0/sylvia/types/struct.InstantiateCtx.html). Context gives us access to the blockchain state, information about our contract, and the sender of the @@ -58,7 +56,7 @@ which uses standard `CosmWasm` error It's generic over [`Response`](https://docs.rs/cosmwasm-std/1.3.1/cosmwasm_std/struct.Response.html). For now, we will return the `default` value of it. -I recommend expanding the macro now and seeing what [Sylvia](https://github.com/CosmWasm/sylvia) generates. +I recommend expanding the macro now and seeing what `Sylvia` generates. It might be overwhelming, as there will be a lot of things generated that seem not relevant to our code, so for the bare minimum check the `InstantiateMsg` and its `impl` block. @@ -67,13 +65,13 @@ so for the bare minimum check the `InstantiateMsg` and its `impl` block. If we build our contract with command: ```shell -$ cargo build --release --target wasm32-unknown-unknown --lib +contract $ cargo build --release --target wasm32-unknown-unknown --lib ``` and then run: ```shell -$ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm +contract $ cosmwasm-check target/wasm32-unknown-unknown/release/contract.wasm ``` **IT WILL FAIL** with message: diff --git a/src/basics/state.md b/src/basics/state.md index c68d839..4b8eb65 100644 --- a/src/basics/state.md +++ b/src/basics/state.md @@ -6,12 +6,11 @@ Let's make it more usable. In this chapter, we will introduce the contract's sta ## Adding contract state The name of our contract is a little spoiler. We will add the `counter` state. It's not a real world -usage of smart contracts, but it helps to see the usage of [Sylvia](https://github.com/CosmWasm/sylvia) -without getting into business logic. +usage of smart contracts, but it helps to see the usage of `Sylvia` without getting into business logic. The first thing to do, is to update `Cargo.toml` with yet another dependency - the [`storage-plus`](https://crates.io/crates/cw-storage-plus) crate with high-level bindings for -[CosmWasm](https://github.com/CosmWasm) smart contracts state management: +CosmWasm smart contracts state management: ```toml [package] @@ -65,10 +64,9 @@ New type: just an **accessor** that allows to read a state stored on the blockchain via the key **"count"** in our case. It doesn't hold any state by itself. -In [CosmWasm](https://github.com/CosmWasm), the blockchain state is just a massive key-value storage. -The keys are prefixed with metainformation, pointing to the contract which owns them -(so no other contract can alter them), but even after removing the prefixes, -the single contract state is a smaller key-value pair. +In CosmWasm, the blockchain state is just a massive key-value storage. The keys are prefixed with +metainformation, pointing to the contract which owns them (so no other contract can alter them), +but even after removing the prefixes, the single contract state is a smaller key-value pair. ## Initializing the state @@ -138,9 +136,9 @@ impl InstantiateMsg { ``` First, adding parameter to the `instantiate` method added it as a field to the `InstantiateMsg`. -It also caused `dispatch` to pass this field to the `instantiate` method. -Thanks to [Sylvia](https://github.com/CosmWasm/sylvia) we don't have to tweak every function, -entry point or message, and all we need to do, is just to modify the `instantiate` function. +It also caused `dispatch` to pass this field to the `instantiate` method. Thanks to Sylvia we don't +have to tweak every function, entry point or message, and all we need to do, is just to modify +the `instantiate` function. ## Next step diff --git a/src/setting-up-env.md b/src/setting-up-env.md index 42213be..0925579 100644 --- a/src/setting-up-env.md +++ b/src/setting-up-env.md @@ -39,22 +39,21 @@ its folder: ```shell $ git clone https://github.com/CosmWasm/sylvia.git $ cd sylvia -[sylvia]$ cargo test +sylvia $ cargo test ``` You should see that everything in the repository gets compiled and all tests pass. -[Sylvia](https://github.com/CosmWasm/sylvia) framework contains some examples of contracts. -To find them go to `examples/contracts` directory. -These contracts are maintained by CosmWasm creators, so contracts in there should follow +`Sylvia` framework contains some examples of contracts. To find them go to `examples/contracts` +directory. These contracts are maintained by CosmWasm creators, so contracts in there should follow good practices. To verify contract using the `cosmwasm-check` utility, first you need to build a smart contract. Go to some contract directory, for example, `examples/contracts/cw1-whitelist`, and run the following commands: ```shell -[sylvia]$ cd examples/contracts/cw1-whitelist -[sylvia/examples/contracts/cw1-whitelist]$ cargo wasm +sylvia $ cd examples/contracts/cw1-whitelist +sylvia/examples/contracts/cw1-whitelist $ cargo wasm ``` `wasm` is a cargo alias for `build --release --target wasm32-unknown-unknown --lib`. @@ -63,7 +62,7 @@ of the root repo directory, not in the contract directory itself! Now you can check if contract validation passes: ```shell -[sylvia]$ cosmwasm-check examples/target/wasm32-unknown-unknown/release/cw1_whitelist.wasm +sylvia $ cosmwasm-check examples/target/wasm32-unknown-unknown/release/cw1_whitelist.wasm Available capabilities: {"cosmwasm_1_2", "cosmwasm_1_3", "staking", "iterator", "stargate", "cosmwasm_1_1"} @@ -82,5 +81,5 @@ the [rust-tools](https://github.com/simrat39/rust-tools.nvim) plugin. You can also use `cargo expand` tool from CLI, like this: ```shell -[sylvia/examples/contracts/cw1-whitelist]$ cargo expand --lib +sylvia/examples/contracts/cw1-whitelist $ cargo expand --lib ```