From 615d05770bb1654fa4f5cee18666381a076903ca Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Fri, 15 Jul 2022 16:47:52 -0400 Subject: [PATCH 001/248] Create _category_.json --- docs/getting-started/_category_.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/getting-started/_category_.json diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/docs/getting-started/_category_.json @@ -0,0 +1 @@ + From 0aa2ee391834c3672b7a1b79a0443957fd72a465 Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Fri, 15 Jul 2022 16:48:13 -0400 Subject: [PATCH 002/248] Create _category_.json --- docs/tutorials/_category_.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/tutorials/_category_.json diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/docs/tutorials/_category_.json @@ -0,0 +1 @@ + From 438af487de1339313bd18aa5ec734e432204616b Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Fri, 15 Jul 2022 16:50:49 -0400 Subject: [PATCH 003/248] Update _category_.json --- docs/getting-started/_category_.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json index 8b1378917..9d73b581d 100644 --- a/docs/getting-started/_category_.json +++ b/docs/getting-started/_category_.json @@ -1 +1,4 @@ - +{ + "position": 2, + "label": "Getting started" +} From eb12dd11041dcbf08738c8804692e347b036f4f2 Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Fri, 15 Jul 2022 16:51:02 -0400 Subject: [PATCH 004/248] Update _category_.json --- docs/getting-started/_category_.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json index 9d73b581d..1e1cded02 100644 --- a/docs/getting-started/_category_.json +++ b/docs/getting-started/_category_.json @@ -1,4 +1,4 @@ { "position": 2, - "label": "Getting started" + "label": "Getting Started" } From d1c9879cd2acc56f2a26bf323679379fa6fb7da6 Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Fri, 15 Jul 2022 16:51:38 -0400 Subject: [PATCH 005/248] Update _category_.json --- docs/tutorials/_category_.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json index 8b1378917..007228083 100644 --- a/docs/tutorials/_category_.json +++ b/docs/tutorials/_category_.json @@ -1 +1,4 @@ - +{ + "position": 4, + "label": "Tutorials" +} From aea77941b20790d79944b69a6c303b9e8ca9f810 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 28 Jul 2022 18:06:17 -0700 Subject: [PATCH 006/248] Add example contract sections (#20) --- docs/getting-started/install.mdx | 6 ++++++ docs/getting-started/setup.mdx | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 docs/getting-started/install.mdx create mode 100644 docs/getting-started/setup.mdx diff --git a/docs/getting-started/install.mdx b/docs/getting-started/install.mdx new file mode 100644 index 000000000..c25f063d3 --- /dev/null +++ b/docs/getting-started/install.mdx @@ -0,0 +1,6 @@ +--- +sidebar_position: 1 +title: Install Soroban +--- + +TODO THIS PAGE IS INCOMPLETE diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx new file mode 100644 index 000000000..826b95da4 --- /dev/null +++ b/docs/getting-started/setup.mdx @@ -0,0 +1,25 @@ +--- +sidebar_position: 1 +title: Setup +--- + +TODO THIS PAGE IS INCOMPLETE + +Soroban contracts are written in [Rust]. To setup your development environment to develop contracts, you need to: + +1. Install Rust +2. Create a new Rust project +3. Update the project to import the `soroban-sdk` +4. Write a test + +## Install Rust + +``` +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +```sh +$ rustup update +``` + +[Rust]: https://www.rust-lang.org/ From 03dc34cede88f4a2b3247c09b4736434aa26bab8 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 28 Jul 2022 19:58:54 -0700 Subject: [PATCH 007/248] Add some getting started pages (#22) --- .../building-optimized-wasm.mdx | 38 +++++ docs/getting-started/first-project.mdx | 135 ++++++++++++++++++ docs/getting-started/install.mdx | 6 - docs/getting-started/setup.mdx | 27 ++-- 4 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 docs/getting-started/building-optimized-wasm.mdx create mode 100644 docs/getting-started/first-project.mdx delete mode 100644 docs/getting-started/install.mdx diff --git a/docs/getting-started/building-optimized-wasm.mdx b/docs/getting-started/building-optimized-wasm.mdx new file mode 100644 index 000000000..bdcd86cdc --- /dev/null +++ b/docs/getting-started/building-optimized-wasm.mdx @@ -0,0 +1,38 @@ +--- +sidebar_position: 3 +title: Building Optimized WASM +--- + +Building optimized WASM files requires some additional options and commands, and +requires installing the nightly Rust toolchain and `wasm-opt`. + +To install the nightly Rust toolchain use `rustup`. + +```sh +rustup install nightly +``` + +To install `wasm-opt`. + +```sh +TODO: Add instructions for installing wasm-opt. +``` + +Then build your contract using nightly, and the additional options that remove +unnecessary information from the contract. + +```sh +cargo +nightly build \ + --target wasm32-unknown-unknown \ + --release \ + -Z build-std=std,panic_abort \ + -Z build-std-features=panic_immediate_abort +``` + +Then additionally use `wasm-opt` to further minimize the size of the `.wasm`. + +```sh +wasm-opt -Oz \ + target/wasm32-unknown-unknown/release/first-project.wasm \ + -o target/wasm32-unknown-unknown/release/first-project-optimized.wasm +``` diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx new file mode 100644 index 000000000..9e060dbd2 --- /dev/null +++ b/docs/getting-started/first-project.mdx @@ -0,0 +1,135 @@ +--- +sidebar_position: 2 +title: First Project +--- + +Once you've [Setup] your development environment, you're ready to create your +first Soroban contract. + +[Setup]: setup.mdx + +## Create New Project + +Start by creating a new Rust library using the `cargo new` command. + +```sh +cargo new --lib [project-name] +``` + +Open the `Cargo.toml`, it should look something like this: + +```toml +[package] +name = "first-project" +version = "0.1.0" +edition = "2021" +``` + +## Add `soroban-sdk` Dependency + +Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. + +```toml +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] + +[dependencies] +soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } + +[dev_dependencies] +first-project = { path = ".", features = ["testutils"] } + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true +``` + +The features list and dev_dependencies might look a little strange, but we've +said that our contract can be built in three variations: +- By `default` with `export` with contract functions exported and available to +be called. +- Optionally without `export` enabled, contract functions not exported but types +exposed, which is useful when developing multiple contracts together. +- And when running tests with `testutils`, so that all the utilities that get +automatically generated for tests are available in the tests of your contract +and others that import it. + +The config for the `release` profile lean the Rust toolchain towards optimizing +the size of the resulting code to keep it smaller. + +## Write the Code + +Open the `src/lib.rs` file, and copy-paste the following code. + +```rust +#![no_std] +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; + +pub struct Contract; + +#[contractimpl(export_if = "export")] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] + } +} + +#[cfg(test)] + mod test { + use super::{Contract, hello}; + use soroban_sdk::{vec, Env, FixedBinary}; + + #[test] + fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, Contract); + + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + ); + } +} +``` + +## Run the Tests + +Run `cargo test` and watch the contract run. You should see the following output: + +```sh +cargo test +``` + +``` +running 1 test +test test::test ... ok +``` + +Try changing the values in the test to see how it works. + +## Build WASM + +To build the contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +## Run the WASM + +It's not yet possible to run the WASM, but check back soon for the release of +the `soroban-cli` where you'll be able to interactively run the WASM. diff --git a/docs/getting-started/install.mdx b/docs/getting-started/install.mdx deleted file mode 100644 index c25f063d3..000000000 --- a/docs/getting-started/install.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 1 -title: Install Soroban ---- - -TODO THIS PAGE IS INCOMPLETE diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 826b95da4..e8397dbba 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -3,23 +3,32 @@ sidebar_position: 1 title: Setup --- -TODO THIS PAGE IS INCOMPLETE +Soroban contracts are small programs written in the [Rust] programming language. -Soroban contracts are written in [Rust]. To setup your development environment to develop contracts, you need to: +To build and develop contracts you need only a couple pre-requisites: To setup +your development environment to develop contracts, you need only a couple +pre-requisites: -1. Install Rust -2. Create a new Rust project -3. Update the project to import the `soroban-sdk` -4. Write a test +- A [Rust] toolchain +- An editor that supports Rust ## Install Rust +If you use macOS, Linux, or another Unix-like OS, the simplest method to install +a Rust toolchain is to install `rustup`. Install `rustup` with the following +command. + ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -```sh -$ rustup update -``` +If you use Windows, or need an alternative method of installing Rust, check out: +https://www.rust-lang.org/tools/install + +## Configure an Editor + +Many editors have support for Rust. Visit the following link to find out how to +configure your editor: +https://www.rust-lang.org/tools [Rust]: https://www.rust-lang.org/ From f5d216e55c09ab084a8a610c186a884d69b199dd Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 28 Jul 2022 22:21:24 -0700 Subject: [PATCH 008/248] addcli (#23) * more * wip * wip * cli * 1 * link --- .../building-optimized-wasm.mdx | 48 +++++++++++++++++-- docs/getting-started/first-project.mdx | 33 +++++++++++-- docs/getting-started/install-soroban-cli.mdx | 42 ++++++++++++++++ docs/getting-started/setup.mdx | 2 + 4 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 docs/getting-started/install-soroban-cli.mdx diff --git a/docs/getting-started/building-optimized-wasm.mdx b/docs/getting-started/building-optimized-wasm.mdx index bdcd86cdc..926702e7e 100644 --- a/docs/getting-started/building-optimized-wasm.mdx +++ b/docs/getting-started/building-optimized-wasm.mdx @@ -1,10 +1,21 @@ --- -sidebar_position: 3 +sidebar_position: 4 title: Building Optimized WASM --- +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + Building optimized WASM files requires some additional options and commands, and -requires installing the nightly Rust toolchain and `wasm-opt`. +requires installing the `nightly` Rust toolchain and `wasm-opt`. + +:::info +Building optimized WASM is only necessary when deploying to network or when +analyzing the real size of a contract. It is otherwise not required during +initial development. +::: + +## Install Rust `nightly` To install the nightly Rust toolchain use `rustup`. @@ -12,12 +23,41 @@ To install the nightly Rust toolchain use `rustup`. rustup install nightly ``` -To install `wasm-opt`. +## Install `wasm-opt` + +To install `wasm-opt`, install `binaryen`. Depending on your operating system +there may be different ways to install it. + + + ```sh -TODO: Add instructions for installing wasm-opt. +brew install binaryen ``` + + + +For distributions that use `apt`: + +```sh +sudo apt install binaryen +``` + +For other distributions see: +https://github.com/WebAssembly/binaryen/releases + + + + +For install options see: +https://github.com/WebAssembly/binaryen/releases + + + + +## Building with `nightly` and `wasm-opt` + Then build your contract using nightly, and the additional options that remove unnecessary information from the contract. diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx index 9e060dbd2..fbc254245 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/first-project.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 title: First Project --- @@ -29,6 +29,11 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. +:::caution +The `soroban-sdk` is still in early development. Please report issues +[here](https://github.com/stellar/soroban-sdk). +::: + ```toml [lib] crate-type = ["cdylib", "rlib"] @@ -129,7 +134,29 @@ To build the contract into a `.wasm` file, use the `cargo build` command. cargo build --target wasm32-unknown-unknown --release ``` +A `.wasm` file should be outputted in the `target` directory: + +``` +target/wasm32-unknown-unknown/release/first-project.wasm +``` + ## Run the WASM -It's not yet possible to run the WASM, but check back soon for the release of -the `soroban-cli` where you'll be able to interactively run the WASM. +If you have [`soroban-cli`] installed, you can invoke contract functions in the +WASM using it. + +```sh +soroban-cli invoke \ + --file target/wasm32-unknown-unknown/release/first-project.wasm \ + --contract-id 1 + --fn hello + --arg friend +``` + +The following output should occur using the code above. + +``` +["Hello","friend"] +``` + +[`soroban-cli`]: install-soroban-cli.mdx diff --git a/docs/getting-started/install-soroban-cli.mdx b/docs/getting-started/install-soroban-cli.mdx new file mode 100644 index 000000000..8c581f5f4 --- /dev/null +++ b/docs/getting-started/install-soroban-cli.mdx @@ -0,0 +1,42 @@ +--- +sidebar_position: 2 +title: Install Soroban CLI +--- + +The Soroban CLI can execute WASM contracts in the same environment the contract +will execute on network, however in a local sandbox. + +Install the Soroban CLI using `cargo install`. + +```sh +cargo install --locked --git http://github.com/stellar/soroban-cli soroban-cli +``` + +:::caution +The `soroban-cli` is still in early development. Please report issues +[here](https://github.com/stellar/soroban-cli). +::: + +## Usage + +Run the `soroban-cli` command and you should see output like below. + +```sh +soroban-cli +``` + +``` +soroban-cli 0.0.1 + +USAGE: + soroban-cli + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + deploy Deploy a WASM file as a contract + version Print version information +``` diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index e8397dbba..b64200e46 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -11,6 +11,7 @@ pre-requisites: - A [Rust] toolchain - An editor that supports Rust +- [Soroban CLI] ## Install Rust @@ -32,3 +33,4 @@ configure your editor: https://www.rust-lang.org/tools [Rust]: https://www.rust-lang.org/ +[Soroban CLI]: install-soroban-cli.mdx From 666cb2d90ca1d0c0db8b373286f71865169d18a1 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 07:37:04 -0700 Subject: [PATCH 009/248] Add more getting started documentation (#25) --- docs/getting-started/build-a-wasm-file.mdx | 16 +++ ...m.mdx => build-an-optimized-wasm-file.mdx} | 4 +- docs/getting-started/install-soroban-cli.mdx | 42 -------- docs/getting-started/run-a-wasm-file.mdx | 28 ++++++ docs/getting-started/setup.mdx | 41 ++++++++ docs/getting-started/testing.mdx | 97 +++++++++++++++++++ docs/getting-started/write-a-contract.mdx | 64 ++++++++++++ 7 files changed, 248 insertions(+), 44 deletions(-) create mode 100644 docs/getting-started/build-a-wasm-file.mdx rename docs/getting-started/{building-optimized-wasm.mdx => build-an-optimized-wasm-file.mdx} (96%) delete mode 100644 docs/getting-started/install-soroban-cli.mdx create mode 100644 docs/getting-started/run-a-wasm-file.mdx create mode 100644 docs/getting-started/testing.mdx create mode 100644 docs/getting-started/write-a-contract.mdx diff --git a/docs/getting-started/build-a-wasm-file.mdx b/docs/getting-started/build-a-wasm-file.mdx new file mode 100644 index 000000000..2855ef6a7 --- /dev/null +++ b/docs/getting-started/build-a-wasm-file.mdx @@ -0,0 +1,16 @@ +--- +sidebar_position: 6 +title: Build a WASM File +--- + +To build a Soroban contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `target` directory: + +``` +target/wasm32-unknown-unknown/release/[project-name].wasm +``` diff --git a/docs/getting-started/building-optimized-wasm.mdx b/docs/getting-started/build-an-optimized-wasm-file.mdx similarity index 96% rename from docs/getting-started/building-optimized-wasm.mdx rename to docs/getting-started/build-an-optimized-wasm-file.mdx index 926702e7e..67c0d8469 100644 --- a/docs/getting-started/building-optimized-wasm.mdx +++ b/docs/getting-started/build-an-optimized-wasm-file.mdx @@ -1,6 +1,6 @@ --- -sidebar_position: 4 -title: Building Optimized WASM +sidebar_position: 8 +title: Build an Optimized WASM File --- import Tabs from '@theme/Tabs'; diff --git a/docs/getting-started/install-soroban-cli.mdx b/docs/getting-started/install-soroban-cli.mdx deleted file mode 100644 index 8c581f5f4..000000000 --- a/docs/getting-started/install-soroban-cli.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -sidebar_position: 2 -title: Install Soroban CLI ---- - -The Soroban CLI can execute WASM contracts in the same environment the contract -will execute on network, however in a local sandbox. - -Install the Soroban CLI using `cargo install`. - -```sh -cargo install --locked --git http://github.com/stellar/soroban-cli soroban-cli -``` - -:::caution -The `soroban-cli` is still in early development. Please report issues -[here](https://github.com/stellar/soroban-cli). -::: - -## Usage - -Run the `soroban-cli` command and you should see output like below. - -```sh -soroban-cli -``` - -``` -soroban-cli 0.0.1 - -USAGE: - soroban-cli - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - deploy Deploy a WASM file as a contract - version Print version information -``` diff --git a/docs/getting-started/run-a-wasm-file.mdx b/docs/getting-started/run-a-wasm-file.mdx new file mode 100644 index 000000000..b3438ce59 --- /dev/null +++ b/docs/getting-started/run-a-wasm-file.mdx @@ -0,0 +1,28 @@ +--- +sidebar_position: 7 +title: Run a WASM File +--- + +If you have [`soroban-cli`] installed, you can invoke contract functions in a +WASM file. + +Using the code we wrote in [Write a Contract](write-a-contract.mdx) and the the +resulting `.wasm` file we built in [Build a WASM File](build-a-wasm-file.mdx) +run the following command to invoke the `hello` function with a single argument +`"friend"`. + +```sh +soroban-cli invoke \ + --file target/wasm32-unknown-unknown/release/first-project.wasm \ + --contract-id 1 + --fn hello + --arg friend +``` + +The following output should appear. + +``` +["Hello","friend"] +``` + +[`soroban-cli`]: install-soroban-cli.mdx diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index b64200e46..ef490acce 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -32,5 +32,46 @@ Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools +## Install Soroban CLI + +The Soroban CLI can execute WASM contracts in the same environment the contract +will execute on network, however in a local sandbox. + +Install the Soroban CLI using `cargo install`. + +```sh +cargo install --locked --git http://github.com/stellar/soroban-cli soroban-cli +``` + +:::caution +The `soroban-cli` is still in early development. Please report issues +[here](https://github.com/stellar/soroban-cli). +::: + +### Usage + +Run the `soroban-cli` command and you should see output like below. + +```sh +soroban-cli +``` + +``` +soroban-cli 0.0.1 + +USAGE: + soroban-cli + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + deploy Deploy a WASM file as a contract + version Print version information +``` + + [Rust]: https://www.rust-lang.org/ [Soroban CLI]: install-soroban-cli.mdx diff --git a/docs/getting-started/testing.mdx b/docs/getting-started/testing.mdx new file mode 100644 index 000000000..47867975a --- /dev/null +++ b/docs/getting-started/testing.mdx @@ -0,0 +1,97 @@ +--- +sidebar_position: 5 +title: Testing +--- + +Writing tests for Soroban contracts involves writing Rust code using the Rust +test facilitiaties and toolchain that you'd use for testing any Rust code. + +Given a simple contract like the contract demonstrated in [Write a +Contract](write-a-contract.mdx). + +```rust +#![no_std] +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; + +pub struct Contract; + +#[contractimpl(export_if = "export")] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] + } +} +``` + +A simple test will look like this. + +``` + +#[cfg(test)] +mod test { + use super::{Contract, hello}; + use soroban_sdk::{vec, Env, FixedBinary}; + + #[test] + fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, Contract); + + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + ); + } +} +``` + +In any test the first thing that is always required is an `Env`, which is the +Host environment that the contract will run it. + +```rust +let env = Env::default(); +``` + +Contracts must be registered with the environment with a contract ID, which is a +32-byte value. In many cases it is sufficient to use a simple zero ID, however +if the test will deploy the contract multiple times, or deploy multiple +contracts, each should use their own IDs. + +```rust +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); +``` + +All public functions within an `impl` block that is annotated with the +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. + +```rust +let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +``` + +The values returned by functions can be asserted on: +```rust +assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] +); +``` + +## Run the Tests + +Run `cargo test` and watch the contract run. You should see the following output: + +```sh +cargo test +``` + +``` +running 1 test +test test::test ... ok +``` + +Try changing the values in the test to see how it works. diff --git a/docs/getting-started/write-a-contract.mdx b/docs/getting-started/write-a-contract.mdx new file mode 100644 index 000000000..03ed2061f --- /dev/null +++ b/docs/getting-started/write-a-contract.mdx @@ -0,0 +1,64 @@ +--- +sidebar_position: 4 +title: Write a Contract +--- + +Once you have a project setup, like how we setup a project in [First +Project](first-project.mdx), writing a contract involves writing Rust code in +the projects `lib.rs` file. + +```rust +#![no_std] +``` + +All contracts should begin with `#![no_std]` to ensure that the Rust standard +library is not included in the build. The Rust standard library is large and not +well suited to being deployed into small programs like those deployed to +blockchains. + +```rust +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +``` + +The contract will need to import the types and macros that it needs from the +`soroban_sdk` crate. Take a look at [First Project](first-project.mdx) to see +how to setup a project. + +Many of the types available in typical Rust programs, such as `std::vec::Vec`, +are not available, as their is no allocator and no heap memory in Soroban +contracts. The `soroban_sdk` provides a variety of types like `Vec`, `Map`, and +`BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environments memory +and native capabilities. + +```rust +pub struct Contract; + +#[contractimpl(export_if = "export")] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + todo!() + } +} +``` + +Contract functions live inside a `impl` for a struct. The `impl` block is +annotated with `#[contractimpl]`, and the functions that are intended to be +called are assigned `pub` visibility and have an `Env` argument as their first +argument. + +Putting those pieces together a simple contract will look like this. + +```rust +#![no_std] +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; + +pub struct Contract; + +#[contractimpl(export_if = "export")] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] + } +} +``` From 6e76dc16f4c99ae280830a48bb8ee27c66cf2163 Mon Sep 17 00:00:00 2001 From: jonjove <31668823+jonjove@users.noreply.github.com> Date: Fri, 29 Jul 2022 09:52:56 -0500 Subject: [PATCH 010/248] Fix formatting in first project (#27) --- docs/getting-started/first-project.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx index fbc254245..a697ec09d 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/first-project.mdx @@ -92,7 +92,7 @@ impl Contract { } #[cfg(test)] - mod test { +mod test { use super::{Contract, hello}; use soroban_sdk::{vec, Env, FixedBinary}; From 1c68d77e240ef24dc6ab31df3d7a0f67b69b3884 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 08:03:19 -0700 Subject: [PATCH 011/248] Make fixes to getting started docs (#28) --- docs/getting-started/first-project.mdx | 32 ++++++++++++----------- docs/getting-started/run-a-wasm-file.mdx | 2 +- docs/getting-started/setup.mdx | 6 ++--- docs/getting-started/write-a-contract.mdx | 3 +++ 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx index a697ec09d..f5c03beaf 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/first-project.mdx @@ -18,7 +18,7 @@ cargo new --lib [project-name] Open the `Cargo.toml`, it should look something like this: -```toml +```toml title="Cargo.toml" [package] name = "first-project" version = "0.1.0" @@ -30,7 +30,7 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. :::caution -The `soroban-sdk` is still in early development. Please report issues +The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/soroban-sdk). ::: @@ -60,18 +60,20 @@ codegen-units = 1 lto = true ``` -The features list and dev_dependencies might look a little strange, but we've -said that our contract can be built in three variations: -- By `default` with `export` with contract functions exported and available to -be called. -- Optionally without `export` enabled, contract functions not exported but types -exposed, which is useful when developing multiple contracts together. -- And when running tests with `testutils`, so that all the utilities that get -automatically generated for tests are available in the tests of your contract -and others that import it. - -The config for the `release` profile lean the Rust toolchain towards optimizing -the size of the resulting code to keep it smaller. +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. + +The config for the `release` profile configures the Rust toolchain to produce +smaller contracts. ## Write the Code @@ -155,7 +157,7 @@ soroban-cli invoke \ The following output should occur using the code above. -``` +```json ["Hello","friend"] ``` diff --git a/docs/getting-started/run-a-wasm-file.mdx b/docs/getting-started/run-a-wasm-file.mdx index b3438ce59..f9bf5b677 100644 --- a/docs/getting-started/run-a-wasm-file.mdx +++ b/docs/getting-started/run-a-wasm-file.mdx @@ -21,7 +21,7 @@ soroban-cli invoke \ The following output should appear. -``` +```json ["Hello","friend"] ``` diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index ef490acce..8f2ecb78b 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -32,7 +32,7 @@ Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools -## Install Soroban CLI +## Install the Soroban CLI The Soroban CLI can execute WASM contracts in the same environment the contract will execute on network, however in a local sandbox. @@ -44,7 +44,7 @@ cargo install --locked --git http://github.com/stellar/soroban-cli soroban-cli ``` :::caution -The `soroban-cli` is still in early development. Please report issues +The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli). ::: @@ -74,4 +74,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: install-soroban-cli.mdx +[Soroban CLI]: #install-the-soroban-cli diff --git a/docs/getting-started/write-a-contract.mdx b/docs/getting-started/write-a-contract.mdx index 03ed2061f..e02ad8226 100644 --- a/docs/getting-started/write-a-contract.mdx +++ b/docs/getting-started/write-a-contract.mdx @@ -46,6 +46,9 @@ annotated with `#[contractimpl]`, and the functions that are intended to be called are assigned `pub` visibility and have an `Env` argument as their first argument. +Implementations annotated can be configured to export the contract functions +only if a feature is enabled, with `export_if = "[feature-name]"`. + Putting those pieces together a simple contract will look like this. ```rust From 10795c87ed58015e7e906e2d196190a42cad66dc Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 29 Jul 2022 11:06:25 -0400 Subject: [PATCH 012/248] fixed all install soroban cli links --- docs/getting-started/first-project.mdx | 2 +- docs/getting-started/run-a-wasm-file.mdx | 2 +- docs/getting-started/setup.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx index f5c03beaf..56b6ed62e 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/first-project.mdx @@ -161,4 +161,4 @@ The following output should occur using the code above. ["Hello","friend"] ``` -[`soroban-cli`]: install-soroban-cli.mdx +[`soroban-cli`]: setup#install-the-soroban-cli diff --git a/docs/getting-started/run-a-wasm-file.mdx b/docs/getting-started/run-a-wasm-file.mdx index f9bf5b677..ef4de71b0 100644 --- a/docs/getting-started/run-a-wasm-file.mdx +++ b/docs/getting-started/run-a-wasm-file.mdx @@ -25,4 +25,4 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban-cli`]: install-soroban-cli.mdx +[`soroban-cli`]: setup#install-the-soroban-cli diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 8f2ecb78b..b857fac67 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -74,4 +74,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: #install-the-soroban-cli +[Soroban CLI]: setup#install-the-soroban-cli From fe3cda94ad6d2132b7ec1a5be4404fa99ffa18f4 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 09:51:37 -0700 Subject: [PATCH 013/248] Merge examples and tutorials (#31) --- docs/tutorials/_category_.json | 4 +- docs/tutorials/custom-types.mdx | 243 +++++++++++++++++++++++++++ docs/tutorials/hello-world.mdx | 179 ++++++++++++++++++++ docs/tutorials/increment.mdx | 193 +++++++++++++++++++++ docs/tutorials/liquidity-pool.mdx | 6 + docs/tutorials/single-offer-sale.mdx | 6 + 6 files changed, 629 insertions(+), 2 deletions(-) create mode 100644 docs/tutorials/custom-types.mdx create mode 100644 docs/tutorials/hello-world.mdx create mode 100644 docs/tutorials/increment.mdx create mode 100644 docs/tutorials/liquidity-pool.mdx create mode 100644 docs/tutorials/single-offer-sale.mdx diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json index 007228083..b3213599f 100644 --- a/docs/tutorials/_category_.json +++ b/docs/tutorials/_category_.json @@ -1,4 +1,4 @@ { - "position": 4, - "label": "Tutorials" + "position": 3, + "label": "Tutorials / Examples" } diff --git a/docs/tutorials/custom-types.mdx b/docs/tutorials/custom-types.mdx new file mode 100644 index 000000000..18bf324a6 --- /dev/null +++ b/docs/tutorials/custom-types.mdx @@ -0,0 +1,243 @@ +--- +sidebar_position: 3 +title: Custom Types +--- + +The [custom types example] demonstrates how to define your own data structures +that can be stored on the ledger, or used as inputs and outputs to contract +invocations. + +[custom types example]: https://github.com/stellar/soroban-examples/tree/main/custom_types + +## Run the example + +First go through the [Setup] process to get your development environment +configured, then clone the examples repository: + +[Setup]: ../getting-started/setup.mdx + +``` +git clone https://github.com/stellar/soroban-examples +``` + +To run the tests for the example, navigate to the `custom_types` directory, and use `cargo test`. + +``` +cd custom_types +cargo test +``` + +You should see the output: + +``` +running 1 test +test test::test ... ok +``` + +## Code + +```rust title="custom_types/src/lib.rs" +#[contracttype] +pub enum Name { + None, + FirstLast(FirstLast), +} + +#[contracttype] +pub struct FirstLast { + pub first: Symbol, + pub last: Symbol, +} + +pub struct CustomTypesContract; + +const NAME: Symbol = Symbol::from_str("NAME"); + +#[contractimpl] +impl CustomTypesContract { + pub fn store(env: Env, name: Name) { + env.contract_data().set(NAME, name); + } + + pub fn retrieve(env: Env) -> Name { + env.contract_data() + .get(NAME) // Get the value associated with key NAME. + .unwrap_or(Ok(Name::None)) // If no value, use None instead. + .unwrap() + } +} +``` + +Ref: https://github.com/stellar/soroban-examples/tree/main/custom_types + +## How it Works + +Custom types are defined using the `#[contracttype]` attribute on either a +`struct` or an `enum`. + +Open the `custom_types/src/lib.rs` file to follow along. + +### Custom Type: Struct + +Structs are stored on ledger as a map of key-value pairs, where the key is a 10 +character string representing the field name, and the value is the value +encoded. + +Field names must be no more than 10 characters. + +```rust +#[contracttype] +pub struct FirstLast { + pub first: Symbol, + pub last: Symbol, +} +``` + +### Custom Type: Enum + +Structs are stored on ledger as a two element vector, where the first element is +the name of the enum variant as a string up to 10 characters in length, and the +value is the value if the variant has one. + +Only unit variants and single value variants, like `Red` and `Blue` below, are +supported. + +```rust +#[contracttype] +pub enum Name { + None, + FirstLast(FirstLast), +} +``` + +### Using Structs and Enums in Functions + +Types that have been annotated with `#[contracttype]` can be used as inputs and +outputs on contract functions, and the values can be stored as contract data and +retrieved later. + +```rust +pub struct CustomTypesContract; + +const NAME: Symbol = Symbol::from_str("NAME"); + +#[contractimpl(export_if = "export")] +impl CustomTypesContract { + pub fn store(env: Env, name: Name) { + env.contract_data().set(NAME, name); + } + + pub fn retrieve(env: Env) -> Name { + env.contract_data() + .get(NAME) // Get the value associated with key NAME. + .unwrap_or(Ok(Name::None)) // If no value, use None instead. + .unwrap() + } +} +``` + +## Tests + +Open the `custom_types/src/test.rs` file to follow along. + +```rust title="custom_types/src/test.js" +#[test] +fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, CustomTypesContract); + + assert_eq!(retrieve::invoke(&env, &contract_id), Name::None); + + store::invoke( + &env, + &contract_id, + &Name::FirstLast(FirstLast { + first: Symbol::from_str("first"), + last: Symbol::from_str("last"), + }), + ); + + assert_eq!( + retrieve::invoke(&env, &contract_id), + Name::FirstLast(FirstLast { + first: Symbol::from_str("first"), + last: Symbol::from_str("last"), + }), + ); +} +``` + +In any test the first thing that is always required is an `Env`, which is the +Host environment that the contract will run it. + +```rust +let env = Env::default(); +``` + +Contracts must be registered with the environment with a contract ID, which is a +32-byte value. + +```rust +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); +``` + +All public functions within an `impl` block that is annotated with the +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. + +The test invokes the `retrieve` function on the registered contract, and asserts +that it returns `Name::None`. + +```rust +assert_eq!(retrieve::invoke(&env, &contract_id), Name::None); +``` + +The test then invokes the `store` function on the registered contract, to change +the name that is stored. + +```rust +store::invoke( + &env, + &contract_id, + &Name::FirstLast(FirstLast { + first: Symbol::from_str("first"), + last: Symbol::from_str("last"), + }), +); +``` + +The test invokes the `retrieve` function again, to assert that it returns the +name that was previously stored. + +```rust +assert_eq!( + retrieve::invoke(&env, &contract_id), + Name::FirstLast(FirstLast { + first: Symbol::from_str("first"), + last: Symbol::from_str("last"), + }), +); +``` + +## Build WASM + +To build the contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `../target` directory: + +``` +../target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm +``` + +## Run the WASM + +The `soroban-cli` is in early development and does not yet accept user-defined +types as arguments at the command line. Follow the GitHub repository to find out +about new releases: +https://github.com/stellar/soroban-cli diff --git a/docs/tutorials/hello-world.mdx b/docs/tutorials/hello-world.mdx new file mode 100644 index 000000000..cf4af9552 --- /dev/null +++ b/docs/tutorials/hello-world.mdx @@ -0,0 +1,179 @@ +--- +sidebar_position: 1 +title: Hello World +--- + +The [hello world example] demonstrates how to write a simple contract, with a +single function that takes one input and returns it as an output. + +[hello world example]: https://github.com/stellar/soroban-examples/tree/main/hello_world + +## Run the example + +First go through the [Setup] process to get your development environment +configured, then clone the examples repository: + +[Setup]: ../getting-started/setup.mdx + +``` +git clone https://github.com/stellar/soroban-examples +``` + +To run the tests for the example, navigate to the `hello_world` directory, and use `cargo test`. + +``` +cd hello_world +cargo test +``` + +You should see the output: + +``` +running 1 test +test test::test ... ok +``` + +## Code + +```rust title="hello_world/src/lib.rs" +#![no_std] +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; + +pub struct HelloContract; + +#[contractimpl] +impl HelloContract { + pub fn hello(env: Env, to: Symbol) -> Vec { + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] + } +} +``` +Ref: https://github.com/stellar/soroban-examples/tree/main/hello_world + +## How it Works + +Soroban contracts export all public functions that are within `impl` blocks that +have been annotated with `#[contractimpl]`. In the example above the contract +exports a single function, `hello`. + +Contract functions must be given names that are no more than 10 characters long. + +Open the `hello_world/src/lib.rs` file to follow along. + +### Contract Type + +Contract functions must be defined within an `impl` block, and therefore a type +is required for the impl to be attached. A simple zero-sized struct can be used. + +```rust +pub struct HelloContract; +``` + +### Contract Function + +Contract functions look much like regular Rust functions. They mave have any +number of arguments, but arguments must support being transmitted to and from +the Host environment that the contract runs in. The Soroban SDK provides some +types like `Symbol`, `Vec`, `Map`, `Binary`, `FixedBinary`, etc that can be +used. Primitive values like `u64`, `i64`, `u32`, `i32`, and `bool` can also be +used. Floats are not supported. + +Contract inputs must not be references. + +If the first argument of a contract function is of the `soroban_sdk::Env` type, +an `Env` will be provided that provides access to Host functionality. Most +functionality within the SDK requires an Env, so it is recommended to have it in +the argument list for most functions. + +```rust +#[contractimpl] +impl HelloContract { + pub fn hello(env: Env, to: Symbol) -> Vec { + ... + } +} +``` + +## Tests + +Open the `hello_world/src/test.rs` file to follow along. + +```rust title="hello_world/src/test.js" +#[test] +fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, HelloContract); + + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); + assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] + ); +} +``` + +In any test the first thing that is always required is an `Env`, which is the +Host environment that the contract will run it. + +```rust +let env = Env::default(); +``` + +Contracts must be registered with the environment with a contract ID, which is a +32-byte value. + +```rust +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); +``` + +All public functions within an `impl` block that is annotated with the +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. + +```rust +let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +``` + +The values returned by functions can be asserted on: +```rust +assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] +); +``` + +## Build WASM + +To build the contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `../target` directory: + +``` +../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm +``` + +## Run the WASM + +If you have [`soroban-cli`] installed, you can invoke contract functions in the +WASM using it. + +```sh +soroban-cli invoke \ + --file ../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm \ + --contract-id 1 + --fn hello + --arg friend +``` + +The following output should occur using the code above. + +```json +["Hello","friend"] +``` diff --git a/docs/tutorials/increment.mdx b/docs/tutorials/increment.mdx new file mode 100644 index 000000000..14296bf42 --- /dev/null +++ b/docs/tutorials/increment.mdx @@ -0,0 +1,193 @@ +--- +sidebar_position: 2 +title: Increment +--- + +The [increment example] demonstrates how to write a simple contract, with a +single function that increments an internal counter and returns the value. + +[increment example]: https://github.com/stellar/soroban-examples/tree/main/increment + +## Run the example + +First go through the [Setup] process to get your development environment +configured, then clone the examples repository: + +[Setup]: ../getting-started/setup.mdx + +``` +git clone https://github.com/stellar/soroban-examples +``` + +To run the tests for the example, navigate to the `increment` directory, and use `cargo test`. + +``` +cd increment +cargo test +``` + +You should see the output: + +``` +running 1 test +test test::test ... ok +``` + +## Code + +```rust title="increment/src/lib.rs" +const COUNTER: Symbol = Symbol::from_str("COUNTER"); + +pub struct IncrementContract; + +#[contractimpl(export_if = "export")] +impl IncrementContract { + pub fn increment(env: Env) -> u32 { + let mut count: u32 = env + .contract_data() + .get(COUNTER) + .unwrap_or(Ok(0)) // If no value set, assume 0. + .unwrap(); // Panic if the value of COUNTER is not u32. + count += 1; + env.contract_data().set(COUNTER, count); + count + } +} +``` +Ref: https://github.com/stellar/soroban-examples/tree/main/increment + +## How it Works + +Open the `hello_world/src/lib.rs` file to follow along. + +### Contract Data Keys + +Contract data that is stored is stored associated with a key. The key is the +value that can be used at a later time to lookup the value. + +`Symbol`s are a space and execution efficient value to use as static keys. When +produced in a `const` variable they are computed at compile time and stored in +code as a 64-bit value. Their maximum character length is 10. + +```rust +const COUNTER: Symbol = Symbol::from_str("COUNTER"); +``` + +### Contract Data Access + +The `Env` `contract_data()` function is used to retrieve access and update a +counter. The executing contract is the only contract that can query or modify +contract data that it has stored. The data stored is viewable on ledger anywhere +the ledger is viewable, but contracts executing within the Host environment are +restricted to their own data. + +The `get()` function gets the current value associated with the counter key. + +```rust +let mut count: u32 = env + .contract_data() + .get(COUNTER) + .unwrap_or(Ok(0)) // If no value set, assume 0. + .unwrap(); // Panic if the value of COUNTER is not u32. +``` + +If no value is currently stored, the value given to `unwrap_or(...)` is returned +instead. + +Values stored as contract data and retrieved are transmitted from the host and +expanded into the type specified. In this case a `u32`. If the value can be +expanded the type returned will be an `Ok(u32)`, otherwise the type returned +will be an `Err(_)`. The final `unwrap()` in the above code snippet is assuming +the value will always be a u32. If a developer caused it to be some other type a +panic would occur at the unwrap. + +The `set()` function stores the new count value against the key, replacing the +existing value. + +```rust +env.contract_data().set(COUNTER, count); +``` + +## Tests + +Open the `increment/src/test.rs` file to follow along. + +```rust title="increment/src/test.js" +#[test] +fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, IncrementContract); + + let count = increment::invoke(&env, &contract_id); + assert_eq!(count, 1); + + let count = increment::invoke(&env, &contract_id); + assert_eq!(count, 2); + + let count = increment::invoke(&env, &contract_id); + assert_eq!(count, 3); +} +``` + +In any test the first thing that is always required is an `Env`, which is the +Host environment that the contract will run it. + +```rust +let env = Env::default(); +``` + +Contracts must be registered with the environment with a contract ID, which is a +32-byte value. + +```rust +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); +``` + +All public functions within an `impl` block that is annotated with the +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. + +```rust +let count = increment::invoke(&env, &contract_id); +``` + +The values returned by functions can be asserted on: +```rust +assert_eq!(count, 1); +``` + +## Build WASM + +To build the contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `../target` directory: + +``` +../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm +``` + +## Run the WASM + +If you have [`soroban-cli`] installed, you can invoke contract functions in the +WASM using it. + +```sh +soroban-cli invoke \ + --file ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ + --contract-id 1 + --fn increment +``` + +The following output should occur using the code above. + +``` +1 +``` + +Run it a few more times to watch the count change. diff --git a/docs/tutorials/liquidity-pool.mdx b/docs/tutorials/liquidity-pool.mdx new file mode 100644 index 000000000..ee362a448 --- /dev/null +++ b/docs/tutorials/liquidity-pool.mdx @@ -0,0 +1,6 @@ +--- +sidebar_position: 4 +title: Liquidity Pool +--- + +TODO diff --git a/docs/tutorials/single-offer-sale.mdx b/docs/tutorials/single-offer-sale.mdx new file mode 100644 index 000000000..dccf7b492 --- /dev/null +++ b/docs/tutorials/single-offer-sale.mdx @@ -0,0 +1,6 @@ +--- +sidebar_position: 5 +title: Single Offer Sale +--- + +TODO From 4e1dc94b3b0d243674eec94eb72eef295a11f97f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 09:56:10 -0700 Subject: [PATCH 014/248] Fix code highlighting --- docs/getting-started/testing.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/getting-started/testing.mdx b/docs/getting-started/testing.mdx index 47867975a..50c0c8a58 100644 --- a/docs/getting-started/testing.mdx +++ b/docs/getting-started/testing.mdx @@ -26,8 +26,7 @@ impl Contract { A simple test will look like this. -``` - +```rust #[cfg(test)] mod test { use super::{Contract, hello}; From 15096a4e2a036434fd1375dd7e3b774ff642ec5b Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 09:57:28 -0700 Subject: [PATCH 015/248] Make example less idented (#32) --- docs/getting-started/testing.mdx | 37 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/docs/getting-started/testing.mdx b/docs/getting-started/testing.mdx index 50c0c8a58..0e35d6d91 100644 --- a/docs/getting-started/testing.mdx +++ b/docs/getting-started/testing.mdx @@ -9,7 +9,7 @@ test facilitiaties and toolchain that you'd use for testing any Rust code. Given a simple contract like the contract demonstrated in [Write a Contract](write-a-contract.mdx). -```rust +```rust title="src/lib.rs" #![no_std] use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; @@ -26,24 +26,23 @@ impl Contract { A simple test will look like this. -```rust -#[cfg(test)] -mod test { - use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary}; - - #[test] - fn test() { - let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); - env.register_contract(&contract_id, Contract); - - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); - assert_eq!( - words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] - ); - } +```rust title="src/test.rs" +#![cfg(test)] + +use super::{Contract, hello}; +use soroban_sdk::{vec, Env, FixedBinary}; + +#[test] +fn test() { + let env = Env::default(); + let contract_id = FixedBinary::from_array(&env, [0; 32]); + env.register_contract(&contract_id, Contract); + + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + assert_eq!( + words, + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + ); } ``` From d39ea3b30016679b489ff902a226c57ff0469be6 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:12:28 -0700 Subject: [PATCH 016/248] Order tutorials above learn (#34) --- docs/tutorials/_category_.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json index b3213599f..8d285b205 100644 --- a/docs/tutorials/_category_.json +++ b/docs/tutorials/_category_.json @@ -1,4 +1,4 @@ { - "position": 3, + "position": 2, "label": "Tutorials / Examples" } From 01befed4bb07d3ef1aa8ba8ef0e54c8c61faba30 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:16:47 -0700 Subject: [PATCH 017/248] Rename tutorials/examples folder (#35) --- docs/tutorials/_category_.json | 4 - docs/tutorials/custom-types.mdx | 243 --------------------------- docs/tutorials/hello-world.mdx | 179 -------------------- docs/tutorials/increment.mdx | 193 --------------------- docs/tutorials/liquidity-pool.mdx | 6 - docs/tutorials/single-offer-sale.mdx | 6 - 6 files changed, 631 deletions(-) delete mode 100644 docs/tutorials/_category_.json delete mode 100644 docs/tutorials/custom-types.mdx delete mode 100644 docs/tutorials/hello-world.mdx delete mode 100644 docs/tutorials/increment.mdx delete mode 100644 docs/tutorials/liquidity-pool.mdx delete mode 100644 docs/tutorials/single-offer-sale.mdx diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json deleted file mode 100644 index 8d285b205..000000000 --- a/docs/tutorials/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "position": 2, - "label": "Tutorials / Examples" -} diff --git a/docs/tutorials/custom-types.mdx b/docs/tutorials/custom-types.mdx deleted file mode 100644 index 18bf324a6..000000000 --- a/docs/tutorials/custom-types.mdx +++ /dev/null @@ -1,243 +0,0 @@ ---- -sidebar_position: 3 -title: Custom Types ---- - -The [custom types example] demonstrates how to define your own data structures -that can be stored on the ledger, or used as inputs and outputs to contract -invocations. - -[custom types example]: https://github.com/stellar/soroban-examples/tree/main/custom_types - -## Run the example - -First go through the [Setup] process to get your development environment -configured, then clone the examples repository: - -[Setup]: ../getting-started/setup.mdx - -``` -git clone https://github.com/stellar/soroban-examples -``` - -To run the tests for the example, navigate to the `custom_types` directory, and use `cargo test`. - -``` -cd custom_types -cargo test -``` - -You should see the output: - -``` -running 1 test -test test::test ... ok -``` - -## Code - -```rust title="custom_types/src/lib.rs" -#[contracttype] -pub enum Name { - None, - FirstLast(FirstLast), -} - -#[contracttype] -pub struct FirstLast { - pub first: Symbol, - pub last: Symbol, -} - -pub struct CustomTypesContract; - -const NAME: Symbol = Symbol::from_str("NAME"); - -#[contractimpl] -impl CustomTypesContract { - pub fn store(env: Env, name: Name) { - env.contract_data().set(NAME, name); - } - - pub fn retrieve(env: Env) -> Name { - env.contract_data() - .get(NAME) // Get the value associated with key NAME. - .unwrap_or(Ok(Name::None)) // If no value, use None instead. - .unwrap() - } -} -``` - -Ref: https://github.com/stellar/soroban-examples/tree/main/custom_types - -## How it Works - -Custom types are defined using the `#[contracttype]` attribute on either a -`struct` or an `enum`. - -Open the `custom_types/src/lib.rs` file to follow along. - -### Custom Type: Struct - -Structs are stored on ledger as a map of key-value pairs, where the key is a 10 -character string representing the field name, and the value is the value -encoded. - -Field names must be no more than 10 characters. - -```rust -#[contracttype] -pub struct FirstLast { - pub first: Symbol, - pub last: Symbol, -} -``` - -### Custom Type: Enum - -Structs are stored on ledger as a two element vector, where the first element is -the name of the enum variant as a string up to 10 characters in length, and the -value is the value if the variant has one. - -Only unit variants and single value variants, like `Red` and `Blue` below, are -supported. - -```rust -#[contracttype] -pub enum Name { - None, - FirstLast(FirstLast), -} -``` - -### Using Structs and Enums in Functions - -Types that have been annotated with `#[contracttype]` can be used as inputs and -outputs on contract functions, and the values can be stored as contract data and -retrieved later. - -```rust -pub struct CustomTypesContract; - -const NAME: Symbol = Symbol::from_str("NAME"); - -#[contractimpl(export_if = "export")] -impl CustomTypesContract { - pub fn store(env: Env, name: Name) { - env.contract_data().set(NAME, name); - } - - pub fn retrieve(env: Env) -> Name { - env.contract_data() - .get(NAME) // Get the value associated with key NAME. - .unwrap_or(Ok(Name::None)) // If no value, use None instead. - .unwrap() - } -} -``` - -## Tests - -Open the `custom_types/src/test.rs` file to follow along. - -```rust title="custom_types/src/test.js" -#[test] -fn test() { - let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); - env.register_contract(&contract_id, CustomTypesContract); - - assert_eq!(retrieve::invoke(&env, &contract_id), Name::None); - - store::invoke( - &env, - &contract_id, - &Name::FirstLast(FirstLast { - first: Symbol::from_str("first"), - last: Symbol::from_str("last"), - }), - ); - - assert_eq!( - retrieve::invoke(&env, &contract_id), - Name::FirstLast(FirstLast { - first: Symbol::from_str("first"), - last: Symbol::from_str("last"), - }), - ); -} -``` - -In any test the first thing that is always required is an `Env`, which is the -Host environment that the contract will run it. - -```rust -let env = Env::default(); -``` - -Contracts must be registered with the environment with a contract ID, which is a -32-byte value. - -```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); -``` - -All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. - -The test invokes the `retrieve` function on the registered contract, and asserts -that it returns `Name::None`. - -```rust -assert_eq!(retrieve::invoke(&env, &contract_id), Name::None); -``` - -The test then invokes the `store` function on the registered contract, to change -the name that is stored. - -```rust -store::invoke( - &env, - &contract_id, - &Name::FirstLast(FirstLast { - first: Symbol::from_str("first"), - last: Symbol::from_str("last"), - }), -); -``` - -The test invokes the `retrieve` function again, to assert that it returns the -name that was previously stored. - -```rust -assert_eq!( - retrieve::invoke(&env, &contract_id), - Name::FirstLast(FirstLast { - first: Symbol::from_str("first"), - last: Symbol::from_str("last"), - }), -); -``` - -## Build WASM - -To build the contract into a `.wasm` file, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file should be outputted in the `../target` directory: - -``` -../target/wasm32-unknown-unknown/release/soroban_custom_types_contract.wasm -``` - -## Run the WASM - -The `soroban-cli` is in early development and does not yet accept user-defined -types as arguments at the command line. Follow the GitHub repository to find out -about new releases: -https://github.com/stellar/soroban-cli diff --git a/docs/tutorials/hello-world.mdx b/docs/tutorials/hello-world.mdx deleted file mode 100644 index cf4af9552..000000000 --- a/docs/tutorials/hello-world.mdx +++ /dev/null @@ -1,179 +0,0 @@ ---- -sidebar_position: 1 -title: Hello World ---- - -The [hello world example] demonstrates how to write a simple contract, with a -single function that takes one input and returns it as an output. - -[hello world example]: https://github.com/stellar/soroban-examples/tree/main/hello_world - -## Run the example - -First go through the [Setup] process to get your development environment -configured, then clone the examples repository: - -[Setup]: ../getting-started/setup.mdx - -``` -git clone https://github.com/stellar/soroban-examples -``` - -To run the tests for the example, navigate to the `hello_world` directory, and use `cargo test`. - -``` -cd hello_world -cargo test -``` - -You should see the output: - -``` -running 1 test -test test::test ... ok -``` - -## Code - -```rust title="hello_world/src/lib.rs" -#![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; - -pub struct HelloContract; - -#[contractimpl] -impl HelloContract { - pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] - } -} -``` -Ref: https://github.com/stellar/soroban-examples/tree/main/hello_world - -## How it Works - -Soroban contracts export all public functions that are within `impl` blocks that -have been annotated with `#[contractimpl]`. In the example above the contract -exports a single function, `hello`. - -Contract functions must be given names that are no more than 10 characters long. - -Open the `hello_world/src/lib.rs` file to follow along. - -### Contract Type - -Contract functions must be defined within an `impl` block, and therefore a type -is required for the impl to be attached. A simple zero-sized struct can be used. - -```rust -pub struct HelloContract; -``` - -### Contract Function - -Contract functions look much like regular Rust functions. They mave have any -number of arguments, but arguments must support being transmitted to and from -the Host environment that the contract runs in. The Soroban SDK provides some -types like `Symbol`, `Vec`, `Map`, `Binary`, `FixedBinary`, etc that can be -used. Primitive values like `u64`, `i64`, `u32`, `i32`, and `bool` can also be -used. Floats are not supported. - -Contract inputs must not be references. - -If the first argument of a contract function is of the `soroban_sdk::Env` type, -an `Env` will be provided that provides access to Host functionality. Most -functionality within the SDK requires an Env, so it is recommended to have it in -the argument list for most functions. - -```rust -#[contractimpl] -impl HelloContract { - pub fn hello(env: Env, to: Symbol) -> Vec { - ... - } -} -``` - -## Tests - -Open the `hello_world/src/test.rs` file to follow along. - -```rust title="hello_world/src/test.js" -#[test] -fn test() { - let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); - env.register_contract(&contract_id, HelloContract); - - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); - assert_eq!( - words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] - ); -} -``` - -In any test the first thing that is always required is an `Env`, which is the -Host environment that the contract will run it. - -```rust -let env = Env::default(); -``` - -Contracts must be registered with the environment with a contract ID, which is a -32-byte value. - -```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); -``` - -All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. - -```rust -let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); -``` - -The values returned by functions can be asserted on: -```rust -assert_eq!( - words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] -); -``` - -## Build WASM - -To build the contract into a `.wasm` file, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file should be outputted in the `../target` directory: - -``` -../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm -``` - -## Run the WASM - -If you have [`soroban-cli`] installed, you can invoke contract functions in the -WASM using it. - -```sh -soroban-cli invoke \ - --file ../target/wasm32-unknown-unknown/release/soroban_hello_world_contract.wasm \ - --contract-id 1 - --fn hello - --arg friend -``` - -The following output should occur using the code above. - -```json -["Hello","friend"] -``` diff --git a/docs/tutorials/increment.mdx b/docs/tutorials/increment.mdx deleted file mode 100644 index 14296bf42..000000000 --- a/docs/tutorials/increment.mdx +++ /dev/null @@ -1,193 +0,0 @@ ---- -sidebar_position: 2 -title: Increment ---- - -The [increment example] demonstrates how to write a simple contract, with a -single function that increments an internal counter and returns the value. - -[increment example]: https://github.com/stellar/soroban-examples/tree/main/increment - -## Run the example - -First go through the [Setup] process to get your development environment -configured, then clone the examples repository: - -[Setup]: ../getting-started/setup.mdx - -``` -git clone https://github.com/stellar/soroban-examples -``` - -To run the tests for the example, navigate to the `increment` directory, and use `cargo test`. - -``` -cd increment -cargo test -``` - -You should see the output: - -``` -running 1 test -test test::test ... ok -``` - -## Code - -```rust title="increment/src/lib.rs" -const COUNTER: Symbol = Symbol::from_str("COUNTER"); - -pub struct IncrementContract; - -#[contractimpl(export_if = "export")] -impl IncrementContract { - pub fn increment(env: Env) -> u32 { - let mut count: u32 = env - .contract_data() - .get(COUNTER) - .unwrap_or(Ok(0)) // If no value set, assume 0. - .unwrap(); // Panic if the value of COUNTER is not u32. - count += 1; - env.contract_data().set(COUNTER, count); - count - } -} -``` -Ref: https://github.com/stellar/soroban-examples/tree/main/increment - -## How it Works - -Open the `hello_world/src/lib.rs` file to follow along. - -### Contract Data Keys - -Contract data that is stored is stored associated with a key. The key is the -value that can be used at a later time to lookup the value. - -`Symbol`s are a space and execution efficient value to use as static keys. When -produced in a `const` variable they are computed at compile time and stored in -code as a 64-bit value. Their maximum character length is 10. - -```rust -const COUNTER: Symbol = Symbol::from_str("COUNTER"); -``` - -### Contract Data Access - -The `Env` `contract_data()` function is used to retrieve access and update a -counter. The executing contract is the only contract that can query or modify -contract data that it has stored. The data stored is viewable on ledger anywhere -the ledger is viewable, but contracts executing within the Host environment are -restricted to their own data. - -The `get()` function gets the current value associated with the counter key. - -```rust -let mut count: u32 = env - .contract_data() - .get(COUNTER) - .unwrap_or(Ok(0)) // If no value set, assume 0. - .unwrap(); // Panic if the value of COUNTER is not u32. -``` - -If no value is currently stored, the value given to `unwrap_or(...)` is returned -instead. - -Values stored as contract data and retrieved are transmitted from the host and -expanded into the type specified. In this case a `u32`. If the value can be -expanded the type returned will be an `Ok(u32)`, otherwise the type returned -will be an `Err(_)`. The final `unwrap()` in the above code snippet is assuming -the value will always be a u32. If a developer caused it to be some other type a -panic would occur at the unwrap. - -The `set()` function stores the new count value against the key, replacing the -existing value. - -```rust -env.contract_data().set(COUNTER, count); -``` - -## Tests - -Open the `increment/src/test.rs` file to follow along. - -```rust title="increment/src/test.js" -#[test] -fn test() { - let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); - env.register_contract(&contract_id, IncrementContract); - - let count = increment::invoke(&env, &contract_id); - assert_eq!(count, 1); - - let count = increment::invoke(&env, &contract_id); - assert_eq!(count, 2); - - let count = increment::invoke(&env, &contract_id); - assert_eq!(count, 3); -} -``` - -In any test the first thing that is always required is an `Env`, which is the -Host environment that the contract will run it. - -```rust -let env = Env::default(); -``` - -Contracts must be registered with the environment with a contract ID, which is a -32-byte value. - -```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); -``` - -All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. - -```rust -let count = increment::invoke(&env, &contract_id); -``` - -The values returned by functions can be asserted on: -```rust -assert_eq!(count, 1); -``` - -## Build WASM - -To build the contract into a `.wasm` file, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file should be outputted in the `../target` directory: - -``` -../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm -``` - -## Run the WASM - -If you have [`soroban-cli`] installed, you can invoke contract functions in the -WASM using it. - -```sh -soroban-cli invoke \ - --file ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ - --contract-id 1 - --fn increment -``` - -The following output should occur using the code above. - -``` -1 -``` - -Run it a few more times to watch the count change. diff --git a/docs/tutorials/liquidity-pool.mdx b/docs/tutorials/liquidity-pool.mdx deleted file mode 100644 index ee362a448..000000000 --- a/docs/tutorials/liquidity-pool.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 4 -title: Liquidity Pool ---- - -TODO diff --git a/docs/tutorials/single-offer-sale.mdx b/docs/tutorials/single-offer-sale.mdx deleted file mode 100644 index dccf7b492..000000000 --- a/docs/tutorials/single-offer-sale.mdx +++ /dev/null @@ -1,6 +0,0 @@ ---- -sidebar_position: 5 -title: Single Offer Sale ---- - -TODO From 58a1b0d517396f7f6dd8e262a7c650cce92fc2c2 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:29:21 -0700 Subject: [PATCH 018/248] Fix links (#37) --- docs/getting-started/first-project.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/first-project.mdx index 56b6ed62e..8d409146e 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/first-project.mdx @@ -31,7 +31,7 @@ Add the following sections to the `Cargo.toml` that will import the `soroban-sdk :::caution The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/soroban-sdk). +[here](https://github.com/stellar/rs-soroban-sdk). ::: ```toml From 5c2da9ff4fb8ec28fb402f21f6852b4a295c7be2 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:30:50 -0700 Subject: [PATCH 019/248] Fix refs to crate name (#38) --- docs/getting-started/write-a-contract.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/write-a-contract.mdx b/docs/getting-started/write-a-contract.mdx index e02ad8226..03d92d882 100644 --- a/docs/getting-started/write-a-contract.mdx +++ b/docs/getting-started/write-a-contract.mdx @@ -21,12 +21,12 @@ use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the -`soroban_sdk` crate. Take a look at [First Project](first-project.mdx) to see +`soroban-sdk` crate. Take a look at [First Project](first-project.mdx) to see how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as their is no allocator and no heap memory in Soroban -contracts. The `soroban_sdk` provides a variety of types like `Vec`, `Map`, and +contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, and `BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environments memory and native capabilities. From 601f640fc96663e681cd011277d1799b12893f9c Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:36:30 -0700 Subject: [PATCH 020/248] Move Learn and Under-the-Hood to Guides (#39) --- docs/guides/_category_.json | 4 + docs/guides/contract-lifecycle.mdx | 38 +++ docs/guides/debugging.mdx | 42 ++++ docs/guides/environment-concepts.mdx | 47 ++++ docs/guides/events.mdx | 11 + docs/guides/gas-and-metering.mdx | 12 + docs/guides/high-level-overview.mdx | 30 +++ docs/guides/interacting-with-contracts-2.mdx | 44 ++++ docs/guides/interacting-with-contracts.mdx | 100 ++++++++ docs/guides/persisting-data.mdx | 22 ++ docs/guides/rust-dialect.mdx | 56 +++++ .../standard-assets-and-authorization.mdx | 234 ++++++++++++++++++ 12 files changed, 640 insertions(+) create mode 100644 docs/guides/_category_.json create mode 100644 docs/guides/contract-lifecycle.mdx create mode 100644 docs/guides/debugging.mdx create mode 100644 docs/guides/environment-concepts.mdx create mode 100644 docs/guides/events.mdx create mode 100644 docs/guides/gas-and-metering.mdx create mode 100644 docs/guides/high-level-overview.mdx create mode 100644 docs/guides/interacting-with-contracts-2.mdx create mode 100644 docs/guides/interacting-with-contracts.mdx create mode 100644 docs/guides/persisting-data.mdx create mode 100644 docs/guides/rust-dialect.mdx create mode 100644 docs/guides/standard-assets-and-authorization.mdx diff --git a/docs/guides/_category_.json b/docs/guides/_category_.json new file mode 100644 index 000000000..1ba237c2d --- /dev/null +++ b/docs/guides/_category_.json @@ -0,0 +1,4 @@ +{ + "position": 5, + "label": "Guides" +} diff --git a/docs/guides/contract-lifecycle.mdx b/docs/guides/contract-lifecycle.mdx new file mode 100644 index 000000000..b35189a57 --- /dev/null +++ b/docs/guides/contract-lifecycle.mdx @@ -0,0 +1,38 @@ +--- +sidebar_position: 3 +title: Contract Lifecycle +--- + +## Development +Contract development can be done on a local computer with as little as 3 necessary components: an IDE, a copy of the Rust toolchain, and a copy of the Soroban SDK. + +The SDK contains a full working copy of the host environment, as well as a "mock" version of the ledger for persistent storage of contract data. It is therefore possible (and encouraged) to edit, compile, test and debug contracts directly against this "local" copy of the host, entirely offline and without even accessing a test network. + +To make the local development process even more convenient and fast, the contract being developed can (and should) be compiled as native code and linked directly to the local host, rather than compiled to WASM and run in a local VM sandbox. Both configurations are possible, but the native configuration is fastest and provides the richest testing and debugging experience. + +The SDK-provided local contract host also contains a local web server that serves the necessary HTTP API endpoint used for client applications to interact with a contract. This can be used for local development of applications, again without needing to deploy contracts to any test or live network. +## Deployment +Once a contract has been tested and debugged locally, it can be deployed. To do this it must be compiled to WASM code, and then included by value in a transaction sent to the intended deployment network. + +The SDK provides a command-line utility that invokes the Rust compiler with the correct settings for producing a WASM bundle for deployment, but developers can also build this themselves. + +Before submitting to the network, developers should inspect the resulting WASM binary emitted by the Rust compiler to ensure that it contains only the intended code and data, and is as small as possible. The SDK command-line utility contains diagnostic commands to assist with this process. + +The SDK command-line utility can also build and submit the transaction deploying a WASM contract to the network. Deployment requires sufficient network credentials to sign a transaction performing the deployment and pay its fees. Contracts should be deployed to test networks and thoroughly tested there being deployed to the live network. +## Execution +Deployed contracts live on chain in a CONTRACT_DATA ledger entry. They are executed within a VM sandbox managed by a host environment inside stellar-core. Each transaction that leads to a contract execution is run in a separate host environment, and each contract called by such a transaction (either directly or indirectly from another contract) is executed in a separate guest WASM VM contained within the transaction’s host environment. + +Execution is initiated by a host function called "call". The "call" host function can itself be invoked two different ways: either by someone submitting a transaction to the network that invokes "call" directly, or indirectly by some other contract invoking "call". + +In either case, the "call" host function is provided with the ID of a contract to invoke, the name of a function in the contract, and a vector of argument values to pass. The "call" host function then sets up a VM sandbox for the called contract, loads and instantiates its WASM bytecode, and invokes the named function, passing the provided arguments. + +Each contract execution continues until the contract either completes successfully or traps with an error condition. If execution completes successfully, all ledger entries modified during execution will be written back to the ledger atomically. If execution traps, all modified ledger entries will be discarded and the contract will have no effect on the ledger. + +A variety of conditions in either the guest or host environments can cause a contract to trap. If a host function is called with invalid arguments, for example, the host will trap. Similarly if the contract performs an erroneous WASM bytecode such as a division by zero or access to memory out of bounds, the WASM VM will trap. Also if the contract uses more resources than its enclosing transaction has paid for, the contract will trap. +## Monitoring +Contracts can be monitored in two main ways: by observing events emitted during their execution, and by examining the ledger entries written by them. + +TBD: expand this section. + +## Upgrading contracts +TBD: depends on decisions pending in CAPs. diff --git a/docs/guides/debugging.mdx b/docs/guides/debugging.mdx new file mode 100644 index 000000000..5fc2b5ed6 --- /dev/null +++ b/docs/guides/debugging.mdx @@ -0,0 +1,42 @@ +--- +sidebar_position: 9 +title: Debugging +--- + +Soroban contracts are as much as possible regular Rust programs and can be debugged using the same tools you'd usually use. + +The debugging facilities available differ significantly depending on whether a contract is compiled natively for local testing, or compiled into WASM for deployment. + +Deciding between these two modes and making the most of them while debugging requires a **careful understanding** of which code is compiled-in to deployed contracts and which code is only available for local testing. + +## Local-testing mode + +It is possible (and encouraged during development) to compile Soroban contracts **natively** (eg. as x86-64 or AArch64 code) and link against the host environment **directly**, such that the contract is not a guest running in a WASM virtual machine at all: it is simply one native library calling another -- its host -- and both host and contract are linked together as a single program, together with a test harness. + +This configuration is referred to as **"local-testing mode"** and since it eliminates the WASM virtual machine from the debugging experience it has many advantages: + + - Tests run much faster since there is no VM interpreting them, and will execute in parallel by default on multiple threads. + - Tests can use numerous standard testing and debugging techniques: + - [The standard Rust `#[test]` harness](https://doc.rust-lang.org/reference/attributes/testing.html), including push-button IDE support for running and re-running single tests. + - [Standard IDE-supported debuggers](https://code.visualstudio.com/docs/languages/rust#_debugging), including IDE support for setting breakpoints and inspecting values in both contract and host. + - Lightweight debugging via [standard logging](https://docs.rs/log/latest/log/) or [tracing](https://docs.rs/tracing/latest/tracing/). + - Systematic testing such as [fuzzing](https://crates.io/crates/cargo-fuzz), [property-testing](https://crates.io/crates/proptest), or even [model checking](https://crates.io/crates/kani-verifier) or [formal verification](https://github.com/xldenis/creusot). + - The simplest of all debugging approaches, [printing to standard error](https://doc.rust-lang.org/std/macro.eprintln.html). + +Local-testing mode is the **default** configuration when compiling code targeting your local computer's CPU and operating system, which is what cargo will do if you set up a new Rust project and don't specify a target. + +## WASM mode + +If on the other hand you wish to compile for deployment, you must tell cargo to build for the WASM target. + +Building for WASM will _disable_ many of the debugging facilities described above, typically for one of three reasons: + + - The WASM VM simply can't (or the VM we've chosen doesn't) provide them. + - The WASM VM _could_ provide them but doing so would violate constraints of the [contract Rust dialect](rust-dialect.mdx). + - The WASM VM _could_ provide them but doing so would make the resulting WASM code impractically large. + +While we encourage most testing to happen in local-testing mode, some problems will obviously only arise in deployment and some debugging facilities thus remain available even there: + + - A "sandbox" host with a mock-ledger that can read and write `CONTRACT_DATA` ledger entries to the local filesystem. + - A general logging system that allows contracts to log values of the [shared host/guest "value" type](environment-concepts.mdx), even in production. + - User-extensible `Status` codes that can be returned from any contract call to indicate problems. diff --git a/docs/guides/environment-concepts.mdx b/docs/guides/environment-concepts.mdx new file mode 100644 index 000000000..fee24f854 --- /dev/null +++ b/docs/guides/environment-concepts.mdx @@ -0,0 +1,47 @@ +--- +sidebar_position: 2 +title: Environment Concepts +--- + +The contract environment is an _interface_ that defines the facilities -- objects, functions, data sources, etc. -- available to contracts. + +## Host and Guest +As an interface, the environment has two sides, which we refer to as the host environment and the guest environment. Code in the host environment _implements_ the environment interface; code in the guest environment _uses_ the environment interface. + +The **host environment** is provided by a known set of Rust crates, compiled once into stellar-core (or the SDK). Multiple contracts interact with the same host environment, and the host environment has access to any facilities of its enclosing operating system: files, networking, memory, etc. + +In contrast, a new **guest environment** is established for each invocation of each smart contract. Each contract sees a single environment interface, and can only call functions provided by the environment interface. In other words, the guest environment is a sandbox for executing arbitrary code within safe parameters. + +## WebAssembly +The on-chain guest environment is isolated inside a WebAssembly (WASM) virtual machine ("VM"). This means that deployed contract code is compiled to WASM bytecode rather than native machine code. The host environment includes an interpreter for the VM, and a new short-lived VM is instantiated for each call to a contract, running the bytecode for the contract and then exiting. + +The use of a VM helps provide security against any potential guest-code misbehavior, to both host and other guest environments, as well as ensuring portability of guest code between hosts running on different types of hardware. + +When developing and testing contract code off-chain, it is possible to compile contract code to native machine code rather than WASM bytecode, and to [run tests and debug contracts](debugging-contracts.mdx) against a local copy of the host environment by linking directly to it, rather than executing within a VM. This configuration runs much faster and provides much better debugging information, but is only possible locally, off-chain. On-chain deployed contracts are always WASM. + +WebAssembly is a relatively low-level VM, which means that it does not provide a very rich set of standard or "built-in" operations. In contrast to VMs like the JVM, it has no garbage collector (not even a memory allocator), no IO facilities, no standard data structures like lists, arrays, maps or strings, no concepts of objects or types at all besides basic machine types like 32 and 64-bit integers. + +As a result, programs compiled to WASM bytecode often face a dilemma: if they want rich standard functionality, they must often include a copy of all the "support code" for that functionality within themselves. But if they do, they dramatically increase their code size, which incurs costs and limits performance. Moreover, including such support code limits their ability to interoperate with other programs that may include different, incompatible support code. + +The way out of this dilemma is for the environment itself to provide support code for rich standard functionality, in the form of host objects and functions that guest code can use by reference. Each contract refers to the same functionality implemented in the host, ensuring much smaller code size, higher performance, and greater interoperability between contracts. This is what Soroban does. + +## Host objects and functions +Shared, standard functionality available to all contract guest code is provided through the environment interface in terms of host objects and host functions. + +The environment supports a small number of types of host objects covering data structures like vectors, maps, binary blobs, and arbitrary precision numbers. Host objects are all immutable, are allocated and reside within the host environment, and are only available in the guest environment by reference. Guest code refers to host objects by integer-valued handles. + +There is also a slightly larger set of host functions that act on host objects: creating, modifying, inspecting and manipulating them. Some host functions allow copying blocks of binary data into and out of the VM memory of the guest, and some host functions perform cryptographic operations on host objects. + +There are also host functions for interacting with select components of the host environment beyond the host object repertoire, such as reading and writing ledger entries, emitting events, calling other contracts, and accessing information about the transaction context in which guest code is executing. + +### Serialization +Host objects can be passed (by handle) directly to storage routines or between collaborating contracts. **No serialization or deserialization code needs to exist in the guest**: the host knows how to serialize and deserialize all of its object types and does so transparently whenever necessary. + +## Values and types +All host functions can accept as arguments and return values from, at most, the limited WASM VM repertoire of machine-level types. To simplify matters, Soroban further limits all host functions to passing and returning values from within a single specialized form of 64-bit integers called "value" or "the value type". Through careful bit-packing, the value type can encode any of several separate types more meaningful to users than just "integers". + +Specifically, the value type can directly encode 63-bit unsigned integers (equivalent to positive signed 64-bit numbers), but also boolean true and false, signed or unsigned 32-bit integers, typed host object handles, typed error codes, small symbols (up to 10 latin-alphanumeric characters), small bitsets (up to 60 bits), or a unique void value. Individual bits in a value are allocated to tagging and switching between these cases dynamically, and host functions or objects that require specific cases may reject values of other cases. + +Since the value type can contain a handle to a host object, any container object that can contain the value type can in fact hold any object. Therefore the host map and vector types -- container data structures -- are defined merely as containers for the value type, where the specific case of each value may vary from container to container or even among the elements of a container. In this way, the host container types are more like the containers of dynamic-typed languages like JavaScript or Python. The SDK also provides static, uniformly-typed wrappers when this is desired, prohibiting values outside the designated case from being added to the container. + +![](/diagrams/environment-concepts.png) diff --git a/docs/guides/events.mdx b/docs/guides/events.mdx new file mode 100644 index 000000000..02916f069 --- /dev/null +++ b/docs/guides/events.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 6 +title: Events +--- + +Events are the mechanism that applications off-chain can use to monitor changes +and events in contracts on-chain. + +:::danger +Soroban events are under active-development and are not yet available. +::: diff --git a/docs/guides/gas-and-metering.mdx b/docs/guides/gas-and-metering.mdx new file mode 100644 index 000000000..9966da277 --- /dev/null +++ b/docs/guides/gas-and-metering.mdx @@ -0,0 +1,12 @@ +--- +sidebar_position: 8 +title: Gas and metering +--- + +Gas and metering are the mechanisms that will measure the cost of running a +contract and bill that cost to the account executing the contract. + +:::danger +Soroban gas and metering are under active-development and are not yet available. +::: + diff --git a/docs/guides/high-level-overview.mdx b/docs/guides/high-level-overview.mdx new file mode 100644 index 000000000..f43e0a979 --- /dev/null +++ b/docs/guides/high-level-overview.mdx @@ -0,0 +1,30 @@ +--- +sidebar_position: 1 +title: High level overview +--- + +## Rust language +Contracts are small programs written in the [Rust programming language](https://www.rust-lang.org). In order to write contracts, [install a Rust toolchain](https://www.rust-lang.org/tools/install), configure your [editor to support Rust programs](https://www.rust-lang.org/tools), and [learn at least some basic Rust concepts](https://www.rust-lang.org/learn). + +Contracts can be compiled to native code for local (off-chain) testing, but must be compiled as WebAssembly ("WASM") for deployment. The on-chain host environment only allows uploading WASM contracts, and runs them within a WASM "sandbox" virtual machine ("VM"). + +In practice several special characteristics of the contract execution environment -- resource constraints, security considerations, nonstandard IO and invocation primitives, the requirement for strict determinism -- will mean that contracts can only use a very narrow subset of the full Rust language, and must use specialized libraries for most tasks. See the [rust dialect](rust-dialect.mdx) section for details. + +In particular both the Rust standard library and most 3rd party libraries ("crates" in Rust parlance) will not be available for direct off-the-shelf use in contracts, due to the constraints listed above. Some crates will be possible to adapt to use in contracts, others may be incorporated into the host environment as host objects or functions. + +In the future it is possible that other source languages may be supported. The execution environment is somewhat language-agnostic, and some very early experiments suggest that other languages may be possible. However, at this time only Rust is supported. + +## SDK +Contracts are developed with the help of a Software Development Kit or SDK. The SDK consists of both a Rust crate and a command-line tool. + +The SDK crate acts as a substitute for the Rust standard library -- providing data structures and utility functions for contracts -- as well as providing access to smart-contract-specific functionality from the contract environment, like cryptographic hashing and signature verification, access to on-chain persistent storage, and location and invocation of secondary contracts via stable identifiers. + +### Local testing mode +The SDK command-line tool provides a developer-focused front-end for compiling, testing, inspecting, versioning and deploying contracts. + +The SDK also includes a _complete implementation of the contract host environment_ -- identical to the one that runs on-chain -- such that contracts can be **run locally** on a developer's workstation, and can be [tested and debugged](debugging-contracts.mdx) directly with a local debugger within a standard IDE, as well as a native test harness for fast-feedback unit testing and high-speed fuzzing or property testing. + +## Host Environment +The host environment is a set of Rust crates that are compiled into both the SDK command-line tool and stellar-core, the transaction processor at the heart of the stellar network. It comprises a set of host objects and functions, an interface to on-chain storage and contract invocation, a resource-accounting and fee-charging system, and a WASM interpreter. + +Most contract developers will not frequently need to interact with the host environment directly -- SDK functions wrap most of its facilities and provide richer and more ergonomic types and functions -- but it is helpful to understand its structure in order to understand the conceptual model the SDK is presenting. It is also likely that some parts of the host environment will be visible when testing or debugging contracts compiled natively on a local workstation. diff --git a/docs/guides/interacting-with-contracts-2.mdx b/docs/guides/interacting-with-contracts-2.mdx new file mode 100644 index 000000000..d0f9c5bf0 --- /dev/null +++ b/docs/guides/interacting-with-contracts-2.mdx @@ -0,0 +1,44 @@ +--- +sidebar_position: 4 +title: Interacting with contracts 2 +--- + +## Calling contracts + +Contracts are invoked through a pair of host functions `call` and `try_call`: + + - `try_call(contract, function, args)` calls `function` exported from `contract`, passing `args` and returning a `Status` on any error. + - `call(contract, function, args)` just calls `try_call` with its arguments and traps on `Status`, essentially propagating the error. + +In both cases `contract` is a `Binary` host object containing the contract ID, `function` is a `Symbol` holding the name of an exported function to call, and `args` is a `Vector` of values to pass as arguments. + +These host functions can be invoked in two separapte ways: + + - From outside the host, such as when a user submits a transaction that calls a contract. + - From within the host, when one contract calls another. + +Both cases follow the same logic: + + - The contract's WASM bytecode is retrieved from a `CONTRACT_DATA` ledger entry in the host's storage system. + - A WASM VM is instantiated for the duration of the invocation. + - The function is looked up and invoked, with arguments passed from caller to callee. + +When a call occurs from outside the host, any arguments will typically be provided in serialized XDR form accompanying the transaction, and will be deserialized and converted to host objects automatically before invoking the contract. + +When a call occurs from inside the host, the caller and callee contracts _share the same host_ and the caller can pass references to host objects directly to the callee without any need to serialize or deserialize them. + +Since host objects are immutable, there is limited risk to passing a shared reference from one contract to another: the callee cannot modify the object in a way that would surprise the caller, only create new objects. + +## Storage footprint and preflight + +As mentioned in the [persisting data](../learn/persisting-data) section, a contract can only load or store `CONTRACT_DATA` entries that are declared in a _footprint_ associated with its invocation. + +A footprint is a set of ledger keys, each marked as either read-only or read-write. Read-only keys are available to the transaction for reading, read-write available for reading, writing or both. + +Any transaction submitted by a user has to be accompanied by a footprint. A single footprint encompasses _all_ the data read and written by _all_ contracts transitively invoked by the transaction: not just the initial contract that the transaction calls, but also all contracts it calls, and so on. + +Since it can be difficult for a user to always know which ledger entries a given contract call will attempt to read or write -- especially those caused by contracts called by other contracts deep within a transaction -- the host provides an auxiliary **"preflight"** mechanism that executes a transaction against a temporary, possibly slightly-stale _snapshot_ of the ledger. The preflight mechanism is _not_ constrained to only read or write the contents of a footprint; rather it _records_ a footprint describing the transaction's execution, discards the execution's effects, and then returns the recorded footprint it to its caller. + +Such a preflight-provided footprint can then be used to accompany a "real" submission of the same transaction to the network for real execution. If the state of the ledger has changed too much between the time of the preflight and the real submission, the footprint may be too stale and no longer accurately identify the _keys_ the transaction needs to read and write, at which point the preflight must be retried to refresh the footprint. + +In any event -- whether successful or failing -- the real transaction will execute atomically, deterministically and with serializable consistency semantics. An inaccurate footprint simply causes deterministic transaction failure, not a stale-read anomaly. All effects of such a failed transaction are discarded, as they would be in the presence of any other error. diff --git a/docs/guides/interacting-with-contracts.mdx b/docs/guides/interacting-with-contracts.mdx new file mode 100644 index 000000000..96ea92af6 --- /dev/null +++ b/docs/guides/interacting-with-contracts.mdx @@ -0,0 +1,100 @@ +--- +sidebar_position: 4 +title: Interacting with contracts +--- + +## Three types of interactions + +### Function call + +A function call is the simplest and least expensive kind of contract +interaction. A function call does exactly what you would expect a contract call +to do in any other software development context: the contract transfers control +and data to another part of the _same_ contract. Because a function call always +transfers control to the same contract, they do not change the values returned +by `get_current_contract` and `get_invoking_contract`. A function call is the +only way to access the private methods of a contract, although it can also call +be used to access the public methods of a contract. + +To perform a function call, simply make a Rust function call. + +### Contract invocation + +A contract invocation is a more powerful and more expensive kind of contract +interaction. A contract invocation is similar to starting a new process because +the code that runs will be in a separate address space, meaning that they do +not share any data other than what was passed in the invocation. While a +contract invocation typically transfers control to a _different_ contract, it +is possible to transfer control to the currently running contract. Regardless +of whether the contract that receives control is a different contract or the +currently running contract, the value returned by `get_invoking_contract` will +be the previous value of `get_current_contract`. A contract invocation can only +access the public methods of a contract. + +If a contract contains a public function `f`, then invoking `f` can be done by +making a Rust function call to `f::invoke`. + +Some contracts, such as the token contract, only export the contract invocation +functions. In doing so, they are able to assign those functions friendly names. +For example, +[initialize](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/contract.rs#L55-L57) + +```rust +#[contractimpl(export_if = "export")] +impl TokenTrait for Token { + fn initialize(e: Env, admin: Identifier, decimal: u32, name: Binary, symbol: Binary) { +``` + +is [exported](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/lib.rs#L26) +as + +```rust +pub use crate::contract::initialize::invoke as initialize; +``` + +This function is then easily [called by the liquidity pool contract](https://github.com/stellar/soroban-examples/blob/4060d3bd5ee7846020b68ee583665a4d4cf4b315/liquidity_pool/src/lib.rs#L164-L171). + +### Operation + +An operation is the ultimate entrypoint of every contract interaction. An +operation transfers control and external data to a contract, allowing execution +to begin. + +## Interacting with contracts in tests + +[Debugging contracts](../under-the-hood/debugging-contracts.mdx) explains that +it is much more convenient to debug using native code than WASM. Given that you +are testing native code, it is tempting to interact with your contract directly +using function calls. If you attempt this approach, you will find that it +doesn't always work. Function call interactions do not set the environment into +the correct state for contract execution, so functions involving contract data +and determining the current or invoking contract will not work. + +When writing tests, it is important to always interact with contracts through +contract invocation. In a production setting, contract invocation will execute +WASM bytecode loaded from the ledger. So how does this work if you are testing +native code? You must register your contract with the environment so it knows +what functions are available and how to call them. While this sounds complex, +the `contractimpl` procedural macro automatically generates almost all of the +code to do this. All you have to do is write a small [stub](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/testutils.rs#L12-L15) +to actually call the generated code, such as + +```rust +pub fn register_test_contract(e: &Env, contract_id: &[u8; 32]) { + let contract_id = FixedBinary::from_array(e, *contract_id); + e.register_contract(&contract_id, crate::contract::Token {}); +} +``` + +Some contracts, such as the token contract, also provide a [friendlier interface](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/testutils.rs#L26-L191) +to facilitate testing. There are many ways these interfaces might make testing +easier, but one common one is to allow automatic message signing by passing a +[ed25519_dalek::Keypair](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.Keypair.html). + +Note that everything described in this section is only available if the +`testutils` feature is enabled. + +### Example + +This machinery can also be used to test multiple contracts together. For +example, the single offer contract test case [creates a token](https://github.com/stellar/soroban-examples/blob/56fef787395b5aed7cd7b19772cca28e21b3feb5/single_offer/src/test.rs#L22). diff --git a/docs/guides/persisting-data.mdx b/docs/guides/persisting-data.mdx new file mode 100644 index 000000000..263b804ad --- /dev/null +++ b/docs/guides/persisting-data.mdx @@ -0,0 +1,22 @@ +--- +sidebar_position: 5 +title: Persisting data +--- + +## Ledger entries +Contracts can access ledger entries of type `CONTRACT_DATA`. Host functions are provided to probe, read, write, and delete `CONTRACT_DATA` ledger entries. + +Each `CONTRACT_DATA` ledger entry is keyed in the ledger by the contract ID that owns it, as well as a single user-chosen value, of the standard value type. This means that the user-chosen key may be a simple value such as a symbol, number or binary blob, or it may be a more complex structured value like a vector or map with multiple sub-values. + +Each `CONTRACT_DATA` ledger entry also holds (in addition to its key) a single value associated with the key. Again, this value may be simple like a symbol or number, or may be complex like a vector or map with many sub-values. + +No serialization or deserialization is required in contract code when accessing `CONTRACT_DATA` ledger entries: the host automatically serializes and deserializes any ledger entries accessed, exchanging them with the contract as deserialized values. If a contract wishes to use a custom serialization format, it can store a binary-valued `CONTRACT_DATA` ledger entry and provide its own code to serialize and deserialize, but Soroban has been designed with the intent to minimize the need for contracts to ever do this. + +## Access Control +Contracts are only allowed to read and write `CONTRACT_DATA` ledger entries owned by the contract: those keyed by the same contract ID as the contract performing the read or write. Attempting to access other `CONTRACT_DATA` ledger entries will cause a transaction to fail. + +## Granularity +A `CONTRACT_DATA` ledger entry is read or written from the ledger in its entirety; there is no way to read or write "only a part" of a `CONTRACT_DATA` ledger entry. There is also a fixed overhead cost to accessing any `CONTRACT_DATA` ledger entry. Contracts are therefore responsible for dividing logically "large" data structures into "pieces" with an appropriate size granularity, to use for reading and writing. If pieces are too large there may be unnecessary costs paid for reading and writing unused data, as well as unnecessary contention in parallel execution; but if pieces are too small there may be unnecessary costs paid for the fixed overhead of each entry. + +## Footprints and parallel contention +Contracts are only allowed to access ledger entries specified in the footprint of their transaction. Transactions with overlapping footprints are said to contend, and will only execute sequentially with respect to one another, on a single thread. Transactions with non-overlapping footprints may execute in parallel. This means that a finer granularity of `CONTRACT_DATA` ledger entries may reduce artificial contention among transactions using a contract, and thereby increase parallelism. diff --git a/docs/guides/rust-dialect.mdx b/docs/guides/rust-dialect.mdx new file mode 100644 index 000000000..06604cecc --- /dev/null +++ b/docs/guides/rust-dialect.mdx @@ -0,0 +1,56 @@ +--- +sidebar_position: 8 +title: Contract Rust dialect +--- + +Contract development occurs in the Rust programming language, but several features of the Rust language are either unavailable in the deployment guest environment, or not recommended because their use would incur unacceptable costs at runtime. + +For this reason it makes sense to consider code written for contracts to be a _dialect_ or special variant of the Rust programming language, with certain unusual constraints and priorities, such as determinism and code size. + +These constraints and priorities are _similar_ to those encountered when writing Rust code for "embedded systems", and the tools, libraries and techniques used in the "contract dialect" are frequently borrowed from the [Rust embedded systems community](https://docs.rust-embedded.org/book/index.html), and by default contracts are recommended to be built with the [`#[no_std]` mode](https://docs.rust-embedded.org/book/intro/no-std.html) that excludes the Rust standard library entirely, relying on the smaller underlying `core` library instead. + +Note: these constraints and priorities are **not enforced when building in local-testing mode**, and in fact local contract tests will _frequently_ use facilities -- to generate test input, inspect test output, and guide testing -- that are not supported in the deployment guest environment. Developers **must understand** the difference between code that is compiled-in to WASM modules for deployment and code that is conditionally compiled for testing. See [debugging contracts](debugging-contracts.mdx) for more details. + +The "contract dialect" has the following characteristics: + +## No floating point +Floating-point arithmetic in the guest is completely prohibited. Floating-point operations in WASM have a few nondeterministic or platform-specific aspects: mainly NaN bit patterns, as well as floating-point environment settings such as rounding mode. + +While it is theoretically possible to force all floating-point code into deterministic behaviour across WASM implementations, doing so on some WASM implementations may be difficult, costly, or error-prone. To avoid the complexity, all floating-point code is rejected at instantiation time. + +This restriction may be revisited in a future version. + +## Limited (ideally zero) dynamic memory allocation +Dynamic memory allocation within the guest is **strongly** discouraged, but not completely prohibited. + +The host object and host function repertoire has been designed to relieve the guest from having to perform dynamic allocation within its own linear memory; instead, the guest is expected and intended to allocate dynamic structures _within host objects_ and interact with them using lightweight handles. + +Using host objects instead of data structures in guest memory carries numerous benefits: much higher performance, much smaller code size, interoperability between contracts, shared host support for serialization, debugging and data structure introspection. + +The guest does, however, has a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM. + +This restriction is due to the limited ability of WASM to support code-sharing: there is no standard way for the WASM sandbox to provide shared "standard library" code within a guest, such as a memory allocator, nor does the host have adequate insight into the contents of the guest's memory to provide an allocator itself. Every contract that wishes to use dynamic allocation must therefore carry its own copy of an allocator. + +Many instances where dynamic memory allocation might _seem_ to be required can also be addressed just as well with a library such as [heapless](https://docs.rs/heapless/latest/heapless/). This library (and others of its kind) provide data structures with familiar APIs that _appear_ dynamic, but are actually implemented in terms of a single stack or static allocation, with a fixed maximum size established at construction: attempts to grow the dynamic size beyond the maximum size simply fail. In the context of a contract, this can sometimes be perferable behaviour, and avoids the question of dynamic allocation entirely. + +## Non-standard I/O +All standard I/O facilities and access to the operating system that a typical Rust program would expect to perform using the Rust standard library is prohibited; programs that try to import such functions from the host through (for example) the WASI interface will fail to instantiate, since they refer to functions not provided by the host. + +No operating system, nor any simulation thereof, is present in the contract sandbox. Again, the repertoire of host objects and host functions is intended to replace and largely obviate the need for such facilities from the standard library. + +This restriction arises from the fact that contracts need to run with _stronger_ guarantees than those made by typical operating-system APIs. Specifically contracts must perform I/O with all-or-nothing, transactional semantics (relative to their successful execution or failure) as well as serializable consistency. This eliminating most APIs that would relate to typical file I/O. Furthermore contracts must be isolated from all sources of nondeterminism such as networking or process control, which eliminating most of the remaining APIs. Once files, networking and process control are gone, there simply isn't enough left in the standard operating system I/O facililties to bother trying to provide them. + +## No multithreading +Multithreading is not available. As with I/O functions, attempting to import any APIs from the host related to multithreading will fail at instantiation time. + +This restriction is similarly based on the need for contracts to run in an environment with strong determinism and serializable consistency guarantees. + +## Immediate panic +The Rust `panic!()` facility for unrecoverable errors will trap the WASM virtual machine immediately, halting execution at the instruction that traps rather than unwinding. This means that `Drop` code in Rust types will not run during a panic. This behaviour is similar to the `panic = "abort"` profile that Rust code can (and often is) compiled with. + +This is not a hard restriction enforced by the host, but a soft configuration made through a mixture of SDK functions and flags used when compiling, in the interest of minimizing code size and limiting execution costs. It can be bypassed with some effort if unwinding and `Drop` code is desired, at the cost of greatly increased code size. + +## Pure-functional collections +Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors. + +In particular: host objects are **immutable**, and often **share substructure**. They therefore resemble the data structures from pure-functional programming more closely than the typical imperative model used in many Rust programs. diff --git a/docs/guides/standard-assets-and-authorization.mdx b/docs/guides/standard-assets-and-authorization.mdx new file mode 100644 index 000000000..1096d9a7a --- /dev/null +++ b/docs/guides/standard-assets-and-authorization.mdx @@ -0,0 +1,234 @@ +--- +sidebar_position: 7 +title: Standard assets and authorization +--- + +The authorization model of Soroban is closely related to its "standard asset" contract; the two are best understood together. + +# Authorization + +Authorization is the process of judging which operations "should" or "should not" be allowed to occur; it is about judging _permission_. + +Authorization differs from _authentication_, which is the narrower problem of judging whether a person "is who they say they are", or whether a message claiming to come from a person "really" came from them. + +Authorization often uses cryptographic authentication (via signatures) to support its judgments, but is a broader, more general process. + +## Basic authorization: writing to `CONTRACT_DATA` + +The basic authorization rule is simple: each contract has an identifier, each `CONTRACT_DATA` ledger entry carries the identifier of a contract, and only the contract with the same identifier as a `CONTRACT_DATA` ledger entry can write to it. + +## Complex authorization: multiple users and the impracticality of general rules + +Authorization is complicated by the fact that contracts do not exist or execute in isolation: they record data related to multiple users and run transactions that change multiple users' data simultaneously. Each user might reasonably want (and be permitted) to modify some parts of a contract's data, but not other parts. + +We might expect the system to have a rich set of built-in authorization rules, to allow modeling individual users, their data, and the sets of data each user of a contract can or cannot modify under a variety of transactions and signatures. This is however impractical in general: each contract has complex and unforeseeable conditions governing access to its data. + +As an example, consider a contract holding accounts for users, and exposing a "transfer" operation. If a contract has ledger entries representing account balances for users A and B, then a transfer from A to B probably requires modifying the ledger entries associated with both A and B. But which transfers should be permitted? One possible rule would be to allow transfers from A to B only when A has sufficient funds and A signed the transaction; then B could not initiate the transfer nor could A overspend their balance. But that is not the only possible rule: reasonable contracts might allow "overdraft" on A's account, or could permit A to delegate to B the right to withdraw some of A's funds when necessary. + +In general, the conditions in which data associated with each user should or should-not be modified can be quite complex, and vary on a contract-by-contract basis. Indeed, one way of thinking of contracts is as _primarily_ a set of rules for authorizing changes to data. It is therefore not possible (or at least not practical) to capture all plausible authorization patterns with structured, declarative authorization rules "outside the contracts". The contracts _are_ the rules. + +Instead, we focus on facilities provided _to_ contracts to _support them_ in making authorization decisions for themselves, in their own code. + +## Tools for authorization: identities, messages and authorizations + +Several mechanisms are provided to each contract to make authorization decisions. The mechanisms fall into two categories: + + - Common data structures and functions in the SDK and "standard asset" contract. + - Host functions that assist in validating aspects of these data structures. + +### Common data structures and functions + +The common data structures involved in authorization model key concepts used in authorization judgments. They are provided (and used) by the "standard asset" contract, and form a base set of functionality that should be sufficient for expressing many authorization patterns in other contracts, as well as interacting with instances of the standard asset. + +These concepts are: + + - **Identities**: these are the parties that can initiate actions subject to authorization judgments. Identities may be one of three types: + - **Single-key users**, represented by a single Ed25519 public key + - **Account users**, represented by a reference to an existing account on the Stellar network (which stores, in an account ledger entry, a list of weighted authorized signing keys) + - **Contracts**, represented by a contract ID (not a public key) + - **Messages**: these encode a request from an identity to perform some action, such that the message can have an authorization claim made about it, and an authorization judgment applied to it. Messages include a nonce, a "domain" code number indicating the action to take, and a set of general parameters to that action. + - **Authorizations**: these are statements made _about messages_. Each authorization encodes the claim that the action described by the message is authorized to occur, on the authority of some identity. Authorizations may have three forms, corresponding to the three forms of identity: single-key, account, and contract. + +Contracts decide when a message is authorized with two separate steps: + + - Validate the provided authorization, by some mixture of checking signatures or examining the invocation context. + - Evaluate the operation requested by the message to see if it fits the contract's unique rules for that operation. + +The first step often requires host-function support. The second step is always contract-specific, and cannot be provided by the platform in general. + +### Authorization-validation host functions + +Three families of host function are provided to validate authorizations: + + - **Cryptographic validation** functions. These help validate the "single-key user" form of authorization. Specifically these functions compute SHA256 hashes and verify Ed25519 signatures. + - **Account authorization** functions. These help validate the "account user" form of authorization. Specifically these functions allow looking up the signing thresholds and weights for signing keys, as stored in existing account ledger entries in the Stellar blockchain. + - **Invoking contract** function. This helps validate the "contract" form of authorization. Specifically this function returns the contract ID of the contract that invoked the currently-executing contract. If no contract invoked the currently-executing contract, this function traps. + +This last function deserves further explanation. A contract can be invoked either from a transaction (originating outside of the host) or from a cross-contract call made by some _other_ contract. When some contract X decides to invoke some other contract Y, it is generally sufficient to consider the _fact that X called Y_ as evidence that X authorizes whatever request it is making to Y with that call. After all, if X did not wish to authorize such an invocation, it would not make it! So the only information necessary to evaluate a "contract" authorization is the identity of the (directly) invoking contract. + +# Standard Token Contract + +Tokens are a vital part of blockchains, and contracts that implement token +functionality are inevitable on any smart contract platform. Instead of +expecting a standard to emerge from the ecosystem, we provide our own token +contract implementation. This has a couple advantages. First, we can special +case this contract and run it natively instead of running in a WASM VM, reducing +the cost of using the contract. Second, we can use this native contract to allow +"classic" Stellar assets to interoperate with smart tokens. The current +iteration of the standard token contract doesn't run natively or interoperate +with "classic" Stellar assets, but these improvements will be made in the +future. + +The standard token contract is similar to the widely used ERC-20 token standard, +which should make it easier for existing smart contract developers to get +started on Stellar. + +Note that this standard token contract does not prevent the ecosystem from +developing other token contracts if the one we provide is missing functionality +they require. + +## Token contract authorization semantics + +[Public types](https://github.com/stellar/soroban-token-contract/blob/main/src/public_types.rs) referenced below for the token contract + +### Authorization parameter + +Used by `mint`, `burn`, `freeze`, `unfreeze`, and `set_admin`. These functions +assume the `Authorization` is for the admin `Identifier`, which is why there are +no keys in `Authorization`. + +### KeyedAuthorization parameter + +Used by `allowance`, `approve`, `xfer`, and `xfer_from`. `KeyedAuthorization` is +for contract functions where the user is interacting with a balance or allowance in the token +contract. The user's identifier is specified as a key for +`KeyedAuthorization::Ed25519` and `KeyedAuthorization::Account`, while +`KeyedAuthorization::Contract` implies that the invoking contract's address is +the user. + +### Signatures + +For non-Contract authorization types, both `KeyedAuthorization` and +`Authorization` will include one of more signatures. Those signatures are +derived by signing the `Message` enum, which has one value at the moment, `V0`. +`Message::V0` requires the current nonce for the Identifier providing +authorization, a +[domain](https://github.com/stellar/soroban-token-contract/blob/main/src/cryptography.rs), +and the function parameters. + +### Nonce + +The token contract stores a nonce per `Identifier`. This nonce is required on +any function that requires authorization (The Signatures section above explain +how it’s used). The current nonce for an `Identifier` can be retrieved using the +nonce contract function. + +## Contract Interface + +```rust +// Admin interface + +// Sets the administrator to "admin". Also sets some metadata +fn initialize(e: Env, admin: Identifier, decimal: u32, name: Binary, symbol: Binary); + +// If "admin" is the administrator, burn "amount" from "from" +fn burn(e: Env, admin: Authorization, from: Identifier, amount: BigInt); + +// If "admin" is the administrator, mint "amount" to "to" +fn mint(e: Env, admin: Authorization, to: Identifier, amount: BigInt); + +// If "admin" is the administrator, set the administrator to "id" +fn set_admin(e: Env, admin: Authorization, new_admin: Identifier); + +// If "admin" is the administrator, freeze "id" +fn freeze(e: Env, admin: Authorization, id: Identifier); + +// If "admin" is the administrator, unfreeze "id" +fn unfreeze(e: Env, admin: Authorization, id: Identifier); + +// Token Interface + +// Get the allowance for "spender" to transfer from "from" +fn allowance(e: Env, from: Identifier, spender: Identifier) -> BigInt; + +// Set the allowance to "amount" for "spender" to transfer from "from" +fn approve(e: Env, from: KeyedAuthorization, spender: Identifier, amount: BigInt); + +// Get the balance of "id" +fn balance(e: Env, id: Identifier) -> BigInt; + +// Transfer "amount" from "from" to "to" +fn xfer(e: Env, from: KeyedAuthorization, to: Identifier, amount: BigInt); + +// Transfer "amount" from "from" to "to", consuming the allowance of "spender" +fn xfer_from(e: Env, spender: KeyedAuthorization, from: Identifier, to: Identifier, amount: BigInt); + +// Returns true if "id" is frozen +fn is_frozen(e: Env, id: Identifier) -> bool; + +// Returns the current nonce for "id" +fn nonce(e: Env, id: Identifier) -> BigInt; + +// Descriptive Interface + +// Get the number of decimals used to represent amounts of this token +fn decimals(e: Env) -> u32; + +// Get the name for this token +fn name(e: Env) -> Binary; + +// Get the symbol for this token +fn symbol(e: Env) -> Binary; +``` + +## Running the token contract with testutils machinery +This section has more information about the testutils machinery (TODO: link to interacting-with-contracts.mdx testutils section) + +This [test +case](https://github.com/stellar/soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/tests/test.rs#L20) +shows how the token contract should be used. Note that the actual call into the +contract is in the +[Token](https://github.com/stellar/soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/src/testutils.rs#L26) +wrapper test class. + +## Signing messages + +The two +[examples](https://github.com/stellar//soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/src/testutils.rs#L55) +from the test `Token` wrapper class demonstrate how you sign a contract function that expects an `Authorization` and a `KeyedAuthorization` type. + +### Authorization +The admin must match the `Identifier` that was used to `initialize` the contract. +```rust +pub fn mint(&self, admin: &Keypair, to: &Identifier, amount: &BigInt) { + let mut args: Vec = Vec::new(&self.env); + args.push(to.clone().into_env_val(&self.env)); + args.push(amount.clone().into_env_val(&self.env)); + let msg = Message::V0(MessageV0 { + nonce: self.nonce(&to_ed25519(&self.env, admin)), + domain: Domain::Mint as u32, + parameters: args, + }); + let auth = Authorization::Ed25519(admin.sign(msg).unwrap().into_val(&self.env)); + mint(&self.env, &self.contract_id, &auth, to, amount) +} +``` + +### KeyedAuthorization +```rust + pub fn approve(&self, from: &Keypair, spender: &Identifier, amount: &BigInt) { + let mut args: Vec = Vec::new(&self.env); + args.push(spender.clone().into_env_val(&self.env)); + args.push(amount.clone().into_env_val(&self.env)); + let msg = Message::V0(MessageV0 { + nonce: self.nonce(&to_ed25519(&self.env, from)), + domain: Domain::Approve as u32, + parameters: args, + }); + let auth = KeyedAuthorization::Ed25519(KeyedEd25519Authorization { + public_key: from.public.to_bytes().into_val(&self.env), + signature: from.sign(msg).unwrap().into_val(&self.env), + }); + approve(&self.env, &self.contract_id, &auth, spender, amount) +} +``` \ No newline at end of file From beaec8621ce1d84d8d58a73c9f444b2fe1670928 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 10:58:48 -0700 Subject: [PATCH 021/248] Changes from meeting today (#40) --- docs/getting-started/build-a-wasm-file.mdx | 16 -- .../{first-project.mdx => quick-start.mdx} | 2 +- docs/guides/_category_.json | 4 - docs/guides/contract-lifecycle.mdx | 38 --- docs/guides/debugging.mdx | 42 ---- docs/guides/environment-concepts.mdx | 47 ---- docs/guides/events.mdx | 11 - docs/guides/gas-and-metering.mdx | 12 - docs/guides/high-level-overview.mdx | 30 --- docs/guides/interacting-with-contracts-2.mdx | 44 ---- docs/guides/interacting-with-contracts.mdx | 100 -------- docs/guides/persisting-data.mdx | 22 -- docs/guides/rust-dialect.mdx | 56 ----- .../standard-assets-and-authorization.mdx | 234 ------------------ docs/tutorials/_category_.json | 4 + .../build-an-optimized-wasm-file.mdx | 0 .../build-and-run-a-contract.mdx} | 20 +- docs/tutorials/create-a-project.mdx | 74 ++++++ .../testing.mdx | 0 .../write-a-contract.mdx | 0 20 files changed, 97 insertions(+), 659 deletions(-) delete mode 100644 docs/getting-started/build-a-wasm-file.mdx rename docs/getting-started/{first-project.mdx => quick-start.mdx} (99%) delete mode 100644 docs/guides/_category_.json delete mode 100644 docs/guides/contract-lifecycle.mdx delete mode 100644 docs/guides/debugging.mdx delete mode 100644 docs/guides/environment-concepts.mdx delete mode 100644 docs/guides/events.mdx delete mode 100644 docs/guides/gas-and-metering.mdx delete mode 100644 docs/guides/high-level-overview.mdx delete mode 100644 docs/guides/interacting-with-contracts-2.mdx delete mode 100644 docs/guides/interacting-with-contracts.mdx delete mode 100644 docs/guides/persisting-data.mdx delete mode 100644 docs/guides/rust-dialect.mdx delete mode 100644 docs/guides/standard-assets-and-authorization.mdx create mode 100644 docs/tutorials/_category_.json rename docs/{getting-started => tutorials}/build-an-optimized-wasm-file.mdx (100%) rename docs/{getting-started/run-a-wasm-file.mdx => tutorials/build-and-run-a-contract.mdx} (63%) create mode 100644 docs/tutorials/create-a-project.mdx rename docs/{getting-started => tutorials}/testing.mdx (100%) rename docs/{getting-started => tutorials}/write-a-contract.mdx (100%) diff --git a/docs/getting-started/build-a-wasm-file.mdx b/docs/getting-started/build-a-wasm-file.mdx deleted file mode 100644 index 2855ef6a7..000000000 --- a/docs/getting-started/build-a-wasm-file.mdx +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_position: 6 -title: Build a WASM File ---- - -To build a Soroban contract into a `.wasm` file, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file should be outputted in the `target` directory: - -``` -target/wasm32-unknown-unknown/release/[project-name].wasm -``` diff --git a/docs/getting-started/first-project.mdx b/docs/getting-started/quick-start.mdx similarity index 99% rename from docs/getting-started/first-project.mdx rename to docs/getting-started/quick-start.mdx index 8d409146e..af2c42b02 100644 --- a/docs/getting-started/first-project.mdx +++ b/docs/getting-started/quick-start.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 3 -title: First Project +title: Quick Start --- Once you've [Setup] your development environment, you're ready to create your diff --git a/docs/guides/_category_.json b/docs/guides/_category_.json deleted file mode 100644 index 1ba237c2d..000000000 --- a/docs/guides/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "position": 5, - "label": "Guides" -} diff --git a/docs/guides/contract-lifecycle.mdx b/docs/guides/contract-lifecycle.mdx deleted file mode 100644 index b35189a57..000000000 --- a/docs/guides/contract-lifecycle.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -sidebar_position: 3 -title: Contract Lifecycle ---- - -## Development -Contract development can be done on a local computer with as little as 3 necessary components: an IDE, a copy of the Rust toolchain, and a copy of the Soroban SDK. - -The SDK contains a full working copy of the host environment, as well as a "mock" version of the ledger for persistent storage of contract data. It is therefore possible (and encouraged) to edit, compile, test and debug contracts directly against this "local" copy of the host, entirely offline and without even accessing a test network. - -To make the local development process even more convenient and fast, the contract being developed can (and should) be compiled as native code and linked directly to the local host, rather than compiled to WASM and run in a local VM sandbox. Both configurations are possible, but the native configuration is fastest and provides the richest testing and debugging experience. - -The SDK-provided local contract host also contains a local web server that serves the necessary HTTP API endpoint used for client applications to interact with a contract. This can be used for local development of applications, again without needing to deploy contracts to any test or live network. -## Deployment -Once a contract has been tested and debugged locally, it can be deployed. To do this it must be compiled to WASM code, and then included by value in a transaction sent to the intended deployment network. - -The SDK provides a command-line utility that invokes the Rust compiler with the correct settings for producing a WASM bundle for deployment, but developers can also build this themselves. - -Before submitting to the network, developers should inspect the resulting WASM binary emitted by the Rust compiler to ensure that it contains only the intended code and data, and is as small as possible. The SDK command-line utility contains diagnostic commands to assist with this process. - -The SDK command-line utility can also build and submit the transaction deploying a WASM contract to the network. Deployment requires sufficient network credentials to sign a transaction performing the deployment and pay its fees. Contracts should be deployed to test networks and thoroughly tested there being deployed to the live network. -## Execution -Deployed contracts live on chain in a CONTRACT_DATA ledger entry. They are executed within a VM sandbox managed by a host environment inside stellar-core. Each transaction that leads to a contract execution is run in a separate host environment, and each contract called by such a transaction (either directly or indirectly from another contract) is executed in a separate guest WASM VM contained within the transaction’s host environment. - -Execution is initiated by a host function called "call". The "call" host function can itself be invoked two different ways: either by someone submitting a transaction to the network that invokes "call" directly, or indirectly by some other contract invoking "call". - -In either case, the "call" host function is provided with the ID of a contract to invoke, the name of a function in the contract, and a vector of argument values to pass. The "call" host function then sets up a VM sandbox for the called contract, loads and instantiates its WASM bytecode, and invokes the named function, passing the provided arguments. - -Each contract execution continues until the contract either completes successfully or traps with an error condition. If execution completes successfully, all ledger entries modified during execution will be written back to the ledger atomically. If execution traps, all modified ledger entries will be discarded and the contract will have no effect on the ledger. - -A variety of conditions in either the guest or host environments can cause a contract to trap. If a host function is called with invalid arguments, for example, the host will trap. Similarly if the contract performs an erroneous WASM bytecode such as a division by zero or access to memory out of bounds, the WASM VM will trap. Also if the contract uses more resources than its enclosing transaction has paid for, the contract will trap. -## Monitoring -Contracts can be monitored in two main ways: by observing events emitted during their execution, and by examining the ledger entries written by them. - -TBD: expand this section. - -## Upgrading contracts -TBD: depends on decisions pending in CAPs. diff --git a/docs/guides/debugging.mdx b/docs/guides/debugging.mdx deleted file mode 100644 index 5fc2b5ed6..000000000 --- a/docs/guides/debugging.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -sidebar_position: 9 -title: Debugging ---- - -Soroban contracts are as much as possible regular Rust programs and can be debugged using the same tools you'd usually use. - -The debugging facilities available differ significantly depending on whether a contract is compiled natively for local testing, or compiled into WASM for deployment. - -Deciding between these two modes and making the most of them while debugging requires a **careful understanding** of which code is compiled-in to deployed contracts and which code is only available for local testing. - -## Local-testing mode - -It is possible (and encouraged during development) to compile Soroban contracts **natively** (eg. as x86-64 or AArch64 code) and link against the host environment **directly**, such that the contract is not a guest running in a WASM virtual machine at all: it is simply one native library calling another -- its host -- and both host and contract are linked together as a single program, together with a test harness. - -This configuration is referred to as **"local-testing mode"** and since it eliminates the WASM virtual machine from the debugging experience it has many advantages: - - - Tests run much faster since there is no VM interpreting them, and will execute in parallel by default on multiple threads. - - Tests can use numerous standard testing and debugging techniques: - - [The standard Rust `#[test]` harness](https://doc.rust-lang.org/reference/attributes/testing.html), including push-button IDE support for running and re-running single tests. - - [Standard IDE-supported debuggers](https://code.visualstudio.com/docs/languages/rust#_debugging), including IDE support for setting breakpoints and inspecting values in both contract and host. - - Lightweight debugging via [standard logging](https://docs.rs/log/latest/log/) or [tracing](https://docs.rs/tracing/latest/tracing/). - - Systematic testing such as [fuzzing](https://crates.io/crates/cargo-fuzz), [property-testing](https://crates.io/crates/proptest), or even [model checking](https://crates.io/crates/kani-verifier) or [formal verification](https://github.com/xldenis/creusot). - - The simplest of all debugging approaches, [printing to standard error](https://doc.rust-lang.org/std/macro.eprintln.html). - -Local-testing mode is the **default** configuration when compiling code targeting your local computer's CPU and operating system, which is what cargo will do if you set up a new Rust project and don't specify a target. - -## WASM mode - -If on the other hand you wish to compile for deployment, you must tell cargo to build for the WASM target. - -Building for WASM will _disable_ many of the debugging facilities described above, typically for one of three reasons: - - - The WASM VM simply can't (or the VM we've chosen doesn't) provide them. - - The WASM VM _could_ provide them but doing so would violate constraints of the [contract Rust dialect](rust-dialect.mdx). - - The WASM VM _could_ provide them but doing so would make the resulting WASM code impractically large. - -While we encourage most testing to happen in local-testing mode, some problems will obviously only arise in deployment and some debugging facilities thus remain available even there: - - - A "sandbox" host with a mock-ledger that can read and write `CONTRACT_DATA` ledger entries to the local filesystem. - - A general logging system that allows contracts to log values of the [shared host/guest "value" type](environment-concepts.mdx), even in production. - - User-extensible `Status` codes that can be returned from any contract call to indicate problems. diff --git a/docs/guides/environment-concepts.mdx b/docs/guides/environment-concepts.mdx deleted file mode 100644 index fee24f854..000000000 --- a/docs/guides/environment-concepts.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 2 -title: Environment Concepts ---- - -The contract environment is an _interface_ that defines the facilities -- objects, functions, data sources, etc. -- available to contracts. - -## Host and Guest -As an interface, the environment has two sides, which we refer to as the host environment and the guest environment. Code in the host environment _implements_ the environment interface; code in the guest environment _uses_ the environment interface. - -The **host environment** is provided by a known set of Rust crates, compiled once into stellar-core (or the SDK). Multiple contracts interact with the same host environment, and the host environment has access to any facilities of its enclosing operating system: files, networking, memory, etc. - -In contrast, a new **guest environment** is established for each invocation of each smart contract. Each contract sees a single environment interface, and can only call functions provided by the environment interface. In other words, the guest environment is a sandbox for executing arbitrary code within safe parameters. - -## WebAssembly -The on-chain guest environment is isolated inside a WebAssembly (WASM) virtual machine ("VM"). This means that deployed contract code is compiled to WASM bytecode rather than native machine code. The host environment includes an interpreter for the VM, and a new short-lived VM is instantiated for each call to a contract, running the bytecode for the contract and then exiting. - -The use of a VM helps provide security against any potential guest-code misbehavior, to both host and other guest environments, as well as ensuring portability of guest code between hosts running on different types of hardware. - -When developing and testing contract code off-chain, it is possible to compile contract code to native machine code rather than WASM bytecode, and to [run tests and debug contracts](debugging-contracts.mdx) against a local copy of the host environment by linking directly to it, rather than executing within a VM. This configuration runs much faster and provides much better debugging information, but is only possible locally, off-chain. On-chain deployed contracts are always WASM. - -WebAssembly is a relatively low-level VM, which means that it does not provide a very rich set of standard or "built-in" operations. In contrast to VMs like the JVM, it has no garbage collector (not even a memory allocator), no IO facilities, no standard data structures like lists, arrays, maps or strings, no concepts of objects or types at all besides basic machine types like 32 and 64-bit integers. - -As a result, programs compiled to WASM bytecode often face a dilemma: if they want rich standard functionality, they must often include a copy of all the "support code" for that functionality within themselves. But if they do, they dramatically increase their code size, which incurs costs and limits performance. Moreover, including such support code limits their ability to interoperate with other programs that may include different, incompatible support code. - -The way out of this dilemma is for the environment itself to provide support code for rich standard functionality, in the form of host objects and functions that guest code can use by reference. Each contract refers to the same functionality implemented in the host, ensuring much smaller code size, higher performance, and greater interoperability between contracts. This is what Soroban does. - -## Host objects and functions -Shared, standard functionality available to all contract guest code is provided through the environment interface in terms of host objects and host functions. - -The environment supports a small number of types of host objects covering data structures like vectors, maps, binary blobs, and arbitrary precision numbers. Host objects are all immutable, are allocated and reside within the host environment, and are only available in the guest environment by reference. Guest code refers to host objects by integer-valued handles. - -There is also a slightly larger set of host functions that act on host objects: creating, modifying, inspecting and manipulating them. Some host functions allow copying blocks of binary data into and out of the VM memory of the guest, and some host functions perform cryptographic operations on host objects. - -There are also host functions for interacting with select components of the host environment beyond the host object repertoire, such as reading and writing ledger entries, emitting events, calling other contracts, and accessing information about the transaction context in which guest code is executing. - -### Serialization -Host objects can be passed (by handle) directly to storage routines or between collaborating contracts. **No serialization or deserialization code needs to exist in the guest**: the host knows how to serialize and deserialize all of its object types and does so transparently whenever necessary. - -## Values and types -All host functions can accept as arguments and return values from, at most, the limited WASM VM repertoire of machine-level types. To simplify matters, Soroban further limits all host functions to passing and returning values from within a single specialized form of 64-bit integers called "value" or "the value type". Through careful bit-packing, the value type can encode any of several separate types more meaningful to users than just "integers". - -Specifically, the value type can directly encode 63-bit unsigned integers (equivalent to positive signed 64-bit numbers), but also boolean true and false, signed or unsigned 32-bit integers, typed host object handles, typed error codes, small symbols (up to 10 latin-alphanumeric characters), small bitsets (up to 60 bits), or a unique void value. Individual bits in a value are allocated to tagging and switching between these cases dynamically, and host functions or objects that require specific cases may reject values of other cases. - -Since the value type can contain a handle to a host object, any container object that can contain the value type can in fact hold any object. Therefore the host map and vector types -- container data structures -- are defined merely as containers for the value type, where the specific case of each value may vary from container to container or even among the elements of a container. In this way, the host container types are more like the containers of dynamic-typed languages like JavaScript or Python. The SDK also provides static, uniformly-typed wrappers when this is desired, prohibiting values outside the designated case from being added to the container. - -![](/diagrams/environment-concepts.png) diff --git a/docs/guides/events.mdx b/docs/guides/events.mdx deleted file mode 100644 index 02916f069..000000000 --- a/docs/guides/events.mdx +++ /dev/null @@ -1,11 +0,0 @@ ---- -sidebar_position: 6 -title: Events ---- - -Events are the mechanism that applications off-chain can use to monitor changes -and events in contracts on-chain. - -:::danger -Soroban events are under active-development and are not yet available. -::: diff --git a/docs/guides/gas-and-metering.mdx b/docs/guides/gas-and-metering.mdx deleted file mode 100644 index 9966da277..000000000 --- a/docs/guides/gas-and-metering.mdx +++ /dev/null @@ -1,12 +0,0 @@ ---- -sidebar_position: 8 -title: Gas and metering ---- - -Gas and metering are the mechanisms that will measure the cost of running a -contract and bill that cost to the account executing the contract. - -:::danger -Soroban gas and metering are under active-development and are not yet available. -::: - diff --git a/docs/guides/high-level-overview.mdx b/docs/guides/high-level-overview.mdx deleted file mode 100644 index f43e0a979..000000000 --- a/docs/guides/high-level-overview.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -sidebar_position: 1 -title: High level overview ---- - -## Rust language -Contracts are small programs written in the [Rust programming language](https://www.rust-lang.org). In order to write contracts, [install a Rust toolchain](https://www.rust-lang.org/tools/install), configure your [editor to support Rust programs](https://www.rust-lang.org/tools), and [learn at least some basic Rust concepts](https://www.rust-lang.org/learn). - -Contracts can be compiled to native code for local (off-chain) testing, but must be compiled as WebAssembly ("WASM") for deployment. The on-chain host environment only allows uploading WASM contracts, and runs them within a WASM "sandbox" virtual machine ("VM"). - -In practice several special characteristics of the contract execution environment -- resource constraints, security considerations, nonstandard IO and invocation primitives, the requirement for strict determinism -- will mean that contracts can only use a very narrow subset of the full Rust language, and must use specialized libraries for most tasks. See the [rust dialect](rust-dialect.mdx) section for details. - -In particular both the Rust standard library and most 3rd party libraries ("crates" in Rust parlance) will not be available for direct off-the-shelf use in contracts, due to the constraints listed above. Some crates will be possible to adapt to use in contracts, others may be incorporated into the host environment as host objects or functions. - -In the future it is possible that other source languages may be supported. The execution environment is somewhat language-agnostic, and some very early experiments suggest that other languages may be possible. However, at this time only Rust is supported. - -## SDK -Contracts are developed with the help of a Software Development Kit or SDK. The SDK consists of both a Rust crate and a command-line tool. - -The SDK crate acts as a substitute for the Rust standard library -- providing data structures and utility functions for contracts -- as well as providing access to smart-contract-specific functionality from the contract environment, like cryptographic hashing and signature verification, access to on-chain persistent storage, and location and invocation of secondary contracts via stable identifiers. - -### Local testing mode -The SDK command-line tool provides a developer-focused front-end for compiling, testing, inspecting, versioning and deploying contracts. - -The SDK also includes a _complete implementation of the contract host environment_ -- identical to the one that runs on-chain -- such that contracts can be **run locally** on a developer's workstation, and can be [tested and debugged](debugging-contracts.mdx) directly with a local debugger within a standard IDE, as well as a native test harness for fast-feedback unit testing and high-speed fuzzing or property testing. - -## Host Environment -The host environment is a set of Rust crates that are compiled into both the SDK command-line tool and stellar-core, the transaction processor at the heart of the stellar network. It comprises a set of host objects and functions, an interface to on-chain storage and contract invocation, a resource-accounting and fee-charging system, and a WASM interpreter. - -Most contract developers will not frequently need to interact with the host environment directly -- SDK functions wrap most of its facilities and provide richer and more ergonomic types and functions -- but it is helpful to understand its structure in order to understand the conceptual model the SDK is presenting. It is also likely that some parts of the host environment will be visible when testing or debugging contracts compiled natively on a local workstation. diff --git a/docs/guides/interacting-with-contracts-2.mdx b/docs/guides/interacting-with-contracts-2.mdx deleted file mode 100644 index d0f9c5bf0..000000000 --- a/docs/guides/interacting-with-contracts-2.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -sidebar_position: 4 -title: Interacting with contracts 2 ---- - -## Calling contracts - -Contracts are invoked through a pair of host functions `call` and `try_call`: - - - `try_call(contract, function, args)` calls `function` exported from `contract`, passing `args` and returning a `Status` on any error. - - `call(contract, function, args)` just calls `try_call` with its arguments and traps on `Status`, essentially propagating the error. - -In both cases `contract` is a `Binary` host object containing the contract ID, `function` is a `Symbol` holding the name of an exported function to call, and `args` is a `Vector` of values to pass as arguments. - -These host functions can be invoked in two separapte ways: - - - From outside the host, such as when a user submits a transaction that calls a contract. - - From within the host, when one contract calls another. - -Both cases follow the same logic: - - - The contract's WASM bytecode is retrieved from a `CONTRACT_DATA` ledger entry in the host's storage system. - - A WASM VM is instantiated for the duration of the invocation. - - The function is looked up and invoked, with arguments passed from caller to callee. - -When a call occurs from outside the host, any arguments will typically be provided in serialized XDR form accompanying the transaction, and will be deserialized and converted to host objects automatically before invoking the contract. - -When a call occurs from inside the host, the caller and callee contracts _share the same host_ and the caller can pass references to host objects directly to the callee without any need to serialize or deserialize them. - -Since host objects are immutable, there is limited risk to passing a shared reference from one contract to another: the callee cannot modify the object in a way that would surprise the caller, only create new objects. - -## Storage footprint and preflight - -As mentioned in the [persisting data](../learn/persisting-data) section, a contract can only load or store `CONTRACT_DATA` entries that are declared in a _footprint_ associated with its invocation. - -A footprint is a set of ledger keys, each marked as either read-only or read-write. Read-only keys are available to the transaction for reading, read-write available for reading, writing or both. - -Any transaction submitted by a user has to be accompanied by a footprint. A single footprint encompasses _all_ the data read and written by _all_ contracts transitively invoked by the transaction: not just the initial contract that the transaction calls, but also all contracts it calls, and so on. - -Since it can be difficult for a user to always know which ledger entries a given contract call will attempt to read or write -- especially those caused by contracts called by other contracts deep within a transaction -- the host provides an auxiliary **"preflight"** mechanism that executes a transaction against a temporary, possibly slightly-stale _snapshot_ of the ledger. The preflight mechanism is _not_ constrained to only read or write the contents of a footprint; rather it _records_ a footprint describing the transaction's execution, discards the execution's effects, and then returns the recorded footprint it to its caller. - -Such a preflight-provided footprint can then be used to accompany a "real" submission of the same transaction to the network for real execution. If the state of the ledger has changed too much between the time of the preflight and the real submission, the footprint may be too stale and no longer accurately identify the _keys_ the transaction needs to read and write, at which point the preflight must be retried to refresh the footprint. - -In any event -- whether successful or failing -- the real transaction will execute atomically, deterministically and with serializable consistency semantics. An inaccurate footprint simply causes deterministic transaction failure, not a stale-read anomaly. All effects of such a failed transaction are discarded, as they would be in the presence of any other error. diff --git a/docs/guides/interacting-with-contracts.mdx b/docs/guides/interacting-with-contracts.mdx deleted file mode 100644 index 96ea92af6..000000000 --- a/docs/guides/interacting-with-contracts.mdx +++ /dev/null @@ -1,100 +0,0 @@ ---- -sidebar_position: 4 -title: Interacting with contracts ---- - -## Three types of interactions - -### Function call - -A function call is the simplest and least expensive kind of contract -interaction. A function call does exactly what you would expect a contract call -to do in any other software development context: the contract transfers control -and data to another part of the _same_ contract. Because a function call always -transfers control to the same contract, they do not change the values returned -by `get_current_contract` and `get_invoking_contract`. A function call is the -only way to access the private methods of a contract, although it can also call -be used to access the public methods of a contract. - -To perform a function call, simply make a Rust function call. - -### Contract invocation - -A contract invocation is a more powerful and more expensive kind of contract -interaction. A contract invocation is similar to starting a new process because -the code that runs will be in a separate address space, meaning that they do -not share any data other than what was passed in the invocation. While a -contract invocation typically transfers control to a _different_ contract, it -is possible to transfer control to the currently running contract. Regardless -of whether the contract that receives control is a different contract or the -currently running contract, the value returned by `get_invoking_contract` will -be the previous value of `get_current_contract`. A contract invocation can only -access the public methods of a contract. - -If a contract contains a public function `f`, then invoking `f` can be done by -making a Rust function call to `f::invoke`. - -Some contracts, such as the token contract, only export the contract invocation -functions. In doing so, they are able to assign those functions friendly names. -For example, -[initialize](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/contract.rs#L55-L57) - -```rust -#[contractimpl(export_if = "export")] -impl TokenTrait for Token { - fn initialize(e: Env, admin: Identifier, decimal: u32, name: Binary, symbol: Binary) { -``` - -is [exported](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/lib.rs#L26) -as - -```rust -pub use crate::contract::initialize::invoke as initialize; -``` - -This function is then easily [called by the liquidity pool contract](https://github.com/stellar/soroban-examples/blob/4060d3bd5ee7846020b68ee583665a4d4cf4b315/liquidity_pool/src/lib.rs#L164-L171). - -### Operation - -An operation is the ultimate entrypoint of every contract interaction. An -operation transfers control and external data to a contract, allowing execution -to begin. - -## Interacting with contracts in tests - -[Debugging contracts](../under-the-hood/debugging-contracts.mdx) explains that -it is much more convenient to debug using native code than WASM. Given that you -are testing native code, it is tempting to interact with your contract directly -using function calls. If you attempt this approach, you will find that it -doesn't always work. Function call interactions do not set the environment into -the correct state for contract execution, so functions involving contract data -and determining the current or invoking contract will not work. - -When writing tests, it is important to always interact with contracts through -contract invocation. In a production setting, contract invocation will execute -WASM bytecode loaded from the ledger. So how does this work if you are testing -native code? You must register your contract with the environment so it knows -what functions are available and how to call them. While this sounds complex, -the `contractimpl` procedural macro automatically generates almost all of the -code to do this. All you have to do is write a small [stub](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/testutils.rs#L12-L15) -to actually call the generated code, such as - -```rust -pub fn register_test_contract(e: &Env, contract_id: &[u8; 32]) { - let contract_id = FixedBinary::from_array(e, *contract_id); - e.register_contract(&contract_id, crate::contract::Token {}); -} -``` - -Some contracts, such as the token contract, also provide a [friendlier interface](https://github.com/stellar/soroban-token-contract/blob/42380647bb817bf01c739c19286f18be881e0e41/src/testutils.rs#L26-L191) -to facilitate testing. There are many ways these interfaces might make testing -easier, but one common one is to allow automatic message signing by passing a -[ed25519_dalek::Keypair](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.Keypair.html). - -Note that everything described in this section is only available if the -`testutils` feature is enabled. - -### Example - -This machinery can also be used to test multiple contracts together. For -example, the single offer contract test case [creates a token](https://github.com/stellar/soroban-examples/blob/56fef787395b5aed7cd7b19772cca28e21b3feb5/single_offer/src/test.rs#L22). diff --git a/docs/guides/persisting-data.mdx b/docs/guides/persisting-data.mdx deleted file mode 100644 index 263b804ad..000000000 --- a/docs/guides/persisting-data.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -sidebar_position: 5 -title: Persisting data ---- - -## Ledger entries -Contracts can access ledger entries of type `CONTRACT_DATA`. Host functions are provided to probe, read, write, and delete `CONTRACT_DATA` ledger entries. - -Each `CONTRACT_DATA` ledger entry is keyed in the ledger by the contract ID that owns it, as well as a single user-chosen value, of the standard value type. This means that the user-chosen key may be a simple value such as a symbol, number or binary blob, or it may be a more complex structured value like a vector or map with multiple sub-values. - -Each `CONTRACT_DATA` ledger entry also holds (in addition to its key) a single value associated with the key. Again, this value may be simple like a symbol or number, or may be complex like a vector or map with many sub-values. - -No serialization or deserialization is required in contract code when accessing `CONTRACT_DATA` ledger entries: the host automatically serializes and deserializes any ledger entries accessed, exchanging them with the contract as deserialized values. If a contract wishes to use a custom serialization format, it can store a binary-valued `CONTRACT_DATA` ledger entry and provide its own code to serialize and deserialize, but Soroban has been designed with the intent to minimize the need for contracts to ever do this. - -## Access Control -Contracts are only allowed to read and write `CONTRACT_DATA` ledger entries owned by the contract: those keyed by the same contract ID as the contract performing the read or write. Attempting to access other `CONTRACT_DATA` ledger entries will cause a transaction to fail. - -## Granularity -A `CONTRACT_DATA` ledger entry is read or written from the ledger in its entirety; there is no way to read or write "only a part" of a `CONTRACT_DATA` ledger entry. There is also a fixed overhead cost to accessing any `CONTRACT_DATA` ledger entry. Contracts are therefore responsible for dividing logically "large" data structures into "pieces" with an appropriate size granularity, to use for reading and writing. If pieces are too large there may be unnecessary costs paid for reading and writing unused data, as well as unnecessary contention in parallel execution; but if pieces are too small there may be unnecessary costs paid for the fixed overhead of each entry. - -## Footprints and parallel contention -Contracts are only allowed to access ledger entries specified in the footprint of their transaction. Transactions with overlapping footprints are said to contend, and will only execute sequentially with respect to one another, on a single thread. Transactions with non-overlapping footprints may execute in parallel. This means that a finer granularity of `CONTRACT_DATA` ledger entries may reduce artificial contention among transactions using a contract, and thereby increase parallelism. diff --git a/docs/guides/rust-dialect.mdx b/docs/guides/rust-dialect.mdx deleted file mode 100644 index 06604cecc..000000000 --- a/docs/guides/rust-dialect.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -sidebar_position: 8 -title: Contract Rust dialect ---- - -Contract development occurs in the Rust programming language, but several features of the Rust language are either unavailable in the deployment guest environment, or not recommended because their use would incur unacceptable costs at runtime. - -For this reason it makes sense to consider code written for contracts to be a _dialect_ or special variant of the Rust programming language, with certain unusual constraints and priorities, such as determinism and code size. - -These constraints and priorities are _similar_ to those encountered when writing Rust code for "embedded systems", and the tools, libraries and techniques used in the "contract dialect" are frequently borrowed from the [Rust embedded systems community](https://docs.rust-embedded.org/book/index.html), and by default contracts are recommended to be built with the [`#[no_std]` mode](https://docs.rust-embedded.org/book/intro/no-std.html) that excludes the Rust standard library entirely, relying on the smaller underlying `core` library instead. - -Note: these constraints and priorities are **not enforced when building in local-testing mode**, and in fact local contract tests will _frequently_ use facilities -- to generate test input, inspect test output, and guide testing -- that are not supported in the deployment guest environment. Developers **must understand** the difference between code that is compiled-in to WASM modules for deployment and code that is conditionally compiled for testing. See [debugging contracts](debugging-contracts.mdx) for more details. - -The "contract dialect" has the following characteristics: - -## No floating point -Floating-point arithmetic in the guest is completely prohibited. Floating-point operations in WASM have a few nondeterministic or platform-specific aspects: mainly NaN bit patterns, as well as floating-point environment settings such as rounding mode. - -While it is theoretically possible to force all floating-point code into deterministic behaviour across WASM implementations, doing so on some WASM implementations may be difficult, costly, or error-prone. To avoid the complexity, all floating-point code is rejected at instantiation time. - -This restriction may be revisited in a future version. - -## Limited (ideally zero) dynamic memory allocation -Dynamic memory allocation within the guest is **strongly** discouraged, but not completely prohibited. - -The host object and host function repertoire has been designed to relieve the guest from having to perform dynamic allocation within its own linear memory; instead, the guest is expected and intended to allocate dynamic structures _within host objects_ and interact with them using lightweight handles. - -Using host objects instead of data structures in guest memory carries numerous benefits: much higher performance, much smaller code size, interoperability between contracts, shared host support for serialization, debugging and data structure introspection. - -The guest does, however, has a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM. - -This restriction is due to the limited ability of WASM to support code-sharing: there is no standard way for the WASM sandbox to provide shared "standard library" code within a guest, such as a memory allocator, nor does the host have adequate insight into the contents of the guest's memory to provide an allocator itself. Every contract that wishes to use dynamic allocation must therefore carry its own copy of an allocator. - -Many instances where dynamic memory allocation might _seem_ to be required can also be addressed just as well with a library such as [heapless](https://docs.rs/heapless/latest/heapless/). This library (and others of its kind) provide data structures with familiar APIs that _appear_ dynamic, but are actually implemented in terms of a single stack or static allocation, with a fixed maximum size established at construction: attempts to grow the dynamic size beyond the maximum size simply fail. In the context of a contract, this can sometimes be perferable behaviour, and avoids the question of dynamic allocation entirely. - -## Non-standard I/O -All standard I/O facilities and access to the operating system that a typical Rust program would expect to perform using the Rust standard library is prohibited; programs that try to import such functions from the host through (for example) the WASI interface will fail to instantiate, since they refer to functions not provided by the host. - -No operating system, nor any simulation thereof, is present in the contract sandbox. Again, the repertoire of host objects and host functions is intended to replace and largely obviate the need for such facilities from the standard library. - -This restriction arises from the fact that contracts need to run with _stronger_ guarantees than those made by typical operating-system APIs. Specifically contracts must perform I/O with all-or-nothing, transactional semantics (relative to their successful execution or failure) as well as serializable consistency. This eliminating most APIs that would relate to typical file I/O. Furthermore contracts must be isolated from all sources of nondeterminism such as networking or process control, which eliminating most of the remaining APIs. Once files, networking and process control are gone, there simply isn't enough left in the standard operating system I/O facililties to bother trying to provide them. - -## No multithreading -Multithreading is not available. As with I/O functions, attempting to import any APIs from the host related to multithreading will fail at instantiation time. - -This restriction is similarly based on the need for contracts to run in an environment with strong determinism and serializable consistency guarantees. - -## Immediate panic -The Rust `panic!()` facility for unrecoverable errors will trap the WASM virtual machine immediately, halting execution at the instruction that traps rather than unwinding. This means that `Drop` code in Rust types will not run during a panic. This behaviour is similar to the `panic = "abort"` profile that Rust code can (and often is) compiled with. - -This is not a hard restriction enforced by the host, but a soft configuration made through a mixture of SDK functions and flags used when compiling, in the interest of minimizing code size and limiting execution costs. It can be bypassed with some effort if unwinding and `Drop` code is desired, at the cost of greatly increased code size. - -## Pure-functional collections -Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors. - -In particular: host objects are **immutable**, and often **share substructure**. They therefore resemble the data structures from pure-functional programming more closely than the typical imperative model used in many Rust programs. diff --git a/docs/guides/standard-assets-and-authorization.mdx b/docs/guides/standard-assets-and-authorization.mdx deleted file mode 100644 index 1096d9a7a..000000000 --- a/docs/guides/standard-assets-and-authorization.mdx +++ /dev/null @@ -1,234 +0,0 @@ ---- -sidebar_position: 7 -title: Standard assets and authorization ---- - -The authorization model of Soroban is closely related to its "standard asset" contract; the two are best understood together. - -# Authorization - -Authorization is the process of judging which operations "should" or "should not" be allowed to occur; it is about judging _permission_. - -Authorization differs from _authentication_, which is the narrower problem of judging whether a person "is who they say they are", or whether a message claiming to come from a person "really" came from them. - -Authorization often uses cryptographic authentication (via signatures) to support its judgments, but is a broader, more general process. - -## Basic authorization: writing to `CONTRACT_DATA` - -The basic authorization rule is simple: each contract has an identifier, each `CONTRACT_DATA` ledger entry carries the identifier of a contract, and only the contract with the same identifier as a `CONTRACT_DATA` ledger entry can write to it. - -## Complex authorization: multiple users and the impracticality of general rules - -Authorization is complicated by the fact that contracts do not exist or execute in isolation: they record data related to multiple users and run transactions that change multiple users' data simultaneously. Each user might reasonably want (and be permitted) to modify some parts of a contract's data, but not other parts. - -We might expect the system to have a rich set of built-in authorization rules, to allow modeling individual users, their data, and the sets of data each user of a contract can or cannot modify under a variety of transactions and signatures. This is however impractical in general: each contract has complex and unforeseeable conditions governing access to its data. - -As an example, consider a contract holding accounts for users, and exposing a "transfer" operation. If a contract has ledger entries representing account balances for users A and B, then a transfer from A to B probably requires modifying the ledger entries associated with both A and B. But which transfers should be permitted? One possible rule would be to allow transfers from A to B only when A has sufficient funds and A signed the transaction; then B could not initiate the transfer nor could A overspend their balance. But that is not the only possible rule: reasonable contracts might allow "overdraft" on A's account, or could permit A to delegate to B the right to withdraw some of A's funds when necessary. - -In general, the conditions in which data associated with each user should or should-not be modified can be quite complex, and vary on a contract-by-contract basis. Indeed, one way of thinking of contracts is as _primarily_ a set of rules for authorizing changes to data. It is therefore not possible (or at least not practical) to capture all plausible authorization patterns with structured, declarative authorization rules "outside the contracts". The contracts _are_ the rules. - -Instead, we focus on facilities provided _to_ contracts to _support them_ in making authorization decisions for themselves, in their own code. - -## Tools for authorization: identities, messages and authorizations - -Several mechanisms are provided to each contract to make authorization decisions. The mechanisms fall into two categories: - - - Common data structures and functions in the SDK and "standard asset" contract. - - Host functions that assist in validating aspects of these data structures. - -### Common data structures and functions - -The common data structures involved in authorization model key concepts used in authorization judgments. They are provided (and used) by the "standard asset" contract, and form a base set of functionality that should be sufficient for expressing many authorization patterns in other contracts, as well as interacting with instances of the standard asset. - -These concepts are: - - - **Identities**: these are the parties that can initiate actions subject to authorization judgments. Identities may be one of three types: - - **Single-key users**, represented by a single Ed25519 public key - - **Account users**, represented by a reference to an existing account on the Stellar network (which stores, in an account ledger entry, a list of weighted authorized signing keys) - - **Contracts**, represented by a contract ID (not a public key) - - **Messages**: these encode a request from an identity to perform some action, such that the message can have an authorization claim made about it, and an authorization judgment applied to it. Messages include a nonce, a "domain" code number indicating the action to take, and a set of general parameters to that action. - - **Authorizations**: these are statements made _about messages_. Each authorization encodes the claim that the action described by the message is authorized to occur, on the authority of some identity. Authorizations may have three forms, corresponding to the three forms of identity: single-key, account, and contract. - -Contracts decide when a message is authorized with two separate steps: - - - Validate the provided authorization, by some mixture of checking signatures or examining the invocation context. - - Evaluate the operation requested by the message to see if it fits the contract's unique rules for that operation. - -The first step often requires host-function support. The second step is always contract-specific, and cannot be provided by the platform in general. - -### Authorization-validation host functions - -Three families of host function are provided to validate authorizations: - - - **Cryptographic validation** functions. These help validate the "single-key user" form of authorization. Specifically these functions compute SHA256 hashes and verify Ed25519 signatures. - - **Account authorization** functions. These help validate the "account user" form of authorization. Specifically these functions allow looking up the signing thresholds and weights for signing keys, as stored in existing account ledger entries in the Stellar blockchain. - - **Invoking contract** function. This helps validate the "contract" form of authorization. Specifically this function returns the contract ID of the contract that invoked the currently-executing contract. If no contract invoked the currently-executing contract, this function traps. - -This last function deserves further explanation. A contract can be invoked either from a transaction (originating outside of the host) or from a cross-contract call made by some _other_ contract. When some contract X decides to invoke some other contract Y, it is generally sufficient to consider the _fact that X called Y_ as evidence that X authorizes whatever request it is making to Y with that call. After all, if X did not wish to authorize such an invocation, it would not make it! So the only information necessary to evaluate a "contract" authorization is the identity of the (directly) invoking contract. - -# Standard Token Contract - -Tokens are a vital part of blockchains, and contracts that implement token -functionality are inevitable on any smart contract platform. Instead of -expecting a standard to emerge from the ecosystem, we provide our own token -contract implementation. This has a couple advantages. First, we can special -case this contract and run it natively instead of running in a WASM VM, reducing -the cost of using the contract. Second, we can use this native contract to allow -"classic" Stellar assets to interoperate with smart tokens. The current -iteration of the standard token contract doesn't run natively or interoperate -with "classic" Stellar assets, but these improvements will be made in the -future. - -The standard token contract is similar to the widely used ERC-20 token standard, -which should make it easier for existing smart contract developers to get -started on Stellar. - -Note that this standard token contract does not prevent the ecosystem from -developing other token contracts if the one we provide is missing functionality -they require. - -## Token contract authorization semantics - -[Public types](https://github.com/stellar/soroban-token-contract/blob/main/src/public_types.rs) referenced below for the token contract - -### Authorization parameter - -Used by `mint`, `burn`, `freeze`, `unfreeze`, and `set_admin`. These functions -assume the `Authorization` is for the admin `Identifier`, which is why there are -no keys in `Authorization`. - -### KeyedAuthorization parameter - -Used by `allowance`, `approve`, `xfer`, and `xfer_from`. `KeyedAuthorization` is -for contract functions where the user is interacting with a balance or allowance in the token -contract. The user's identifier is specified as a key for -`KeyedAuthorization::Ed25519` and `KeyedAuthorization::Account`, while -`KeyedAuthorization::Contract` implies that the invoking contract's address is -the user. - -### Signatures - -For non-Contract authorization types, both `KeyedAuthorization` and -`Authorization` will include one of more signatures. Those signatures are -derived by signing the `Message` enum, which has one value at the moment, `V0`. -`Message::V0` requires the current nonce for the Identifier providing -authorization, a -[domain](https://github.com/stellar/soroban-token-contract/blob/main/src/cryptography.rs), -and the function parameters. - -### Nonce - -The token contract stores a nonce per `Identifier`. This nonce is required on -any function that requires authorization (The Signatures section above explain -how it’s used). The current nonce for an `Identifier` can be retrieved using the -nonce contract function. - -## Contract Interface - -```rust -// Admin interface - -// Sets the administrator to "admin". Also sets some metadata -fn initialize(e: Env, admin: Identifier, decimal: u32, name: Binary, symbol: Binary); - -// If "admin" is the administrator, burn "amount" from "from" -fn burn(e: Env, admin: Authorization, from: Identifier, amount: BigInt); - -// If "admin" is the administrator, mint "amount" to "to" -fn mint(e: Env, admin: Authorization, to: Identifier, amount: BigInt); - -// If "admin" is the administrator, set the administrator to "id" -fn set_admin(e: Env, admin: Authorization, new_admin: Identifier); - -// If "admin" is the administrator, freeze "id" -fn freeze(e: Env, admin: Authorization, id: Identifier); - -// If "admin" is the administrator, unfreeze "id" -fn unfreeze(e: Env, admin: Authorization, id: Identifier); - -// Token Interface - -// Get the allowance for "spender" to transfer from "from" -fn allowance(e: Env, from: Identifier, spender: Identifier) -> BigInt; - -// Set the allowance to "amount" for "spender" to transfer from "from" -fn approve(e: Env, from: KeyedAuthorization, spender: Identifier, amount: BigInt); - -// Get the balance of "id" -fn balance(e: Env, id: Identifier) -> BigInt; - -// Transfer "amount" from "from" to "to" -fn xfer(e: Env, from: KeyedAuthorization, to: Identifier, amount: BigInt); - -// Transfer "amount" from "from" to "to", consuming the allowance of "spender" -fn xfer_from(e: Env, spender: KeyedAuthorization, from: Identifier, to: Identifier, amount: BigInt); - -// Returns true if "id" is frozen -fn is_frozen(e: Env, id: Identifier) -> bool; - -// Returns the current nonce for "id" -fn nonce(e: Env, id: Identifier) -> BigInt; - -// Descriptive Interface - -// Get the number of decimals used to represent amounts of this token -fn decimals(e: Env) -> u32; - -// Get the name for this token -fn name(e: Env) -> Binary; - -// Get the symbol for this token -fn symbol(e: Env) -> Binary; -``` - -## Running the token contract with testutils machinery -This section has more information about the testutils machinery (TODO: link to interacting-with-contracts.mdx testutils section) - -This [test -case](https://github.com/stellar/soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/tests/test.rs#L20) -shows how the token contract should be used. Note that the actual call into the -contract is in the -[Token](https://github.com/stellar/soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/src/testutils.rs#L26) -wrapper test class. - -## Signing messages - -The two -[examples](https://github.com/stellar//soroban-token-contract/blob/37e2cd3580f8e28beea9e8f9194b9cf8547472dd/src/testutils.rs#L55) -from the test `Token` wrapper class demonstrate how you sign a contract function that expects an `Authorization` and a `KeyedAuthorization` type. - -### Authorization -The admin must match the `Identifier` that was used to `initialize` the contract. -```rust -pub fn mint(&self, admin: &Keypair, to: &Identifier, amount: &BigInt) { - let mut args: Vec = Vec::new(&self.env); - args.push(to.clone().into_env_val(&self.env)); - args.push(amount.clone().into_env_val(&self.env)); - let msg = Message::V0(MessageV0 { - nonce: self.nonce(&to_ed25519(&self.env, admin)), - domain: Domain::Mint as u32, - parameters: args, - }); - let auth = Authorization::Ed25519(admin.sign(msg).unwrap().into_val(&self.env)); - mint(&self.env, &self.contract_id, &auth, to, amount) -} -``` - -### KeyedAuthorization -```rust - pub fn approve(&self, from: &Keypair, spender: &Identifier, amount: &BigInt) { - let mut args: Vec = Vec::new(&self.env); - args.push(spender.clone().into_env_val(&self.env)); - args.push(amount.clone().into_env_val(&self.env)); - let msg = Message::V0(MessageV0 { - nonce: self.nonce(&to_ed25519(&self.env, from)), - domain: Domain::Approve as u32, - parameters: args, - }); - let auth = KeyedAuthorization::Ed25519(KeyedEd25519Authorization { - public_key: from.public.to_bytes().into_val(&self.env), - signature: from.sign(msg).unwrap().into_val(&self.env), - }); - approve(&self.env, &self.contract_id, &auth, spender, amount) -} -``` \ No newline at end of file diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json new file mode 100644 index 000000000..9a2d7cc52 --- /dev/null +++ b/docs/tutorials/_category_.json @@ -0,0 +1,4 @@ +{ + "position": 2, + "label": "Tutorials" +} diff --git a/docs/getting-started/build-an-optimized-wasm-file.mdx b/docs/tutorials/build-an-optimized-wasm-file.mdx similarity index 100% rename from docs/getting-started/build-an-optimized-wasm-file.mdx rename to docs/tutorials/build-an-optimized-wasm-file.mdx diff --git a/docs/getting-started/run-a-wasm-file.mdx b/docs/tutorials/build-and-run-a-contract.mdx similarity index 63% rename from docs/getting-started/run-a-wasm-file.mdx rename to docs/tutorials/build-and-run-a-contract.mdx index ef4de71b0..9732320d6 100644 --- a/docs/getting-started/run-a-wasm-file.mdx +++ b/docs/tutorials/build-and-run-a-contract.mdx @@ -1,8 +1,24 @@ --- -sidebar_position: 7 -title: Run a WASM File +sidebar_position: 6 +title: Build and Run --- +## Build a Contract + +To build a Soroban contract into a `.wasm` file, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `target` directory: + +``` +target/wasm32-unknown-unknown/release/[project-name].wasm +``` + +## Run a Contract + If you have [`soroban-cli`] installed, you can invoke contract functions in a WASM file. diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx new file mode 100644 index 000000000..3f234f36c --- /dev/null +++ b/docs/tutorials/create-a-project.mdx @@ -0,0 +1,74 @@ +--- +sidebar_position: 1 +title: Create a Project +--- + +Once you've [Setup] your development environment, you're ready to create your +first Soroban contract. + +[Setup]: setup.mdx + +Start by creating a new Rust library using the `cargo new` command. + +```sh +cargo new --lib [project-name] +``` + +Open the `Cargo.toml`, it should look something like this: + +```toml title="Cargo.toml" +[package] +name = "first-project" +version = "0.1.0" +edition = "2021" +``` + +## Add `soroban-sdk` Dependency + +Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. + +:::caution +The `soroban-sdk` is in early development. Report issues +[here](https://github.com/stellar/rs-soroban-sdk). +::: + +```toml +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] + +[dependencies] +soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } + +[dev_dependencies] +first-project = { path = ".", features = ["testutils"] } + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true +``` + +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. + +The config for the `release` profile configures the Rust toolchain to produce +smaller contracts. diff --git a/docs/getting-started/testing.mdx b/docs/tutorials/testing.mdx similarity index 100% rename from docs/getting-started/testing.mdx rename to docs/tutorials/testing.mdx diff --git a/docs/getting-started/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx similarity index 100% rename from docs/getting-started/write-a-contract.mdx rename to docs/tutorials/write-a-contract.mdx From 014da677b9204dd7a3fc44d40d38040a5c6e262a Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:18:18 -0700 Subject: [PATCH 022/248] Expand the create a project section (#41) --- docs/tutorials/create-a-project.mdx | 93 ++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 3f234f36c..2eae13d43 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -3,12 +3,12 @@ sidebar_position: 1 title: Create a Project --- -Once you've [Setup] your development environment, you're ready to create your -first Soroban contract. +Once you've [Setup] your development environment, you're ready to create Soroban +contracts. Creating projects is done using the Rust tool, `cargo`. -[Setup]: setup.mdx +[Setup]: ../getting-started/setup.mdx -Start by creating a new Rust library using the `cargo new` command. +Create a new Rust library using the `cargo new` command. ```sh cargo new --lib [project-name] @@ -18,14 +18,24 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] -name = "first-project" +name = "project-name" version = "0.1.0" edition = "2021" ``` -## Add `soroban-sdk` Dependency +## Configure the Library Type -Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. +Add the `crate-type` configuration, required for building contracts. + +```toml +[lib] +crate-type = ["cdylib", "rlib"] +``` + +## Import `soroban-sdk` and Features + +Add the following sections to the `Cargo.toml` that will import the +`soroban-sdk`, and configure a set of features explained below. :::caution The `soroban-sdk` is in early development. Report issues @@ -33,9 +43,6 @@ The `soroban-sdk` is in early development. Report issues ::: ```toml -[lib] -crate-type = ["cdylib", "rlib"] - [features] default = ["export"] export = [] @@ -45,17 +52,7 @@ testutils = ["soroban-sdk/testutils"] soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } [dev_dependencies] -first-project = { path = ".", features = ["testutils"] } - -[profile.release] -opt-level = "z" -overflow-checks = true -debug = 0 -strip = "symbols" -debug-assertions = false -panic = "abort" -codegen-units = 1 -lto = true +project-name = { path = ".", features = ["testutils"] } ``` The `features` list and `dev_dependencies` configure three variations that the @@ -70,5 +67,55 @@ not intended to be invoked. calling the contract in tests. The library itself is added as a `dev_dependencies` so that whenever its tests are running the `testutils` feature is enabled. -The config for the `release` profile configures the Rust toolchain to produce -smaller contracts. +## Configure the `release` Profile + +Configuring the `release` profile to optimize the contract build is critical. +Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, +without these configurations almost always exceed this size. + +Add the following to your `Cargo.toml`. + +```toml +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true +``` + +## Wrapping it Up + +The steps below should produce a `Cargo.toml` that looks like so. + +```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2021" +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } + +[dev_dependencies] +project-name = { path = ".", features = ["testutils"] } +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true +``` From 94bb91ce53a1b8f8b7e035ead49fb5a30d726482 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 29 Jul 2022 14:40:47 -0400 Subject: [PATCH 023/248] added category indexes --- docs/getting-started/_category_.json | 7 +++++-- docs/tutorials/_category_.json | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json index 1e1cded02..97808849a 100644 --- a/docs/getting-started/_category_.json +++ b/docs/getting-started/_category_.json @@ -1,4 +1,7 @@ { "position": 2, - "label": "Getting Started" -} + "label": "Getting Started", + "link": { + "type": "generated-index" + } +} \ No newline at end of file diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json index 9a2d7cc52..8d772d396 100644 --- a/docs/tutorials/_category_.json +++ b/docs/tutorials/_category_.json @@ -1,4 +1,7 @@ { "position": 2, - "label": "Tutorials" + "label": "Tutorials", + "link": { + "type": "generated-index" + } } From a2427c85bfbaf983d702f61551280f72eb5417e2 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:50:34 -0700 Subject: [PATCH 024/248] Add title of file to example (#42) --- docs/tutorials/write-a-contract.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 03d92d882..9629b3fc9 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -51,7 +51,7 @@ only if a feature is enabled, with `export_if = "[feature-name]"`. Putting those pieces together a simple contract will look like this. -```rust +```rust title="src/lib.rs" #![no_std] use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; From 38f6f78d05cbde52e15a35aca0b92c96656a2b29 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 11:57:06 -0700 Subject: [PATCH 025/248] Update optimized page (#44) --- ...ized-wasm-file.mdx => build-optimized.mdx} | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) rename docs/tutorials/{build-an-optimized-wasm-file.mdx => build-optimized.mdx} (65%) diff --git a/docs/tutorials/build-an-optimized-wasm-file.mdx b/docs/tutorials/build-optimized.mdx similarity index 65% rename from docs/tutorials/build-an-optimized-wasm-file.mdx rename to docs/tutorials/build-optimized.mdx index 67c0d8469..d266fa52c 100644 --- a/docs/tutorials/build-an-optimized-wasm-file.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -1,20 +1,28 @@ --- sidebar_position: 8 -title: Build an Optimized WASM File +title: Build Optimized --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Building optimized WASM files requires some additional options and commands, and -requires installing the `nightly` Rust toolchain and `wasm-opt`. +Building optimized contracts to be as small as possible requires some additional +tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. :::info -Building optimized WASM is only necessary when deploying to network or when -analyzing the real size of a contract. It is otherwise not required during -initial development. +Building optimized contracts is only necessary when deploying to network or when +analyzing and profiling a contract to get it as small as possible. If you're +just starting out writing a contract, these steps are not necessary. ::: +:::info +All contracts are optimized to some degree by the projects `release` profile. +It is highly recommended to use the release profile outlined in [Configure the +Release Profile], otherwise the contract will be too large to deploy or run. +::: + +[Create a Project]: create-a-project#configure-the-release-profile + ## Install Rust `nightly` To install the nightly Rust toolchain use `rustup`. From b7251b902a37f855d177e8f7e0de7bf7e2bf11d1 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 12:00:51 -0700 Subject: [PATCH 026/248] Fix links (#45) --- ...build-and-run-a-contract.mdx => build-and-run.mdx} | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) rename docs/tutorials/{build-and-run-a-contract.mdx => build-and-run.mdx} (66%) diff --git a/docs/tutorials/build-and-run-a-contract.mdx b/docs/tutorials/build-and-run.mdx similarity index 66% rename from docs/tutorials/build-and-run-a-contract.mdx rename to docs/tutorials/build-and-run.mdx index 9732320d6..922acfeb8 100644 --- a/docs/tutorials/build-and-run-a-contract.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -22,10 +22,9 @@ target/wasm32-unknown-unknown/release/[project-name].wasm If you have [`soroban-cli`] installed, you can invoke contract functions in a WASM file. -Using the code we wrote in [Write a Contract](write-a-contract.mdx) and the the -resulting `.wasm` file we built in [Build a WASM File](build-a-wasm-file.mdx) -run the following command to invoke the `hello` function with a single argument -`"friend"`. +Using the code we wrote in [Write a Contract] and the the resulting `.wasm` file +we built in [Build and Run] run the following command to invoke the `hello` +function with a single argument `"friend"`. ```sh soroban-cli invoke \ @@ -41,4 +40,6 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban-cli`]: setup#install-the-soroban-cli +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[Write a Contract]: write-a-contract +[Build and Run]: build-and-run From ce60587437ec9218522cf71d5971d56a96b75370 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 29 Jul 2022 15:13:54 -0400 Subject: [PATCH 027/248] update first project to create a project --- docs/tutorials/write-a-contract.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 9629b3fc9..400ca1e92 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -3,8 +3,7 @@ sidebar_position: 4 title: Write a Contract --- -Once you have a project setup, like how we setup a project in [First -Project](first-project.mdx), writing a contract involves writing Rust code in +Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in the projects `lib.rs` file. ```rust @@ -21,7 +20,7 @@ use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the -`soroban-sdk` crate. Take a look at [First Project](first-project.mdx) to see +`soroban-sdk` crate. Take a look at [Create a Project] to see how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, @@ -65,3 +64,4 @@ impl Contract { } } ``` +[Create a Project]: create-a-project.mdx \ No newline at end of file From 875606f7a0af8534f3aeecad13572ec5143745aa Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:12:49 -0600 Subject: [PATCH 028/248] Change "their" to "there" Grammar. --- docs/tutorials/write-a-contract.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 400ca1e92..702de7530 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -24,7 +24,7 @@ The contract will need to import the types and macros that it needs from the how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, -are not available, as their is no allocator and no heap memory in Soroban +are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, and `BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environments memory and native capabilities. @@ -64,4 +64,4 @@ impl Contract { } } ``` -[Create a Project]: create-a-project.mdx \ No newline at end of file +[Create a Project]: create-a-project.mdx From ce53403725c174079f763ec793ba265959f8624b Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:22:15 -0600 Subject: [PATCH 029/248] Changed "environments" to "environment's" Grammar. --- docs/tutorials/write-a-contract.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 702de7530..46d27bcc4 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -26,7 +26,7 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, and -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environments memory +`BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environment's memory and native capabilities. ```rust From 322adc2431d548c47d7a649c69fc3adcb7bf29fb Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:26:48 -0600 Subject: [PATCH 030/248] Facilities spelling error --- docs/tutorials/testing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 0e35d6d91..1c3d53d9e 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -4,7 +4,7 @@ title: Testing --- Writing tests for Soroban contracts involves writing Rust code using the Rust -test facilitiaties and toolchain that you'd use for testing any Rust code. +test facilities and toolchain that you'd use for testing any Rust code. Given a simple contract like the contract demonstrated in [Write a Contract](write-a-contract.mdx). From 6d28565cd3fb18285fb26c435c8eaafc19efcca9 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:29:30 -0600 Subject: [PATCH 031/248] Remove double "the" --- docs/tutorials/build-and-run.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 922acfeb8..3218de05a 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -22,7 +22,7 @@ target/wasm32-unknown-unknown/release/[project-name].wasm If you have [`soroban-cli`] installed, you can invoke contract functions in a WASM file. -Using the code we wrote in [Write a Contract] and the the resulting `.wasm` file +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `"friend"`. From 8af88376e1c929c3fb00d87cc98c8c632d3bcbc1 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Fri, 29 Jul 2022 15:32:52 -0600 Subject: [PATCH 032/248] Added apostrophe in "project's" for possession --- docs/tutorials/build-optimized.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index d266fa52c..08eff8499 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -16,7 +16,7 @@ just starting out writing a contract, these steps are not necessary. ::: :::info -All contracts are optimized to some degree by the projects `release` profile. +All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: From 7ffc15374a6589afe8bbcd0c30f38b6d1c60aee3 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Fri, 29 Jul 2022 16:35:11 -0700 Subject: [PATCH 033/248] Fix quick-start example (#53) --- docs/getting-started/quick-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index af2c42b02..4fa57b96f 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -96,7 +96,7 @@ impl Contract { #[cfg(test)] mod test { use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary}; + use soroban_sdk::{vec, Env, FixedBinary, Symbol}; #[test] fn test() { From 6f0fb608b4ad609a035474b26d021ca8e029880e Mon Sep 17 00:00:00 2001 From: Alex Cordeiro Date: Fri, 29 Jul 2022 17:02:02 -0700 Subject: [PATCH 034/248] A few tweaks to quick start guide to make it work (#54) --- docs/getting-started/quick-start.mdx | 8 ++++---- docs/getting-started/setup.mdx | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 4fa57b96f..57af86131 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -13,7 +13,7 @@ first Soroban contract. Start by creating a new Rust library using the `cargo new` command. ```sh -cargo new --lib [project-name] +cargo new --lib first-project ``` Open the `Cargo.toml`, it should look something like this: @@ -149,9 +149,9 @@ WASM using it. ```sh soroban-cli invoke \ - --file target/wasm32-unknown-unknown/release/first-project.wasm \ - --contract-id 1 - --fn hello + --wasm target/wasm32-unknown-unknown/release/first-project.wasm \ + --id 1 \ + --fn hello \ --arg friend ``` diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index b857fac67..57fc0bdba 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -26,6 +26,15 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh If you use Windows, or need an alternative method of installing Rust, check out: https://www.rust-lang.org/tools/install + +## Install WASM target platform + +You'll need to install the `wasm32-unknown-unknown` target platform in your machine: + +```sh +rustup target add wasm32-unknown-unknown +``` + ## Configure an Editor Many editors have support for Rust. Visit the following link to find out how to From 2c6210cd9c70c7442b04da107c0e81e239d93260 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Fri, 29 Jul 2022 17:25:14 -0700 Subject: [PATCH 035/248] fix cli usage (#55) --- docs/tutorials/build-and-run.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 3218de05a..245b41f36 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -28,9 +28,9 @@ function with a single argument `"friend"`. ```sh soroban-cli invoke \ - --file target/wasm32-unknown-unknown/release/first-project.wasm \ - --contract-id 1 - --fn hello + --wasm target/wasm32-unknown-unknown/release/first-project.wasm \ + --id 1 \ + --fn hello \ --arg friend ``` From 8e31f90f4f907db4791ee6b5eec3dd7e8420f005 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 17:36:35 -0700 Subject: [PATCH 036/248] Update crate links to use crates.io (#56) --- docs/getting-started/quick-start.mdx | 4 ++-- docs/getting-started/setup.mdx | 4 ++-- docs/tutorials/create-a-project.mdx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 57af86131..287b396f3 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -31,7 +31,7 @@ Add the following sections to the `Cargo.toml` that will import the `soroban-sdk :::caution The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/rs-soroban-sdk). +[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml @@ -44,7 +44,7 @@ export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } +soroban-sdk = "0.0.3" [dev_dependencies] first-project = { path = ".", features = ["testutils"] } diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 57fc0bdba..09274a9c4 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -49,12 +49,12 @@ will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --git http://github.com/stellar/soroban-cli soroban-cli +cargo install --locked --version 0.0.2 soroban-cli ``` :::caution The `soroban-cli` is in early development. Report issues -[here](https://github.com/stellar/soroban-cli). +[here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: ### Usage diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 2eae13d43..a76ab392d 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -39,7 +39,7 @@ Add the following sections to the `Cargo.toml` that will import the :::caution The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/rs-soroban-sdk). +[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml @@ -105,7 +105,7 @@ testutils = ["soroban-sdk/testutils"] crate-type = ["cdylib", "rlib"] [dependencies] -soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } +soroban-sdk = "0.0.3" [dev_dependencies] project-name = { path = ".", features = ["testutils"] } From c0f2b36f7e02d5144dc76897269ee5e071e621ea Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 17:38:53 -0700 Subject: [PATCH 037/248] Merge the rustup sections (#57) --- docs/getting-started/setup.mdx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 09274a9c4..b50e4a182 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -23,18 +23,15 @@ command. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -If you use Windows, or need an alternative method of installing Rust, check out: -https://www.rust-lang.org/tools/install - - -## Install WASM target platform - -You'll need to install the `wasm32-unknown-unknown` target platform in your machine: +And install the `wasm32-unknown-unknown` target. ```sh rustup target add wasm32-unknown-unknown ``` +If you use Windows, or need an alternative method of installing Rust, check out: +https://www.rust-lang.org/tools/install + ## Configure an Editor Many editors have support for Rust. Visit the following link to find out how to From 1dffb79d3e0a93ea7ed50452d8f0af28e7df6bd4 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 17:40:52 -0700 Subject: [PATCH 038/248] Fix cli version (#58) --- docs/getting-started/setup.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index b50e4a182..845ab640d 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -63,7 +63,7 @@ soroban-cli ``` ``` -soroban-cli 0.0.1 +soroban-cli 0.0.2 USAGE: soroban-cli From 84511affb738dd6dbf38e5db99c880fb604fc460 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 29 Jul 2022 17:43:10 -0700 Subject: [PATCH 039/248] Fix formatting (#59) --- docs/tutorials/create-a-project.mdx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index a76ab392d..a1bc76b16 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -43,16 +43,16 @@ The `soroban-sdk` is in early development. Report issues ::: ```toml -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] - [dependencies] -soroban-sdk = { git = "https://github.com/stellar/rs-soroban-sdk", rev = "32b76650" } +soroban-sdk = "0.0.3" [dev_dependencies] project-name = { path = ".", features = ["testutils"] } + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] ``` The `features` list and `dev_dependencies` configure three variations that the @@ -96,10 +96,6 @@ The steps below should produce a `Cargo.toml` that looks like so. name = "project-name" version = "0.1.0" edition = "2021" -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] [lib] crate-type = ["cdylib", "rlib"] @@ -109,6 +105,12 @@ soroban-sdk = "0.0.3" [dev_dependencies] project-name = { path = ".", features = ["testutils"] } + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] + [profile.release] opt-level = "z" overflow-checks = true From 094191357e71cdac5ec9fd0f42744018bd3c5c72 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 1 Aug 2022 14:29:26 -0700 Subject: [PATCH 040/248] Variety of small fixes (#65) --- docs/getting-started/quick-start.mdx | 8 ++++---- docs/getting-started/setup.mdx | 8 +++----- docs/tutorials/build-and-run.mdx | 12 +++++++----- docs/tutorials/build-optimized.mdx | 3 ++- docs/tutorials/testing.mdx | 24 +++++++++++++++++------- docs/tutorials/write-a-contract.mdx | 15 ++++++++------- 6 files changed, 41 insertions(+), 29 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 287b396f3..f144d50ee 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -128,7 +128,7 @@ test test::test ... ok Try changing the values in the test to see how it works. -## Build WASM +## Build the Contract To build the contract into a `.wasm` file, use the `cargo build` command. @@ -142,10 +142,10 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/first-project.wasm ``` -## Run the WASM +## Run the Contract If you have [`soroban-cli`] installed, you can invoke contract functions in the -WASM using it. +contract. ```sh soroban-cli invoke \ @@ -155,7 +155,7 @@ soroban-cli invoke \ --arg friend ``` -The following output should occur using the code above. +You should see the following output: ```json ["Hello","friend"] diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 845ab640d..d5b0eaf48 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -5,9 +5,7 @@ title: Setup Soroban contracts are small programs written in the [Rust] programming language. -To build and develop contracts you need only a couple pre-requisites: To setup -your development environment to develop contracts, you need only a couple -pre-requisites: +To build and develop contracts you need only a couple prerequisites: - A [Rust] toolchain - An editor that supports Rust @@ -40,8 +38,8 @@ https://www.rust-lang.org/tools ## Install the Soroban CLI -The Soroban CLI can execute WASM contracts in the same environment the contract -will execute on network, however in a local sandbox. +The Soroban CLI can execute Soroban contracts in the same environment the +contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 245b41f36..c7fcfd23d 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,13 +5,15 @@ title: Build and Run ## Build a Contract -To build a Soroban contract into a `.wasm` file, use the `cargo build` command. +To build a Soroban contract to deploy or run with the [`soroban-cli`], use the +`cargo build` command. ```sh cargo build --target wasm32-unknown-unknown --release ``` -A `.wasm` file should be outputted in the `target` directory: +A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is +the built contract. ``` target/wasm32-unknown-unknown/release/[project-name].wasm @@ -19,12 +21,12 @@ target/wasm32-unknown-unknown/release/[project-name].wasm ## Run a Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in a -WASM file. +If you have the [`soroban-cli`] installed, you can invoke contract functions +that have been built. Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build and Run] run the following command to invoke the `hello` -function with a single argument `"friend"`. +function with a single argument `friend`. ```sh soroban-cli invoke \ diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index 08eff8499..e2da7d660 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -21,7 +21,7 @@ It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: -[Create a Project]: create-a-project#configure-the-release-profile +[Configure the Release Profile]: create-a-project#configure-the-release-profile ## Install Rust `nightly` @@ -29,6 +29,7 @@ To install the nightly Rust toolchain use `rustup`. ```sh rustup install nightly +rustup target add --toolchain nightly wasm32-unknown-unknown ``` ## Install `wasm-opt` diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 1c3d53d9e..cafdc2622 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -3,13 +3,19 @@ sidebar_position: 5 title: Testing --- -Writing tests for Soroban contracts involves writing Rust code using the Rust -test facilities and toolchain that you'd use for testing any Rust code. +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Writing tests for Soroban contracts involves writing Rust code using the test +facilities and toolchain that you'd use for testing any Rust code. Given a simple contract like the contract demonstrated in [Write a -Contract](write-a-contract.mdx). +Contract](write-a-contract.mdx), a simple test will look like this. + + + -```rust title="src/lib.rs" +```rust #![no_std] use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; @@ -24,9 +30,10 @@ impl Contract { } ``` -A simple test will look like this. + + -```rust title="src/test.rs" +```rust #![cfg(test)] use super::{Contract, hello}; @@ -46,8 +53,11 @@ fn test() { } ``` + + + In any test the first thing that is always required is an `Env`, which is the -Host environment that the contract will run it. +Soroban environment that the contract will run inside of. ```rust let env = Env::default(); diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 46d27bcc4..c0383a945 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -25,9 +25,9 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban -contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, and -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Host environment's memory -and native capabilities. +contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, +`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's +memory and native capabilities. ```rust pub struct Contract; @@ -40,10 +40,11 @@ impl Contract { } ``` -Contract functions live inside a `impl` for a struct. The `impl` block is -annotated with `#[contractimpl]`, and the functions that are intended to be -called are assigned `pub` visibility and have an `Env` argument as their first -argument. +Contract functions live inside an `impl` for a struct. The `impl` block is +annotated with `#[contractimpl]`. Functions that are intended to be called +externally are should be marked with `pub` visibility. The first argument can be +an `Env` argument to get a copy of the Soroban environment, which is necessary +for most things. Implementations annotated can be configured to export the contract functions only if a feature is enabled, with `export_if = "[feature-name]"`. From 56d52db1245df1f569c00077546419b7a3d91912 Mon Sep 17 00:00:00 2001 From: Fabricio Leonardo Sodano Pascazi Date: Tue, 2 Aug 2022 08:30:57 +1000 Subject: [PATCH 041/248] Add warning for hyphenated project names (#67) --- docs/getting-started/quick-start.mdx | 8 ++++++-- docs/tutorials/build-and-run.mdx | 4 ++-- docs/tutorials/build-optimized.mdx | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index f144d50ee..5bf6d1535 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -139,9 +139,13 @@ cargo build --target wasm32-unknown-unknown --release A `.wasm` file should be outputted in the `target` directory: ``` -target/wasm32-unknown-unknown/release/first-project.wasm +target/wasm32-unknown-unknown/release/first_project.wasm ``` +:::info +Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. +::: + ## Run the Contract If you have [`soroban-cli`] installed, you can invoke contract functions in the @@ -149,7 +153,7 @@ contract. ```sh soroban-cli invoke \ - --wasm target/wasm32-unknown-unknown/release/first-project.wasm \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ --arg friend diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index c7fcfd23d..1ca3fdcae 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -16,7 +16,7 @@ A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. ``` -target/wasm32-unknown-unknown/release/[project-name].wasm +target/wasm32-unknown-unknown/release/[project_name].wasm ``` ## Run a Contract @@ -30,7 +30,7 @@ function with a single argument `friend`. ```sh soroban-cli invoke \ - --wasm target/wasm32-unknown-unknown/release/first-project.wasm \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ --arg friend diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index e2da7d660..531940000 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -82,6 +82,6 @@ Then additionally use `wasm-opt` to further minimize the size of the `.wasm`. ```sh wasm-opt -Oz \ - target/wasm32-unknown-unknown/release/first-project.wasm \ + target/wasm32-unknown-unknown/release/first_project.wasm \ -o target/wasm32-unknown-unknown/release/first-project-optimized.wasm ``` From 3cf4ce3681e65c34aa7545242b6cbcff72637a9e Mon Sep 17 00:00:00 2001 From: Thibault Date: Fri, 26 Aug 2022 15:52:46 -0700 Subject: [PATCH 042/248] Correct few typos in examples and tutorials (#83) --- docs/tutorials/write-a-contract.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index c0383a945..3165ebbd8 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -42,7 +42,7 @@ impl Contract { Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Functions that are intended to be called -externally are should be marked with `pub` visibility. The first argument can be +externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. From 6df66827e47ce62ff1e313182265a9f658242aab Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 10:19:23 -0700 Subject: [PATCH 043/248] Update sdk and cli versions and output (#87) --- docs/getting-started/quick-start.mdx | 2 +- docs/getting-started/setup.mdx | 18 ++++++++++++------ docs/tutorials/create-a-project.mdx | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 5bf6d1535..f0372f775 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -44,7 +44,7 @@ export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] first-project = { path = ".", features = ["testutils"] } diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d5b0eaf48..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.2 soroban-cli +cargo install --locked --version 0.0.4 soroban-cli ``` :::caution @@ -61,7 +61,9 @@ soroban-cli ``` ``` -soroban-cli 0.0.2 +❯ soroban-cli +soroban-cli 0.0.4 +https://soroban.stellar.org USAGE: soroban-cli @@ -70,10 +72,14 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - deploy Deploy a WASM file as a contract - version Print version information + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + read Print the current value of a contract-data ledger entry + serve Run a local webserver for web app development and testing + deploy Deploy a WASM file as a contract + gen Generate code client bindings for a contract + version Print version information + completion Print shell completion code for the specified shell ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index a1bc76b16..af1ee70e2 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,7 +44,7 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] project-name = { path = ".", features = ["testutils"] } @@ -101,7 +101,7 @@ edition = "2021" crate-type = ["cdylib", "rlib"] [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] project-name = { path = ".", features = ["testutils"] } From de8656a7e409e2c8110d6c008b4c9a0095070b5d Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 11:16:59 -0700 Subject: [PATCH 044/248] Update code samples in quickstart (#88) --- docs/getting-started/quick-start.mdx | 47 ++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index f0372f775..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,15 +39,13 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] [dependencies] soroban-sdk = "0.0.4" [dev_dependencies] -first-project = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -60,17 +58,17 @@ codegen-units = 1 lto = true ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -81,33 +79,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } #[cfg(test)] mod test { - use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary, Symbol}; + use super::{Contract, ContractClient}; + use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } } @@ -166,3 +164,6 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html From bf92b14fddebb68eab13ec5e327f4e2d757571f4 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 11:20:31 -0700 Subject: [PATCH 045/248] empty From 5030d1bf20c5ea43968136a629f5bd6a5c8916cb Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 11:26:23 -0700 Subject: [PATCH 046/248] Update the tutorial for creating a project (#89) --- docs/tutorials/create-a-project.mdx | 44 +++++++++++++---------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index af1ee70e2..27e2eb889 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -47,25 +47,23 @@ The `soroban-sdk` is in early development. Report issues soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: ## Configure the `release` Profile @@ -92,24 +90,17 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2021" - [lib] crate-type = ["cdylib", "rlib"] +[features] +testutils = ["soroban-sdk/testutils"] + [dependencies] soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } - -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -121,3 +112,6 @@ panic = "abort" codegen-units = 1 lto = true ``` + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html From 4d0c214f40b0e153b5e12bfe4c4de2f0ee093561 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 11:34:36 -0700 Subject: [PATCH 047/248] Update the tutorial for writing a contract (#90) --- docs/tutorials/write-a-contract.mdx | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index c0383a945..b6e48376c 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's -memory and native capabilities. +`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban +environment's memory and native capabilities. ```rust pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,22 +46,18 @@ externally are should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. -Implementations annotated can be configured to export the contract functions -only if a feature is enabled, with `export_if = "[feature-name]"`. - Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` From 3d72944d6bfb61bef54882d43517603e9dd4441f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 12:08:22 -0700 Subject: [PATCH 048/248] Update the tutorial for testing (#91) --- docs/tutorials/testing.mdx | 47 ++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index cafdc2622..5653bc0d2 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,15 +17,14 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` @@ -36,26 +35,38 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, hello}; -use soroban_sdk::{vec, Env, FixedBinary}; +use super::{Contract, ContractClient}; +use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } ``` + +:::info +The above example is a [Rust unit test] that lives inside the `src/` directory. +Note that if you place the test in the `tests/` directory it becomes a [Rust +integration test] with the test being compiled separately. Integration tests +require `#![cfg(feature = "testutils")]` at the top of the file and to be run +with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to +enable the generated Soroban test utilities. +::: + + In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -69,23 +80,26 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); +let contract_id = BytesN::from_array(&env, &[0; 32]); +env.register_contract(&contract_id, Contract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. +`#[contractimpl]` attribute have a corresponding function generated in a +generated client type. The client type will be named the same as the contract +type with `Client` appended. For example, in our contract the contract type is +`Contract`, and the client is named `ContractClient`. ```rust -let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +let client = ContractClient::new(&env, &contract_id); +let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); ``` @@ -103,3 +117,6 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. + +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html From 1dc54990726ce713b3e760fab62067bf687775e8 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 17:01:57 -0700 Subject: [PATCH 049/248] Put auth example earlier in list of examples (#96) * noop * noop * Update sdk and cli versions and output (#87) * Update code samples in quickstart (#88) * empty * Update the tutorial for creating a project (#89) * Update the tutorial for writing a contract (#90) * Update the tutorial for testing (#91) * Update the hello_world contract (#92) * Small fix to hello contract * Update the increment contract (#93) * Small fix to increment example * Update the custom_types contract (#94) * Add auth example and update auth learn page (#95) * Put auth example earlier in list of examples Co-authored-by: Tyler van der Hoeven Co-authored-by: Siddharth Suresh --- docs/getting-started/quick-start.mdx | 49 ++++++++++++++-------------- docs/getting-started/setup.mdx | 18 ++++++---- docs/tutorials/create-a-project.mdx | 48 ++++++++++++--------------- docs/tutorials/testing.mdx | 47 +++++++++++++++++--------- docs/tutorials/write-a-contract.mdx | 18 ++++------ 5 files changed, 97 insertions(+), 83 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 5bf6d1535..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,15 +39,13 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -first-project = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -60,17 +58,17 @@ codegen-units = 1 lto = true ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -81,33 +79,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } #[cfg(test)] mod test { - use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary, Symbol}; + use super::{Contract, ContractClient}; + use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } } @@ -166,3 +164,6 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d5b0eaf48..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.2 soroban-cli +cargo install --locked --version 0.0.4 soroban-cli ``` :::caution @@ -61,7 +61,9 @@ soroban-cli ``` ``` -soroban-cli 0.0.2 +❯ soroban-cli +soroban-cli 0.0.4 +https://soroban.stellar.org USAGE: soroban-cli @@ -70,10 +72,14 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - deploy Deploy a WASM file as a contract - version Print version information + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + read Print the current value of a contract-data ledger entry + serve Run a local webserver for web app development and testing + deploy Deploy a WASM file as a contract + gen Generate code client bindings for a contract + version Print version information + completion Print shell completion code for the specified shell ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index a1bc76b16..27e2eb889 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,28 +44,26 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: ## Configure the `release` Profile @@ -92,24 +90,17 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2021" - [lib] crate-type = ["cdylib", "rlib"] +[features] +testutils = ["soroban-sdk/testutils"] + [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } - -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -121,3 +112,6 @@ panic = "abort" codegen-units = 1 lto = true ``` + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index cafdc2622..5653bc0d2 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,15 +17,14 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` @@ -36,26 +35,38 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, hello}; -use soroban_sdk::{vec, Env, FixedBinary}; +use super::{Contract, ContractClient}; +use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } ``` + +:::info +The above example is a [Rust unit test] that lives inside the `src/` directory. +Note that if you place the test in the `tests/` directory it becomes a [Rust +integration test] with the test being compiled separately. Integration tests +require `#![cfg(feature = "testutils")]` at the top of the file and to be run +with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to +enable the generated Soroban test utilities. +::: + + In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -69,23 +80,26 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); +let contract_id = BytesN::from_array(&env, &[0; 32]); +env.register_contract(&contract_id, Contract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. +`#[contractimpl]` attribute have a corresponding function generated in a +generated client type. The client type will be named the same as the contract +type with `Client` appended. For example, in our contract the contract type is +`Contract`, and the client is named `ContractClient`. ```rust -let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +let client = ContractClient::new(&env, &contract_id); +let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); ``` @@ -103,3 +117,6 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. + +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 3165ebbd8..b617e3a62 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's -memory and native capabilities. +`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban +environment's memory and native capabilities. ```rust pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,22 +46,18 @@ externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. -Implementations annotated can be configured to export the contract functions -only if a feature is enabled, with `export_if = "[feature-name]"`. - Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` From 159da95bf679fb7344169ef09c9eb8d219686788 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 30 Aug 2022 17:02:43 -0700 Subject: [PATCH 050/248] Revert "Put auth example earlier in list of examples (#96)" (#97) This reverts commit 1dc54990726ce713b3e760fab62067bf687775e8. --- docs/getting-started/quick-start.mdx | 49 ++++++++++++++-------------- docs/getting-started/setup.mdx | 18 ++++------ docs/tutorials/create-a-project.mdx | 48 +++++++++++++++------------ docs/tutorials/testing.mdx | 47 +++++++++----------------- docs/tutorials/write-a-contract.mdx | 18 ++++++---- 5 files changed, 83 insertions(+), 97 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3e6e1acd7..5bf6d1535 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,13 +39,15 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] +default = ["export"] +export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +first-project = { path = ".", features = ["testutils"] } [profile.release] opt-level = "z" @@ -58,17 +60,17 @@ codegen-units = 1 lto = true ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -79,33 +81,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } #[cfg(test)] mod test { - use super::{Contract, ContractClient}; - use soroban_sdk::{symbol, vec, BytesN, Env}; + use super::{Contract, hello}; + use soroban_sdk::{vec, Env, FixedBinary, Symbol}; #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); + let contract_id = FixedBinary::from_array(&env, [0; 32]); env.register_contract(&contract_id, Contract); - let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&symbol!("Dev")); + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] ); } } @@ -164,6 +166,3 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4070513b0..d5b0eaf48 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.4 soroban-cli +cargo install --locked --version 0.0.2 soroban-cli ``` :::caution @@ -61,9 +61,7 @@ soroban-cli ``` ``` -❯ soroban-cli -soroban-cli 0.0.4 -https://soroban.stellar.org +soroban-cli 0.0.2 USAGE: soroban-cli @@ -72,14 +70,10 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - read Print the current value of a contract-data ledger entry - serve Run a local webserver for web app development and testing - deploy Deploy a WASM file as a contract - gen Generate code client bindings for a contract - version Print version information - completion Print shell completion code for the specified shell + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + deploy Deploy a WASM file as a contract + version Print version information ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 27e2eb889..a1bc76b16 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,26 +44,28 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +project-name = { path = ".", features = ["testutils"] } [features] +default = ["export"] +export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. ## Configure the `release` Profile @@ -90,17 +92,24 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2021" + [lib] crate-type = ["cdylib", "rlib"] -[features] -testutils = ["soroban-sdk/testutils"] - [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +project-name = { path = ".", features = ["testutils"] } + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] [profile.release] opt-level = "z" @@ -112,6 +121,3 @@ panic = "abort" codegen-units = 1 lto = true ``` - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 5653bc0d2..cafdc2622 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,14 +17,15 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } ``` @@ -35,38 +36,26 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, ContractClient}; -use soroban_sdk::{symbol, vec, BytesN, Env}; +use super::{Contract, hello}; +use soroban_sdk::{vec, Env, FixedBinary}; #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); + let contract_id = FixedBinary::from_array(&env, [0; 32]); env.register_contract(&contract_id, Contract); - let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&symbol!("Dev")); + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] ); } ``` - -:::info -The above example is a [Rust unit test] that lives inside the `src/` directory. -Note that if you place the test in the `tests/` directory it becomes a [Rust -integration test] with the test being compiled separately. Integration tests -require `#![cfg(feature = "testutils")]` at the top of the file and to be run -with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to -enable the generated Soroban test utilities. -::: - - In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -80,26 +69,23 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = BytesN::from_array(&env, &[0; 32]); -env.register_contract(&contract_id, Contract); +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have a corresponding function generated in a -generated client type. The client type will be named the same as the contract -type with `Client` appended. For example, in our contract the contract type is -`Contract`, and the client is named `ContractClient`. +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. ```rust -let client = ContractClient::new(&env, &contract_id); -let words = client.hello(&symbol!("Dev")); +let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] ); ``` @@ -117,6 +103,3 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. - -[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a62..3165ebbd8 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's +memory and native capabilities. ```rust pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,18 +46,22 @@ externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +Implementations annotated can be configured to export the contract functions +only if a feature is enabled, with `export_if = "[feature-name]"`. + Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } ``` From ee9e03fbc565bec36f56ac811e65a851d4bf453b Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:07:39 -0700 Subject: [PATCH 051/248] Add auth sdk page (#108) * noop * noop * Update sdk and cli versions and output (#87) * Update code samples in quickstart (#88) * empty * Update the tutorial for creating a project (#89) * Update the tutorial for writing a contract (#90) * Update the tutorial for testing (#91) * Update the hello_world contract (#92) * Small fix to hello contract * Update the increment contract (#93) * Small fix to increment example * Update the custom_types contract (#94) * Add auth example and update auth learn page (#95) * Put auth example earlier in list of examples (#98) (cherry picked from commit fc2fc75d34aad6eecae9d5f8de10f16268edd7c2) * Add events example (#100) * Update the cross_contract contract (#99) * Small tweak to contract call doc * Fix to contract call code sample * Fix to contract call code sample * noop to try and make it deploy properly * Reorder examples so that contract events appears higher in list * Fix headings of cross contract example (#102) * Add soroban-cli read example * Tweak language about developer discord * Some changes to the events example page (#101) * Rename standard-contracts and update token-contract (#103) * Rename Standard Contracts to Built-In Contracts * Update built-in-contracts/token-contract and examples/authorization * Fix title capitalization of built-in contracts page (#104) * Add stub for token example (#105) * Update authorization docs to line up with contract examples (#106) * Small fixes for token contract doc * Make authorization docs line up with the example * Instruct users to checkout v0.0.4 tag for examples (#107) * fix pages and sdk instructions * Add auth sdk page Co-authored-by: Tyler van der Hoeven Co-authored-by: Siddharth Suresh Co-authored-by: Jay Geng Co-authored-by: jonjove <31668823+jonjove@users.noreply.github.com> --- docs/getting-started/quick-start.mdx | 49 ++++++++++++++-------------- docs/getting-started/setup.mdx | 18 ++++++---- docs/tutorials/create-a-project.mdx | 48 ++++++++++++--------------- docs/tutorials/testing.mdx | 47 +++++++++++++++++--------- docs/tutorials/write-a-contract.mdx | 18 ++++------ 5 files changed, 97 insertions(+), 83 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 5bf6d1535..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,15 +39,13 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -first-project = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -60,17 +58,17 @@ codegen-units = 1 lto = true ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -81,33 +79,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } #[cfg(test)] mod test { - use super::{Contract, hello}; - use soroban_sdk::{vec, Env, FixedBinary, Symbol}; + use super::{Contract, ContractClient}; + use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } } @@ -166,3 +164,6 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d5b0eaf48..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.2 soroban-cli +cargo install --locked --version 0.0.4 soroban-cli ``` :::caution @@ -61,7 +61,9 @@ soroban-cli ``` ``` -soroban-cli 0.0.2 +❯ soroban-cli +soroban-cli 0.0.4 +https://soroban.stellar.org USAGE: soroban-cli @@ -70,10 +72,14 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - deploy Deploy a WASM file as a contract - version Print version information + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + read Print the current value of a contract-data ledger entry + serve Run a local webserver for web app development and testing + deploy Deploy a WASM file as a contract + gen Generate code client bindings for a contract + version Print version information + completion Print shell completion code for the specified shell ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index a1bc76b16..27e2eb889 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,28 +44,26 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [features] -default = ["export"] -export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list and `dev_dependencies` configure three variations that the -contract can be built with: -- By `default`, with `export` enabled, contract functions will be exported and -available to be invoked when the contract is deployed. -- Optionally without `export` enabled, contract functions will not be exported. -Types will be still exposed, which is useful when developing multiple contracts -together and this contract is to be imported into another but its functions are -not intended to be invoked. -- And `testutils` which will cause additional test utilities to be generated for -calling the contract in tests. The library itself is added as a `dev_dependencies` -so that whenever its tests are running the `testutils` feature is enabled. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. + +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: ## Configure the `release` Profile @@ -92,24 +90,17 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2021" - [lib] crate-type = ["cdylib", "rlib"] +[features] +testutils = ["soroban-sdk/testutils"] + [dependencies] -soroban-sdk = "0.0.3" +soroban-sdk = "0.0.4" [dev_dependencies] -project-name = { path = ".", features = ["testutils"] } - -[features] -default = ["export"] -export = [] -testutils = ["soroban-sdk/testutils"] +soroban-sdk = { version = "0.0.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -121,3 +112,6 @@ panic = "abort" codegen-units = 1 lto = true ``` + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index cafdc2622..5653bc0d2 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,15 +17,14 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` @@ -36,26 +35,38 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, hello}; -use soroban_sdk::{vec, Env, FixedBinary}; +use super::{Contract, ContractClient}; +use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = FixedBinary::from_array(&env, [0; 32]); + let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); + let client = ContractClient::new(&env, &contract_id); - let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); + let words = client.hello(&symbol!("Dev")); assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); } ``` + +:::info +The above example is a [Rust unit test] that lives inside the `src/` directory. +Note that if you place the test in the `tests/` directory it becomes a [Rust +integration test] with the test being compiled separately. Integration tests +require `#![cfg(feature = "testutils")]` at the top of the file and to be run +with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to +enable the generated Soroban test utilities. +::: + + In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -69,23 +80,26 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = FixedBinary::from_array(&env, [0; 32]); -env.register_contract(&contract_id, HelloContract); +let contract_id = BytesN::from_array(&env, &[0; 32]); +env.register_contract(&contract_id, Contract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have an `invoke` function generated, that can be -used to invoke the contract function within the environment. +`#[contractimpl]` attribute have a corresponding function generated in a +generated client type. The client type will be named the same as the contract +type with `Client` appended. For example, in our contract the contract type is +`Contract`, and the client is named `ContractClient`. ```rust -let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); +let client = ContractClient::new(&env, &contract_id); +let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] + vec![&env, symbol!("Hello"), symbol!("Dev"),] ); ``` @@ -103,3 +117,6 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. + +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 3165ebbd8..b617e3a62 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's -memory and native capabilities. +`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban +environment's memory and native capabilities. ```rust pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,22 +46,18 @@ externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. -Implementations annotated can be configured to export the contract functions -only if a feature is enabled, with `export_if = "[feature-name]"`. - Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl(export_if = "export")] +#[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - const GREETING: Symbol = Symbol::from_str("Hello"); - vec![&env, GREETING, to] + vec![&env, symbol!("Hello"), to] } } ``` From 70f5bdf554fafa1b03150ec732067a2bc1b0520d Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Sep 2022 10:08:18 -0700 Subject: [PATCH 052/248] Revert "Add auth sdk page (#108)" (#109) This reverts commit ee9e03fbc565bec36f56ac811e65a851d4bf453b. --- docs/getting-started/quick-start.mdx | 49 ++++++++++++++-------------- docs/getting-started/setup.mdx | 18 ++++------ docs/tutorials/create-a-project.mdx | 48 +++++++++++++++------------ docs/tutorials/testing.mdx | 47 +++++++++----------------- docs/tutorials/write-a-contract.mdx | 18 ++++++---- 5 files changed, 83 insertions(+), 97 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3e6e1acd7..5bf6d1535 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -39,13 +39,15 @@ The `soroban-sdk` is in early development. Report issues crate-type = ["cdylib", "rlib"] [features] +default = ["export"] +export = [] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +first-project = { path = ".", features = ["testutils"] } [profile.release] opt-level = "z" @@ -58,17 +60,17 @@ codegen-units = 1 lto = true ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -79,33 +81,33 @@ Open the `src/lib.rs` file, and copy-paste the following code. ```rust #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } #[cfg(test)] mod test { - use super::{Contract, ContractClient}; - use soroban_sdk::{symbol, vec, BytesN, Env}; + use super::{Contract, hello}; + use soroban_sdk::{vec, Env, FixedBinary, Symbol}; #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); + let contract_id = FixedBinary::from_array(&env, [0; 32]); env.register_contract(&contract_id, Contract); - let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&symbol!("Dev")); + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] ); } } @@ -164,6 +166,3 @@ You should see the following output: ``` [`soroban-cli`]: setup#install-the-soroban-cli - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4070513b0..d5b0eaf48 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -44,7 +44,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.4 soroban-cli +cargo install --locked --version 0.0.2 soroban-cli ``` :::caution @@ -61,9 +61,7 @@ soroban-cli ``` ``` -❯ soroban-cli -soroban-cli 0.0.4 -https://soroban.stellar.org +soroban-cli 0.0.2 USAGE: soroban-cli @@ -72,14 +70,10 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - read Print the current value of a contract-data ledger entry - serve Run a local webserver for web app development and testing - deploy Deploy a WASM file as a contract - gen Generate code client bindings for a contract - version Print version information - completion Print shell completion code for the specified shell + invoke Invoke a contract function in a WASM file + inspect Inspect a WASM file listing contract functions, meta, etc + deploy Deploy a WASM file as a contract + version Print version information ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 27e2eb889..a1bc76b16 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,26 +44,28 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +project-name = { path = ".", features = ["testutils"] } [features] +default = ["export"] +export = [] testutils = ["soroban-sdk/testutils"] ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +The `features` list and `dev_dependencies` configure three variations that the +contract can be built with: +- By `default`, with `export` enabled, contract functions will be exported and +available to be invoked when the contract is deployed. +- Optionally without `export` enabled, contract functions will not be exported. +Types will be still exposed, which is useful when developing multiple contracts +together and this contract is to be imported into another but its functions are +not intended to be invoked. +- And `testutils` which will cause additional test utilities to be generated for +calling the contract in tests. The library itself is added as a `dev_dependencies` +so that whenever its tests are running the `testutils` feature is enabled. ## Configure the `release` Profile @@ -90,17 +92,24 @@ lto = true The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2021" + [lib] crate-type = ["cdylib", "rlib"] -[features] -testutils = ["soroban-sdk/testutils"] - [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.0.3" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +project-name = { path = ".", features = ["testutils"] } + +[features] +default = ["export"] +export = [] +testutils = ["soroban-sdk/testutils"] [profile.release] opt-level = "z" @@ -112,6 +121,3 @@ panic = "abort" codegen-units = 1 lto = true ``` - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 5653bc0d2..cafdc2622 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -17,14 +17,15 @@ Contract](write-a-contract.mdx), a simple test will look like this. ```rust #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } ``` @@ -35,38 +36,26 @@ impl Contract { ```rust #![cfg(test)] -use super::{Contract, ContractClient}; -use soroban_sdk::{symbol, vec, BytesN, Env}; +use super::{Contract, hello}; +use soroban_sdk::{vec, Env, FixedBinary}; #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); + let contract_id = FixedBinary::from_array(&env, [0; 32]); env.register_contract(&contract_id, Contract); - let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&symbol!("Dev")); + let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev")); assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),] ); } ``` - -:::info -The above example is a [Rust unit test] that lives inside the `src/` directory. -Note that if you place the test in the `tests/` directory it becomes a [Rust -integration test] with the test being compiled separately. Integration tests -require `#![cfg(feature = "testutils")]` at the top of the file and to be run -with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to -enable the generated Soroban test utilities. -::: - - In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. @@ -80,26 +69,23 @@ if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust -let contract_id = BytesN::from_array(&env, &[0; 32]); -env.register_contract(&contract_id, Contract); +let contract_id = FixedBinary::from_array(&env, [0; 32]); +env.register_contract(&contract_id, HelloContract); ``` All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have a corresponding function generated in a -generated client type. The client type will be named the same as the contract -type with `Client` appended. For example, in our contract the contract type is -`Contract`, and the client is named `ContractClient`. +`#[contractimpl]` attribute have an `invoke` function generated, that can be +used to invoke the contract function within the environment. ```rust -let client = ContractClient::new(&env, &contract_id); -let words = client.hello(&symbol!("Dev")); +let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun")); ``` The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),] ); ``` @@ -117,6 +103,3 @@ test test::test ... ok ``` Try changing the values in the test to see how it works. - -[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a62..3165ebbd8 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -16,7 +16,7 @@ well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the @@ -26,13 +26,13 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +`BigInt`, `Binary`, `FixedBinary`, that all utilize the Soroban environment's +memory and native capabilities. ```rust pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { todo!() @@ -46,18 +46,22 @@ externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +Implementations annotated can be configured to export the contract functions +only if a feature is enabled, with `export_if = "[feature-name]"`. + Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; -#[contractimpl] +#[contractimpl(export_if = "export")] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + const GREETING: Symbol = Symbol::from_str("Hello"); + vec![&env, GREETING, to] } } ``` From 7b9745a6deb022b54d1ee76ce6a6e5bfe354b881 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:17:33 -0700 Subject: [PATCH 053/248] Add rust-src component install to build optimized tutorial (#117) --- docs/tutorials/build-optimized.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index 531940000..a62974c03 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -30,6 +30,7 @@ To install the nightly Rust toolchain use `rustup`. ```sh rustup install nightly rustup target add --toolchain nightly wasm32-unknown-unknown +rustup component add --toolchain nightly rust-src ``` ## Install `wasm-opt` From c7984f63996fee7fab06fa97d5e31bc482b7b09c Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 13 Sep 2022 18:52:00 +0100 Subject: [PATCH 054/248] ran a linter on the docs --- docs/getting-started/quick-start.mdx | 39 ++++++++------------------- docs/getting-started/setup.mdx | 20 +++++--------- docs/tutorials/build-and-run.mdx | 19 +++++-------- docs/tutorials/build-optimized.mdx | 30 +++++++-------------- docs/tutorials/create-a-project.mdx | 33 +++++++---------------- docs/tutorials/testing.mdx | 40 ++++++++-------------------- docs/tutorials/write-a-contract.mdx | 27 +++++-------------- 7 files changed, 60 insertions(+), 148 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3e6e1acd7..503a01b4c 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -3,10 +3,9 @@ sidebar_position: 3 title: Quick Start --- -Once you've [Setup] your development environment, you're ready to create your -first Soroban contract. +Once you've [Setup] your development environment, you're ready to create your first Soroban contract. -[Setup]: setup.mdx +[setup]: setup.mdx ## Create New Project @@ -29,10 +28,7 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. -:::caution -The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). -::: +:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml [lib] @@ -58,20 +54,11 @@ codegen-units = 1 lto = true ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. +The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: -The config for the `release` profile configures the Rust toolchain to produce -smaller contracts. +The config for the `release` profile configures the Rust toolchain to produce smaller contracts. ## Write the Code @@ -140,14 +127,11 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/first_project.wasm ``` -:::info -Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. -::: +:::info Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. ::: ## Run the Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in the -contract. +If you have [`soroban-cli`] installed, you can invoke contract functions in the contract. ```sh soroban-cli invoke \ @@ -160,10 +144,9 @@ soroban-cli invoke \ You should see the following output: ```json -["Hello","friend"] +["Hello", "friend"] ``` [`soroban-cli`]: setup#install-the-soroban-cli - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4070513b0..086fd42ac 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -13,9 +13,7 @@ To build and develop contracts you need only a couple prerequisites: ## Install Rust -If you use macOS, Linux, or another Unix-like OS, the simplest method to install -a Rust toolchain is to install `rustup`. Install `rustup` with the following -command. +If you use macOS, Linux, or another Unix-like OS, the simplest method to install a Rust toolchain is to install `rustup`. Install `rustup` with the following command. ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh @@ -32,14 +30,12 @@ https://www.rust-lang.org/tools/install ## Configure an Editor -Many editors have support for Rust. Visit the following link to find out how to -configure your editor: +Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools ## Install the Soroban CLI -The Soroban CLI can execute Soroban contracts in the same environment the -contract will execute on network, however in a local sandbox. +The Soroban CLI can execute Soroban contracts in the same environment the contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. @@ -47,10 +43,7 @@ Install the Soroban CLI using `cargo install`. cargo install --locked --version 0.0.4 soroban-cli ``` -:::caution -The `soroban-cli` is in early development. Report issues -[here](https://github.com/stellar/soroban-cli/issues/new/choose). -::: +:::caution The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: ### Usage @@ -82,6 +75,5 @@ SUBCOMMANDS: completion Print shell completion code for the specified shell ``` - -[Rust]: https://www.rust-lang.org/ -[Soroban CLI]: setup#install-the-soroban-cli +[rust]: https://www.rust-lang.org/ +[soroban cli]: setup#install-the-soroban-cli diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 1ca3fdcae..0d8d33972 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,15 +5,13 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban-cli`], use the -`cargo build` command. +To build a Soroban contract to deploy or run with the [`soroban-cli`], use the `cargo build` command. ```sh cargo build --target wasm32-unknown-unknown --release ``` -A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is -the built contract. +A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. ``` target/wasm32-unknown-unknown/release/[project_name].wasm @@ -21,12 +19,9 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban-cli`] installed, you can invoke contract functions -that have been built. +If you have the [`soroban-cli`] installed, you can invoke contract functions that have been built. -Using the code we wrote in [Write a Contract] and the resulting `.wasm` file -we built in [Build and Run] run the following command to invoke the `hello` -function with a single argument `friend`. +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `friend`. ```sh soroban-cli invoke \ @@ -39,9 +34,9 @@ soroban-cli invoke \ The following output should appear. ```json -["Hello","friend"] +["Hello", "friend"] ``` [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[Write a Contract]: write-a-contract -[Build and Run]: build-and-run +[write a contract]: write-a-contract +[build and run]: build-and-run diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index a62974c03..e386f4402 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -3,25 +3,16 @@ sidebar_position: 8 title: Build Optimized --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; -Building optimized contracts to be as small as possible requires some additional -tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. +Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. -:::info -Building optimized contracts is only necessary when deploying to network or when -analyzing and profiling a contract to get it as small as possible. If you're -just starting out writing a contract, these steps are not necessary. -::: +:::info Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. ::: -:::info -All contracts are optimized to some degree by the project's `release` profile. -It is highly recommended to use the release profile outlined in [Configure the -Release Profile], otherwise the contract will be too large to deploy or run. -::: +:::info All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: -[Configure the Release Profile]: create-a-project#configure-the-release-profile +[configure the release profile]: create-a-project#configure-the-release-profile ## Install Rust `nightly` @@ -35,8 +26,7 @@ rustup component add --toolchain nightly rust-src ## Install `wasm-opt` -To install `wasm-opt`, install `binaryen`. Depending on your operating system -there may be different ways to install it. +To install `wasm-opt`, install `binaryen`. Depending on your operating system there may be different ways to install it. @@ -60,16 +50,14 @@ https://github.com/WebAssembly/binaryen/releases -For install options see: -https://github.com/WebAssembly/binaryen/releases +For install options see: https://github.com/WebAssembly/binaryen/releases ## Building with `nightly` and `wasm-opt` -Then build your contract using nightly, and the additional options that remove -unnecessary information from the contract. +Then build your contract using nightly, and the additional options that remove unnecessary information from the contract. ```sh cargo +nightly build \ diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 27e2eb889..bd47aa390 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -3,10 +3,9 @@ sidebar_position: 1 title: Create a Project --- -Once you've [Setup] your development environment, you're ready to create Soroban -contracts. Creating projects is done using the Rust tool, `cargo`. +Once you've [Setup] your development environment, you're ready to create Soroban contracts. Creating projects is done using the Rust tool, `cargo`. -[Setup]: ../getting-started/setup.mdx +[setup]: ../getting-started/setup.mdx Create a new Rust library using the `cargo new` command. @@ -34,13 +33,9 @@ crate-type = ["cdylib", "rlib"] ## Import `soroban-sdk` and Features -Add the following sections to the `Cargo.toml` that will import the -`soroban-sdk`, and configure a set of features explained below. +Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. -:::caution -The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). -::: +:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml [dependencies] @@ -53,23 +48,13 @@ soroban-sdk = { version = "0.0.4", features = ["testutils"] } testutils = ["soroban-sdk/testutils"] ``` -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. +The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. -::: +:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: ## Configure the `release` Profile -Configuring the `release` profile to optimize the contract build is critical. -Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, -without these configurations almost always exceed this size. +Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, without these configurations almost always exceed this size. Add the following to your `Cargo.toml`. @@ -113,5 +98,5 @@ codegen-units = 1 lto = true ``` -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 5653bc0d2..0648f871c 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -3,14 +3,12 @@ sidebar_position: 5 title: Testing --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; -Writing tests for Soroban contracts involves writing Rust code using the test -facilities and toolchain that you'd use for testing any Rust code. +Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. -Given a simple contract like the contract demonstrated in [Write a -Contract](write-a-contract.mdx), a simple test will look like this. +Given a simple contract like the contract demonstrated in [Write a Contract](write-a-contract.mdx), a simple test will look like this. @@ -53,42 +51,25 @@ fn test() { } ``` - -:::info -The above example is a [Rust unit test] that lives inside the `src/` directory. -Note that if you place the test in the `tests/` directory it becomes a [Rust -integration test] with the test being compiled separately. Integration tests -require `#![cfg(feature = "testutils")]` at the top of the file and to be run -with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to -enable the generated Soroban test utilities. -::: - +:::info The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. ::: -In any test the first thing that is always required is an `Env`, which is the -Soroban environment that the contract will run inside of. +In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. ```rust let env = Env::default(); ``` -Contracts must be registered with the environment with a contract ID, which is a -32-byte value. In many cases it is sufficient to use a simple zero ID, however -if the test will deploy the contract multiple times, or deploy multiple -contracts, each should use their own IDs. +Contracts must be registered with the environment with a contract ID, which is a 32-byte value. In many cases it is sufficient to use a simple zero ID, however if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. ```rust let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); ``` -All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have a corresponding function generated in a -generated client type. The client type will be named the same as the contract -type with `Client` appended. For example, in our contract the contract type is -`Contract`, and the client is named `ContractClient`. +All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `Contract`, and the client is named `ContractClient`. ```rust let client = ContractClient::new(&env, &contract_id); @@ -96,6 +77,7 @@ let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: + ```rust assert_eq!( words, @@ -118,5 +100,5 @@ test test::test ... ok Try changing the values in the test to see how it works. -[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a62..42b3746b8 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -3,31 +3,21 @@ sidebar_position: 4 title: Write a Contract --- -Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in -the projects `lib.rs` file. +Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in the projects `lib.rs` file. ```rust #![no_std] ``` -All contracts should begin with `#![no_std]` to ensure that the Rust standard -library is not included in the build. The Rust standard library is large and not -well suited to being deployed into small programs like those deployed to -blockchains. +All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains. ```rust use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` -The contract will need to import the types and macros that it needs from the -`soroban-sdk` crate. Take a look at [Create a Project] to see -how to setup a project. +The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project] to see how to setup a project. -Many of the types available in typical Rust programs, such as `std::vec::Vec`, -are not available, as there is no allocator and no heap memory in Soroban -contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. ```rust pub struct Contract; @@ -40,11 +30,7 @@ impl Contract { } ``` -Contract functions live inside an `impl` for a struct. The `impl` block is -annotated with `#[contractimpl]`. Functions that are intended to be called -externally should be marked with `pub` visibility. The first argument can be -an `Env` argument to get a copy of the Soroban environment, which is necessary -for most things. +Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. Putting those pieces together a simple contract will look like this. @@ -61,4 +47,5 @@ impl Contract { } } ``` -[Create a Project]: create-a-project.mdx + +[create a project]: create-a-project.mdx From 42f53d1133c3606cd3ef4f5446b7aafeb7c502b9 Mon Sep 17 00:00:00 2001 From: tomerweller Date: Tue, 13 Sep 2022 12:24:55 -0700 Subject: [PATCH 055/248] build optimized: fix admonitions (#118) --- docs/tutorials/build-optimized.mdx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index e386f4402..b86a04993 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -8,9 +8,18 @@ import TabItem from "@theme/TabItem"; Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. -:::info Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. ::: +:::info -:::info All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: +Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. + +::: + + +:::info + +All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. + +::: [configure the release profile]: create-a-project#configure-the-release-profile From 59853b35d93fd25465c7ee95b9fcce44a36a076d Mon Sep 17 00:00:00 2001 From: tomerweller Date: Tue, 13 Sep 2022 12:46:02 -0700 Subject: [PATCH 056/248] fix admonitions (#121) --- docs/getting-started/quick-start.mdx | 18 +++++++++++++++--- docs/getting-started/setup.mdx | 6 +++++- docs/tutorials/create-a-project.mdx | 12 ++++++++++-- docs/tutorials/testing.mdx | 6 +++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 503a01b4c..3eabf7d9d 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -28,7 +28,11 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. -:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: +:::caution + +The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). + +::: ```toml [lib] @@ -56,7 +60,11 @@ lto = true The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: +:::info + +The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. + +::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -127,7 +135,11 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/first_project.wasm ``` -:::info Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. ::: +:::info + +Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. + +::: ## Run the Contract diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 086fd42ac..1b4286738 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -43,7 +43,11 @@ Install the Soroban CLI using `cargo install`. cargo install --locked --version 0.0.4 soroban-cli ``` -:::caution The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: +:::caution + +The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). + +::: ### Usage diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index bd47aa390..76776bea7 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -35,7 +35,11 @@ crate-type = ["cdylib", "rlib"] Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. -:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: +:::caution + +The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). + +::: ```toml [dependencies] @@ -50,7 +54,11 @@ testutils = ["soroban-sdk/testutils"] The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: +:::info + +The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. + +::: ## Configure the `release` Profile diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 0648f871c..34036ab4e 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -54,7 +54,11 @@ fn test() { -:::info The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. ::: +:::info + +The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. + +::: In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. From 7f72671b1acff6137a9648b806fe02523e13fac5 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 13 Sep 2022 21:21:35 +0100 Subject: [PATCH 057/248] Revert "fix admonitions (#121)" This reverts commit 59853b35d93fd25465c7ee95b9fcce44a36a076d. --- docs/getting-started/quick-start.mdx | 18 +++--------------- docs/getting-started/setup.mdx | 6 +----- docs/tutorials/create-a-project.mdx | 12 ++---------- docs/tutorials/testing.mdx | 6 +----- 4 files changed, 7 insertions(+), 35 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3eabf7d9d..503a01b4c 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -28,11 +28,7 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. -:::caution - -The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). - -::: +:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml [lib] @@ -60,11 +56,7 @@ lto = true The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info - -The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. - -::: +:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: The config for the `release` profile configures the Rust toolchain to produce smaller contracts. @@ -135,11 +127,7 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/first_project.wasm ``` -:::info - -Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. - -::: +:::info Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. ::: ## Run the Contract diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 1b4286738..086fd42ac 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -43,11 +43,7 @@ Install the Soroban CLI using `cargo install`. cargo install --locked --version 0.0.4 soroban-cli ``` -:::caution - -The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). - -::: +:::caution The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: ### Usage diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 76776bea7..bd47aa390 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -35,11 +35,7 @@ crate-type = ["cdylib", "rlib"] Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. -:::caution - -The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). - -::: +:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: ```toml [dependencies] @@ -54,11 +50,7 @@ testutils = ["soroban-sdk/testutils"] The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. -:::info - -The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. - -::: +:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: ## Configure the `release` Profile diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 34036ab4e..0648f871c 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -54,11 +54,7 @@ fn test() { -:::info - -The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. - -::: +:::info The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. ::: In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. From 42fb0557d16109c8b179e652a8365b3e16e547ec Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 13 Sep 2022 21:22:02 +0100 Subject: [PATCH 058/248] Revert "build optimized: fix admonitions (#118)" This reverts commit 42f53d1133c3606cd3ef4f5446b7aafeb7c502b9. --- docs/tutorials/build-optimized.mdx | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index b86a04993..e386f4402 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -8,18 +8,9 @@ import TabItem from "@theme/TabItem"; Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. -:::info +:::info Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. ::: -Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. - -::: - - -:::info - -All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. - -::: +:::info All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: [configure the release profile]: create-a-project#configure-the-release-profile From d7398f2cb87163334d644849b675ef8aab324ad0 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 13 Sep 2022 21:22:31 +0100 Subject: [PATCH 059/248] Revert "ran a linter on the docs" This reverts commit c7984f63996fee7fab06fa97d5e31bc482b7b09c. --- docs/getting-started/quick-start.mdx | 39 +++++++++++++++++++-------- docs/getting-started/setup.mdx | 20 +++++++++----- docs/tutorials/build-and-run.mdx | 19 ++++++++----- docs/tutorials/build-optimized.mdx | 30 ++++++++++++++------- docs/tutorials/create-a-project.mdx | 33 ++++++++++++++++------- docs/tutorials/testing.mdx | 40 ++++++++++++++++++++-------- docs/tutorials/write-a-contract.mdx | 27 ++++++++++++++----- 7 files changed, 148 insertions(+), 60 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 503a01b4c..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -3,9 +3,10 @@ sidebar_position: 3 title: Quick Start --- -Once you've [Setup] your development environment, you're ready to create your first Soroban contract. +Once you've [Setup] your development environment, you're ready to create your +first Soroban contract. -[setup]: setup.mdx +[Setup]: setup.mdx ## Create New Project @@ -28,7 +29,10 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. -:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: +:::caution +The `soroban-sdk` is in early development. Report issues +[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). +::: ```toml [lib] @@ -54,11 +58,20 @@ codegen-units = 1 lto = true ``` -The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. -:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: -The config for the `release` profile configures the Rust toolchain to produce smaller contracts. +The config for the `release` profile configures the Rust toolchain to produce +smaller contracts. ## Write the Code @@ -127,11 +140,14 @@ A `.wasm` file should be outputted in the `target` directory: target/wasm32-unknown-unknown/release/first_project.wasm ``` -:::info Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. ::: +:::info +Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. +::: ## Run the Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in the contract. +If you have [`soroban-cli`] installed, you can invoke contract functions in the +contract. ```sh soroban-cli invoke \ @@ -144,9 +160,10 @@ soroban-cli invoke \ You should see the following output: ```json -["Hello", "friend"] +["Hello","friend"] ``` [`soroban-cli`]: setup#install-the-soroban-cli -[rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 086fd42ac..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -13,7 +13,9 @@ To build and develop contracts you need only a couple prerequisites: ## Install Rust -If you use macOS, Linux, or another Unix-like OS, the simplest method to install a Rust toolchain is to install `rustup`. Install `rustup` with the following command. +If you use macOS, Linux, or another Unix-like OS, the simplest method to install +a Rust toolchain is to install `rustup`. Install `rustup` with the following +command. ``` curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh @@ -30,12 +32,14 @@ https://www.rust-lang.org/tools/install ## Configure an Editor -Many editors have support for Rust. Visit the following link to find out how to configure your editor: +Many editors have support for Rust. Visit the following link to find out how to +configure your editor: https://www.rust-lang.org/tools ## Install the Soroban CLI -The Soroban CLI can execute Soroban contracts in the same environment the contract will execute on network, however in a local sandbox. +The Soroban CLI can execute Soroban contracts in the same environment the +contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. @@ -43,7 +47,10 @@ Install the Soroban CLI using `cargo install`. cargo install --locked --version 0.0.4 soroban-cli ``` -:::caution The `soroban-cli` is in early development. Report issues [here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: +:::caution +The `soroban-cli` is in early development. Report issues +[here](https://github.com/stellar/soroban-cli/issues/new/choose). +::: ### Usage @@ -75,5 +82,6 @@ SUBCOMMANDS: completion Print shell completion code for the specified shell ``` -[rust]: https://www.rust-lang.org/ -[soroban cli]: setup#install-the-soroban-cli + +[Rust]: https://www.rust-lang.org/ +[Soroban CLI]: setup#install-the-soroban-cli diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 0d8d33972..1ca3fdcae 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,13 +5,15 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban-cli`], use the `cargo build` command. +To build a Soroban contract to deploy or run with the [`soroban-cli`], use the +`cargo build` command. ```sh cargo build --target wasm32-unknown-unknown --release ``` -A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. +A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is +the built contract. ``` target/wasm32-unknown-unknown/release/[project_name].wasm @@ -19,9 +21,12 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban-cli`] installed, you can invoke contract functions that have been built. +If you have the [`soroban-cli`] installed, you can invoke contract functions +that have been built. -Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `friend`. +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file +we built in [Build and Run] run the following command to invoke the `hello` +function with a single argument `friend`. ```sh soroban-cli invoke \ @@ -34,9 +39,9 @@ soroban-cli invoke \ The following output should appear. ```json -["Hello", "friend"] +["Hello","friend"] ``` [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[write a contract]: write-a-contract -[build and run]: build-and-run +[Write a Contract]: write-a-contract +[Build and Run]: build-and-run diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index e386f4402..a62974c03 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -3,16 +3,25 @@ sidebar_position: 8 title: Build Optimized --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. +Building optimized contracts to be as small as possible requires some additional +tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. -:::info Building optimized contracts is only necessary when deploying to network or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. ::: +:::info +Building optimized contracts is only necessary when deploying to network or when +analyzing and profiling a contract to get it as small as possible. If you're +just starting out writing a contract, these steps are not necessary. +::: -:::info All contracts are optimized to some degree by the project's `release` profile. It is highly recommended to use the release profile outlined in [Configure the Release Profile], otherwise the contract will be too large to deploy or run. ::: +:::info +All contracts are optimized to some degree by the project's `release` profile. +It is highly recommended to use the release profile outlined in [Configure the +Release Profile], otherwise the contract will be too large to deploy or run. +::: -[configure the release profile]: create-a-project#configure-the-release-profile +[Configure the Release Profile]: create-a-project#configure-the-release-profile ## Install Rust `nightly` @@ -26,7 +35,8 @@ rustup component add --toolchain nightly rust-src ## Install `wasm-opt` -To install `wasm-opt`, install `binaryen`. Depending on your operating system there may be different ways to install it. +To install `wasm-opt`, install `binaryen`. Depending on your operating system +there may be different ways to install it. @@ -50,14 +60,16 @@ https://github.com/WebAssembly/binaryen/releases -For install options see: https://github.com/WebAssembly/binaryen/releases +For install options see: +https://github.com/WebAssembly/binaryen/releases ## Building with `nightly` and `wasm-opt` -Then build your contract using nightly, and the additional options that remove unnecessary information from the contract. +Then build your contract using nightly, and the additional options that remove +unnecessary information from the contract. ```sh cargo +nightly build \ diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index bd47aa390..27e2eb889 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -3,9 +3,10 @@ sidebar_position: 1 title: Create a Project --- -Once you've [Setup] your development environment, you're ready to create Soroban contracts. Creating projects is done using the Rust tool, `cargo`. +Once you've [Setup] your development environment, you're ready to create Soroban +contracts. Creating projects is done using the Rust tool, `cargo`. -[setup]: ../getting-started/setup.mdx +[Setup]: ../getting-started/setup.mdx Create a new Rust library using the `cargo new` command. @@ -33,9 +34,13 @@ crate-type = ["cdylib", "rlib"] ## Import `soroban-sdk` and Features -Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. +Add the following sections to the `Cargo.toml` that will import the +`soroban-sdk`, and configure a set of features explained below. -:::caution The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: +:::caution +The `soroban-sdk` is in early development. Report issues +[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). +::: ```toml [dependencies] @@ -48,13 +53,23 @@ soroban-sdk = { version = "0.0.4", features = ["testutils"] } testutils = ["soroban-sdk/testutils"] ``` -The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. +The `features` list includes a `testutils` feature, which will cause additional +test utilities to be generated for calling the contract in tests. -:::info The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. ::: +:::info +The `testutils` test utilities are automatically enabled inside [Rust unit +tests] inside the same crate as your contract. If you write [Rust integration +tests], or write tests from another crate, you'll need to add `#[cfg(feature = +"testutils")]` to those tests and enable the `testutils` feature when running +your tests with `cargo test --features testutils` to be able to use those test +utilities. +::: ## Configure the `release` Profile -Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, without these configurations almost always exceed this size. +Configuring the `release` profile to optimize the contract build is critical. +Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, +without these configurations almost always exceed this size. Add the following to your `Cargo.toml`. @@ -98,5 +113,5 @@ codegen-units = 1 lto = true ``` -[rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 0648f871c..5653bc0d2 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -3,12 +3,14 @@ sidebar_position: 5 title: Testing --- -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; -Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. +Writing tests for Soroban contracts involves writing Rust code using the test +facilities and toolchain that you'd use for testing any Rust code. -Given a simple contract like the contract demonstrated in [Write a Contract](write-a-contract.mdx), a simple test will look like this. +Given a simple contract like the contract demonstrated in [Write a +Contract](write-a-contract.mdx), a simple test will look like this. @@ -51,25 +53,42 @@ fn test() { } ``` + -:::info The above example is a [Rust unit test] that lives inside the `src/` directory. Note that if you place the test in the `tests/` directory it becomes a [Rust integration test] with the test being compiled separately. Integration tests require `#![cfg(feature = "testutils")]` at the top of the file and to be run with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to enable the generated Soroban test utilities. ::: +:::info +The above example is a [Rust unit test] that lives inside the `src/` directory. +Note that if you place the test in the `tests/` directory it becomes a [Rust +integration test] with the test being compiled separately. Integration tests +require `#![cfg(feature = "testutils")]` at the top of the file and to be run +with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to +enable the generated Soroban test utilities. +::: + -In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. +In any test the first thing that is always required is an `Env`, which is the +Soroban environment that the contract will run inside of. ```rust let env = Env::default(); ``` -Contracts must be registered with the environment with a contract ID, which is a 32-byte value. In many cases it is sufficient to use a simple zero ID, however if the test will deploy the contract multiple times, or deploy multiple contracts, each should use their own IDs. +Contracts must be registered with the environment with a contract ID, which is a +32-byte value. In many cases it is sufficient to use a simple zero ID, however +if the test will deploy the contract multiple times, or deploy multiple +contracts, each should use their own IDs. ```rust let contract_id = BytesN::from_array(&env, &[0; 32]); env.register_contract(&contract_id, Contract); ``` -All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `Contract`, and the client is named `ContractClient`. +All public functions within an `impl` block that is annotated with the +`#[contractimpl]` attribute have a corresponding function generated in a +generated client type. The client type will be named the same as the contract +type with `Client` appended. For example, in our contract the contract type is +`Contract`, and the client is named `ContractClient`. ```rust let client = ContractClient::new(&env, &contract_id); @@ -77,7 +96,6 @@ let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: - ```rust assert_eq!( words, @@ -100,5 +118,5 @@ test test::test ... ok Try changing the values in the test to see how it works. -[rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 42b3746b8..b617e3a62 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -3,21 +3,31 @@ sidebar_position: 4 title: Write a Contract --- -Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in the projects `lib.rs` file. +Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in +the projects `lib.rs` file. ```rust #![no_std] ``` -All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains. +All contracts should begin with `#![no_std]` to ensure that the Rust standard +library is not included in the build. The Rust standard library is large and not +well suited to being deployed into small programs like those deployed to +blockchains. ```rust use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` -The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project] to see how to setup a project. +The contract will need to import the types and macros that it needs from the +`soroban-sdk` crate. Take a look at [Create a Project] to see +how to setup a project. -Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. +Many of the types available in typical Rust programs, such as `std::vec::Vec`, +are not available, as there is no allocator and no heap memory in Soroban +contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, +`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban +environment's memory and native capabilities. ```rust pub struct Contract; @@ -30,7 +40,11 @@ impl Contract { } ``` -Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +Contract functions live inside an `impl` for a struct. The `impl` block is +annotated with `#[contractimpl]`. Functions that are intended to be called +externally should be marked with `pub` visibility. The first argument can be +an `Env` argument to get a copy of the Soroban environment, which is necessary +for most things. Putting those pieces together a simple contract will look like this. @@ -47,5 +61,4 @@ impl Contract { } } ``` - -[create a project]: create-a-project.mdx +[Create a Project]: create-a-project.mdx From a9f61bc7b90850147cd6c0904920842d21c5994b Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 4 Oct 2022 00:10:10 -0700 Subject: [PATCH 060/248] Rename soroban-cli to soroban --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 16 ++++++++-------- docs/tutorials/build-and-run.mdx | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3e6e1acd7..6e59517cf 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -146,11 +146,11 @@ Hyphens in Rust crate names are replaced by underscores in code and generated fi ## Run the Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in the +If you have [`soroban`] installed, you can invoke contract functions in the contract. ```sh -soroban-cli invoke \ +soroban invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -163,7 +163,7 @@ You should see the following output: ["Hello","friend"] ``` -[`soroban-cli`]: setup#install-the-soroban-cli +[`soroban`]: setup#install-the-soroban [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4070513b0..0f2863fd7 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -48,25 +48,25 @@ cargo install --locked --version 0.0.4 soroban-cli ``` :::caution -The `soroban-cli` is in early development. Report issues -[here](https://github.com/stellar/soroban-cli/issues/new/choose). +The `soroban` is in early development. Report issues +[here](https://github.com/stellar/soroban/issues/new/choose). ::: ### Usage -Run the `soroban-cli` command and you should see output like below. +Run the `soroban` command and you should see output like below. ```sh -soroban-cli +soroban ``` ``` -❯ soroban-cli -soroban-cli 0.0.4 +❯ soroban +soroban 0.0.4 https://soroban.stellar.org USAGE: - soroban-cli + soroban OPTIONS: -h, --help Print help information @@ -84,4 +84,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: setup#install-the-soroban-cli +[Soroban CLI]: setup#install-the-soroban diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 1ca3fdcae..cff70353b 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,7 +5,7 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban-cli`], use the +To build a Soroban contract to deploy or run with the [`soroban`], use the `cargo build` command. ```sh @@ -21,7 +21,7 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban-cli`] installed, you can invoke contract functions +If you have the [`soroban`] installed, you can invoke contract functions that have been built. Using the code we wrote in [Write a Contract] and the resulting `.wasm` file @@ -29,7 +29,7 @@ we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `friend`. ```sh -soroban-cli invoke \ +soroban invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -42,6 +42,6 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[`soroban`]: ../getting-started/setup#install-the-soroban [Write a Contract]: write-a-contract [Build and Run]: build-and-run From 2f4a60f24350dc2ea23f05f2ffc0c0d827a15987 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 5 Oct 2022 16:35:47 -0700 Subject: [PATCH 061/248] Add deployer example (#138) --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 16 ++++++++-------- docs/tutorials/build-and-run.mdx | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 3e6e1acd7..6e59517cf 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -146,11 +146,11 @@ Hyphens in Rust crate names are replaced by underscores in code and generated fi ## Run the Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in the +If you have [`soroban`] installed, you can invoke contract functions in the contract. ```sh -soroban-cli invoke \ +soroban invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -163,7 +163,7 @@ You should see the following output: ["Hello","friend"] ``` -[`soroban-cli`]: setup#install-the-soroban-cli +[`soroban`]: setup#install-the-soroban [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4070513b0..0f2863fd7 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -48,25 +48,25 @@ cargo install --locked --version 0.0.4 soroban-cli ``` :::caution -The `soroban-cli` is in early development. Report issues -[here](https://github.com/stellar/soroban-cli/issues/new/choose). +The `soroban` is in early development. Report issues +[here](https://github.com/stellar/soroban/issues/new/choose). ::: ### Usage -Run the `soroban-cli` command and you should see output like below. +Run the `soroban` command and you should see output like below. ```sh -soroban-cli +soroban ``` ``` -❯ soroban-cli -soroban-cli 0.0.4 +❯ soroban +soroban 0.0.4 https://soroban.stellar.org USAGE: - soroban-cli + soroban OPTIONS: -h, --help Print help information @@ -84,4 +84,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: setup#install-the-soroban-cli +[Soroban CLI]: setup#install-the-soroban diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 1ca3fdcae..cff70353b 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,7 +5,7 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban-cli`], use the +To build a Soroban contract to deploy or run with the [`soroban`], use the `cargo build` command. ```sh @@ -21,7 +21,7 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban-cli`] installed, you can invoke contract functions +If you have the [`soroban`] installed, you can invoke contract functions that have been built. Using the code we wrote in [Write a Contract] and the resulting `.wasm` file @@ -29,7 +29,7 @@ we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `friend`. ```sh -soroban-cli invoke \ +soroban invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -42,6 +42,6 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[`soroban`]: ../getting-started/setup#install-the-soroban [Write a Contract]: write-a-contract [Build and Run]: build-and-run From e2eb27b666c4f3dd40676273bcfda3df3f2c080e Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 5 Oct 2022 16:40:47 -0700 Subject: [PATCH 062/248] Revert "Add deployer example (#138)" (#139) This reverts commit 2f4a60f24350dc2ea23f05f2ffc0c0d827a15987. --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 16 ++++++++-------- docs/tutorials/build-and-run.mdx | 8 ++++---- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 6e59517cf..3e6e1acd7 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -146,11 +146,11 @@ Hyphens in Rust crate names are replaced by underscores in code and generated fi ## Run the Contract -If you have [`soroban`] installed, you can invoke contract functions in the +If you have [`soroban-cli`] installed, you can invoke contract functions in the contract. ```sh -soroban invoke \ +soroban-cli invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -163,7 +163,7 @@ You should see the following output: ["Hello","friend"] ``` -[`soroban`]: setup#install-the-soroban +[`soroban-cli`]: setup#install-the-soroban-cli [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 0f2863fd7..4070513b0 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -48,25 +48,25 @@ cargo install --locked --version 0.0.4 soroban-cli ``` :::caution -The `soroban` is in early development. Report issues -[here](https://github.com/stellar/soroban/issues/new/choose). +The `soroban-cli` is in early development. Report issues +[here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: ### Usage -Run the `soroban` command and you should see output like below. +Run the `soroban-cli` command and you should see output like below. ```sh -soroban +soroban-cli ``` ``` -❯ soroban -soroban 0.0.4 +❯ soroban-cli +soroban-cli 0.0.4 https://soroban.stellar.org USAGE: - soroban + soroban-cli OPTIONS: -h, --help Print help information @@ -84,4 +84,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: setup#install-the-soroban +[Soroban CLI]: setup#install-the-soroban-cli diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index cff70353b..1ca3fdcae 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,7 +5,7 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban`], use the +To build a Soroban contract to deploy or run with the [`soroban-cli`], use the `cargo build` command. ```sh @@ -21,7 +21,7 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban`] installed, you can invoke contract functions +If you have the [`soroban-cli`] installed, you can invoke contract functions that have been built. Using the code we wrote in [Write a Contract] and the resulting `.wasm` file @@ -29,7 +29,7 @@ we built in [Build and Run] run the following command to invoke the `hello` function with a single argument `friend`. ```sh -soroban invoke \ +soroban-cli invoke \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ --id 1 \ --fn hello \ @@ -42,6 +42,6 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban`]: ../getting-started/setup#install-the-soroban +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli [Write a Contract]: write-a-contract [Build and Run]: build-and-run From b5db45d39e97a6f7f91930ee28fce84941c24dc5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 5 Oct 2022 23:21:13 -0700 Subject: [PATCH 063/248] Add logging example (#148) --- docs/getting-started/quick-start.mdx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 6e59517cf..c89dd3926 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -56,6 +56,10 @@ debug-assertions = false panic = "abort" codegen-units = 1 lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true ``` The `features` list includes a `testutils` feature, which will cause additional @@ -71,7 +75,13 @@ utilities. ::: The config for the `release` profile configures the Rust toolchain to produce -smaller contracts. +smaller contracts when built with the `--release` or `--profile release` option. + +The config for the `release-with-logs` profile enables contract logs when +building with `--profile release-with-logs` option. See the [logging example] +for more details. + +[logging example]: ../examples/logging ## Write the Code From f3920640b6b70d573e3e9cdd1a3639d7ed6403fc Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 6 Oct 2022 00:35:46 -0700 Subject: [PATCH 064/248] Update examples (#150) --- docs/getting-started/quick-start.mdx | 3 +-- docs/tutorials/testing.mdx | 13 +++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index c89dd3926..7e2d8aafc 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -108,8 +108,7 @@ mod test { #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); - env.register_contract(&contract_id, Contract); + let contract_id = env.register_contract(None, Contract); let client = ContractClient::new(&env, &contract_id); let words = client.hello(&symbol!("Dev")); diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 5653bc0d2..220657245 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -41,8 +41,7 @@ use soroban_sdk::{symbol, vec, BytesN, Env}; #[test] fn test() { let env = Env::default(); - let contract_id = BytesN::from_array(&env, &[0; 32]); - env.register_contract(&contract_id, Contract); + let contract_id = env.register_contract(None, Contract); let client = ContractClient::new(&env, &contract_id); let words = client.hello(&symbol!("Dev")); @@ -74,14 +73,12 @@ Soroban environment that the contract will run inside of. let env = Env::default(); ``` -Contracts must be registered with the environment with a contract ID, which is a -32-byte value. In many cases it is sufficient to use a simple zero ID, however -if the test will deploy the contract multiple times, or deploy multiple -contracts, each should use their own IDs. +The contract is registered with the environment using the contract type. +Contracts can specify a fixed contract ID as the first argument, or provide +`None` and one will be generated. ```rust -let contract_id = BytesN::from_array(&env, &[0; 32]); -env.register_contract(&contract_id, Contract); +let contract_id = env.register_contract(None, Contract); ``` All public functions within an `impl` block that is annotated with the From 379e375cba1967785cde855642cb4099b7615e9f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 6 Oct 2022 08:24:43 -0700 Subject: [PATCH 065/248] Fix soroban-cli links (#152) --- docs/getting-started/quick-start.mdx | 4 ++-- docs/tutorials/build-and-run.mdx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 7e2d8aafc..0c0f680cb 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -155,7 +155,7 @@ Hyphens in Rust crate names are replaced by underscores in code and generated fi ## Run the Contract -If you have [`soroban`] installed, you can invoke contract functions in the +If you have [`soroban-cli`] installed, you can invoke contract functions in the contract. ```sh @@ -172,7 +172,7 @@ You should see the following output: ["Hello","friend"] ``` -[`soroban`]: setup#install-the-soroban +[`soroban-cli`]: setup#install-the-soroban [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index cff70353b..1559a9ea7 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -5,7 +5,7 @@ title: Build and Run ## Build a Contract -To build a Soroban contract to deploy or run with the [`soroban`], use the +To build a Soroban contract to deploy or run with the [`soroban-cli`], use the `cargo build` command. ```sh @@ -21,7 +21,7 @@ target/wasm32-unknown-unknown/release/[project_name].wasm ## Run a Contract -If you have the [`soroban`] installed, you can invoke contract functions +If you have the [`soroban-cli`] installed, you can invoke contract functions that have been built. Using the code we wrote in [Write a Contract] and the resulting `.wasm` file @@ -42,6 +42,6 @@ The following output should appear. ["Hello","friend"] ``` -[`soroban`]: ../getting-started/setup#install-the-soroban [Write a Contract]: write-a-contract [Build and Run]: build-and-run +[`soroban-cli`]: ../getting-started/setup#install-the-soroban From d99c04ca8d7a52e30445754ab841e696556cf631 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 6 Oct 2022 13:52:00 -0700 Subject: [PATCH 066/248] Fix soroban-cli links (#155) --- docs/getting-started/quick-start.mdx | 2 +- docs/getting-started/setup.mdx | 2 +- docs/tutorials/build-and-run.mdx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 0c0f680cb..e932bfc0d 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -172,7 +172,7 @@ You should see the following output: ["Hello","friend"] ``` -[`soroban-cli`]: setup#install-the-soroban +[`soroban-cli`]: setup#install-the-soroban-cli [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 0f2863fd7..2b3beadc4 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -84,4 +84,4 @@ SUBCOMMANDS: [Rust]: https://www.rust-lang.org/ -[Soroban CLI]: setup#install-the-soroban +[Soroban CLI]: setup#install-the-soroban-cli diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 1559a9ea7..9da8e191f 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -44,4 +44,4 @@ The following output should appear. [Write a Contract]: write-a-contract [Build and Run]: build-and-run -[`soroban-cli`]: ../getting-started/setup#install-the-soroban +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 537b7a6f9390d65f8925e48c0e0ed94f7a2e31fc Mon Sep 17 00:00:00 2001 From: Giuliano Date: Fri, 7 Oct 2022 16:06:05 -0700 Subject: [PATCH 067/248] Add `mod test;` to lib.rs and use `first_project` (#160) --- docs/tutorials/build-and-run.mdx | 2 +- docs/tutorials/build-optimized.mdx | 2 +- docs/tutorials/testing.mdx | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx index 1ca3fdcae..d5eafa3b1 100644 --- a/docs/tutorials/build-and-run.mdx +++ b/docs/tutorials/build-and-run.mdx @@ -16,7 +16,7 @@ A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. ``` -target/wasm32-unknown-unknown/release/[project_name].wasm +target/wasm32-unknown-unknown/release/first_project.wasm ``` ## Run a Contract diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index a62974c03..f8a0f6991 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -84,5 +84,5 @@ Then additionally use `wasm-opt` to further minimize the size of the `.wasm`. ```sh wasm-opt -Oz \ target/wasm32-unknown-unknown/release/first_project.wasm \ - -o target/wasm32-unknown-unknown/release/first-project-optimized.wasm + -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm ``` diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 5653bc0d2..2312820d3 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -27,6 +27,9 @@ impl Contract { vec![&env, symbol!("Hello"), to] } } + +#[cfg(test)] +mod test; ``` From 2f0a784511493d145ad2c837b58653a1cc53d8c9 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 8 Oct 2022 20:33:04 -0700 Subject: [PATCH 068/248] Add run in pages (#179) --- docs/tutorials/build-and-run.mdx | 47 ----------- docs/tutorials/build-optimized.mdx | 2 +- docs/tutorials/build.mdx | 22 +++++ docs/tutorials/run-on-local-network.mdx | 106 ++++++++++++++++++++++++ docs/tutorials/run-on-sandbox.mdx | 39 +++++++++ 5 files changed, 168 insertions(+), 48 deletions(-) delete mode 100644 docs/tutorials/build-and-run.mdx create mode 100644 docs/tutorials/build.mdx create mode 100644 docs/tutorials/run-on-local-network.mdx create mode 100644 docs/tutorials/run-on-sandbox.mdx diff --git a/docs/tutorials/build-and-run.mdx b/docs/tutorials/build-and-run.mdx deleted file mode 100644 index 033b16cdc..000000000 --- a/docs/tutorials/build-and-run.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 6 -title: Build and Run ---- - -## Build a Contract - -To build a Soroban contract to deploy or run with the [`soroban-cli`], use the -`cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is -the built contract. - -``` -target/wasm32-unknown-unknown/release/first_project.wasm -``` - -## Run a Contract - -If you have the [`soroban-cli`] installed, you can invoke contract functions -that have been built. - -Using the code we wrote in [Write a Contract] and the resulting `.wasm` file -we built in [Build and Run] run the following command to invoke the `hello` -function with a single argument `friend`. - -```sh -soroban invoke \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ - --id 1 \ - --fn hello \ - --arg friend -``` - -The following output should appear. - -```json -["Hello","friend"] -``` - -[Write a Contract]: write-a-contract -[Build and Run]: build-and-run -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index f8a0f6991..55a0a5529 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 title: Build Optimized --- diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx new file mode 100644 index 000000000..b531af4ea --- /dev/null +++ b/docs/tutorials/build.mdx @@ -0,0 +1,22 @@ +--- +sidebar_position: 6 +title: Build +--- + +To build a Soroban contract to deploy or run, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is +the built contract. + +``` +target/wasm32-unknown-unknown/release/first_project.wasm +``` + +The `.wasm` file contains the logic of the contract, as well as a the contracts +specification that can be imported into other contracts who wish to call it. +This is the only artifact needed to deploy the contract, share the interface +with others, or integration test against the contract. diff --git a/docs/tutorials/run-on-local-network.mdx b/docs/tutorials/run-on-local-network.mdx new file mode 100644 index 000000000..4872087b6 --- /dev/null +++ b/docs/tutorials/run-on-local-network.mdx @@ -0,0 +1,106 @@ +--- +sidebar_position: 8 +title: Run on a Local Network +--- + +If you have Docker installed, you can run a local standalone network with the +Stellar Quickstart Docker image. + +The Quickstart image is a single container that runs everything you need to test +against a fully featured network. It contains a Stellar node, Soroban RPC +server, Horizon server, and Friendbot server. + +If you have the [`soroban-cli`] installed, you can deploy contracts to a network +and invoke those functions from the command line. + +:::info +It's also possible to run a contract in the local sandbox environment without a +network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. +::: + +To run a local standalone network with the Stellar Quickstart Docker image, +run the following command. + +```sh +docker run --rm -it \ + -p 8000:8000 \ + --name stellar \ + stellar/quickstart:soroban-dev \ + --standalone \ + --enable-soroban-rpc +``` + +Once the image is started you can check its status by querying the Horizon API: +```sh +curl http://localhost:8000 +``` + +Generate a key for use on the local sandbox environment by going to the [Stellar +Laboratory]. Make note of both the G... and S... keys. The G... key is the +public key and will also be the account ID. The S... key is the secret key and +is what you'll use to control the account. + +:::tip +It's a good security practice to never use the same keys for testing and +development that you use do for the public Stellar network. Generate new keys +for testing and development and avoid ever using them for other purposes. +::: + +Create an account on the local sandbox environment by making a request to the +local Friendbot. Specify as the `addr` the G... key of your account. + +```sh +curl http://localhost:8000/?addr=G... +``` + +Once you have an account on the network, we'll use the code we wrote in [Write a +Contract] and the resulting `.wasm` file we built in [Build] as our contract to +deploy. Run the following commands to deploy the contract to the network. Use +the S... key as the secret key. + +```sh +soroban deploy \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --rpc-url http://localhost:8000/soroban/rpc \ + --network-passphrase 'Standalone Network ; February 2017' + --secret-key S... +``` + +:::tip +It's a good practice to avoid putting secret keys on the command line. You can +also specify the secret key by setting the environment variable +`SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the +future there will be more secure ways to provide a secret key, such as via +hardware keys. +::: + +A contract ID will be outputted. + +``` +cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 +``` + +Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the +`hello` function with a single argument `friend`. + +```sh +soroban invoke + --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 + --rpc-url http://localhost:8000/soroban/rpc + --network-passphrase 'Standalone Network ; February 2017' + --secret-key S... + --fn hello + --arg friend +``` + +The following output should appear. + +```json +["Hello","friend"] +``` + +[Write a Contract]: write-a-contract +[Run on a Local Network]: run-on-local-network +[Build]: build +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx new file mode 100644 index 000000000..d4915b7cc --- /dev/null +++ b/docs/tutorials/run-on-sandbox.mdx @@ -0,0 +1,39 @@ +--- +sidebar_position: 7 +title: Run on Sandbox +--- + +If you have the [`soroban-cli`] installed, you can run contracts in a local +sandbox environment. + +The Soroban sandbox environment is the same Soroban environment that runs on +Stellar networks, but it runs without nodes, and without the other features you +find on a Stellar network. + +:::info +It's also possible to run a contract on a fully featured local network. See +[Run on a Local Network] for more details. +::: + +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file +we built in [Build] run the following command to invoke the `hello` +function with a single argument `friend`. + +```sh +soroban invoke \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --id 1 \ + --fn hello \ + --arg friend +``` + +The following output should appear. + +```json +["Hello","friend"] +``` + +[Write a Contract]: write-a-contract +[Run on a Local Network]: run-on-local-network +[Build]: build +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 3533691b73304438371c954d9f6e39cd67530238 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 8 Oct 2022 20:36:08 -0700 Subject: [PATCH 069/248] Tweaks to run on local network page --- docs/tutorials/run-on-local-network.mdx | 41 ++++++++++++++----------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/docs/tutorials/run-on-local-network.mdx b/docs/tutorials/run-on-local-network.mdx index 4872087b6..a417ff90d 100644 --- a/docs/tutorials/run-on-local-network.mdx +++ b/docs/tutorials/run-on-local-network.mdx @@ -1,17 +1,20 @@ --- sidebar_position: 8 -title: Run on a Local Network +title: Run on Local Network --- If you have Docker installed, you can run a local standalone network with the -Stellar Quickstart Docker image. +[Stellar Quickstart] Docker image. The Quickstart image is a single container that runs everything you need to test -against a fully featured network. It contains a Stellar node, Soroban RPC -server, Horizon server, and Friendbot server. +against a fully featured network. It contains: -If you have the [`soroban-cli`] installed, you can deploy contracts to a network -and invoke those functions from the command line. +- Stellar Core – Node software that runs the network, coordinates consensus, and +finalizes ledgers. +- Soroban RPC server – JSON RPC server for interacting with Soroban contracts. +- Horizon server – HTTP API for access ledger state and historical transactions. +- Friendbot server – HTTP API for creating and funding new accounts on test +networks. :::info It's also possible to run a contract in the local sandbox environment without a @@ -36,18 +39,18 @@ curl http://localhost:8000 ``` Generate a key for use on the local sandbox environment by going to the [Stellar -Laboratory]. Make note of both the G... and S... keys. The G... key is the -public key and will also be the account ID. The S... key is the secret key and -is what you'll use to control the account. +Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the +public key and will also be the account ID. The `S...` key is the secret key and +is that you use to control the account. :::tip -It's a good security practice to never use the same keys for testing and -development that you use do for the public Stellar network. Generate new keys -for testing and development and avoid ever using them for other purposes. +It's a good practice to never use the same keys for testing and development that +you use do for the public Stellar network. Generate new keys for testing and +development and avoid ever using them for other purposes. ::: Create an account on the local sandbox environment by making a request to the -local Friendbot. Specify as the `addr` the G... key of your account. +local Friendbot. Specify as the `addr` the `G...` key of your account. ```sh curl http://localhost:8000/?addr=G... @@ -56,21 +59,21 @@ curl http://localhost:8000/?addr=G... Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use -the S... key as the secret key. +the `S...` key as the secret key. ```sh soroban deploy \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --secret-key S... --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' - --secret-key S... ``` :::tip -It's a good practice to avoid putting secret keys on the command line. You can +It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the -future there will be more secure ways to provide a secret key, such as via +future there will be other secure ways to provide a secret key, such as via hardware keys. ::: @@ -86,9 +89,9 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the ```sh soroban invoke --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 + --secret-key S... --rpc-url http://localhost:8000/soroban/rpc --network-passphrase 'Standalone Network ; February 2017' - --secret-key S... --fn hello --arg friend ``` @@ -104,3 +107,5 @@ The following output should appear. [Build]: build [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli [Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test +[Run on Sandbox]: run-on-sandbox +[Stellar Quickstart]: https://github.com/stellar/quickstart From f86efcc9fc08ec0531ec2f6a6c7871ccea8e516c Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 8 Oct 2022 23:39:19 -0700 Subject: [PATCH 070/248] Move the FAQ to the top level (#182) --- docs/faq.mdx | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 docs/faq.mdx diff --git a/docs/faq.mdx b/docs/faq.mdx new file mode 100644 index 000000000..954e81ec5 --- /dev/null +++ b/docs/faq.mdx @@ -0,0 +1,40 @@ +--- +sidebar_position: 8 +title: Soroban on Stellar FAQ +--- + +:::caution +Soroban's Stellar integration is under active-development and may change. +::: + +### What is Soroban to Stellar? Is it a new blockchain? +Soroban is not a new blockchain. Soroban is a Smart contract platform that is integrated into the existing Stellar blockchain. It is an *additive* feature that lives alongside, and doesn't replace, the existing set of Stellar operations. + +### How do I invoke a Soroban contract on Stellar? +A Soroban contract can be invoked by submitting a transaction that contains the new operation: `InvokeContractOp`. + +### Can Soroban contracts use Stellar accounts for authentication? +Yes. Stellar accounts are shared with Soroban. Smart contacts have access to Stellar account signer configuration and know the source account that directly invoked them in a transaction. Check out the Auth and Advanced Auth examples for more information. + +### Can Soroban contracts interact with Stellar Assets? +Yes. Soroban contains a built-in token contract that is able to import a balance from a Stellar trust line into an equivalent Soroban balance and also to export it back to the Stellar trust line. Check out the built-in token for more information on token capabilities, and the token interface for building your own tokens with custom behaviors. +*Note 1: This means that one account can simultaneously have two balances of the same asset: once in a Stellar trust line and one in a Soroban token balance. This bears some similarity to the relationship between ETH and WETH on Ethereum.* +*Note 2: Tokens that have been issued on Soroban can not be exported to a Stellar trust line.* + +### Do Issuers of Stellar Assets maintain their authorization over an asset that has been imported to Soroban? (AUTH_REQUIRED, AUTH_REVOCABLE, AUTH_CLAWBACK) +Yes. Issuers retain the same level of control on Soroban as they have on Classic . This functionality is accessible through a set of admin functions (freeze, burn) on the built in Soroban token contract. + +### Can Soroban contracts interact with any other Stellar operations? +No. Aside from the interactions with Accounts and Assets as mentioned above. This means that Soroban contracts can not interact with SDEX, AMMs, Claimable Balances or Sponsorships. + +### Does the Stellar base reserve apply to Soroban contracts? +No. Soroban has a different fee structure and ledger entries that are allocated by Soroban contracts do not add to an account's required minimal balance. + +### Should I issue my token as a Stellar Asset or a Soroban token? +We recommend, to the extent possible, issuing tokens as Stellar assets. These tokens will benefit from being interopable with the existing ecosystem of tools available in the Stellar ecosystem, and will be usable on Soroban through import/export functionality. + +### How should Wallets handle Accounts having a Stellar and Soroban balance? +Best practices are still being explored. At this time we recommend: (1) displaying separate balances for Soroban and Stellar Assets, (2) allowing users to import/export between them and (3) executing payments based on the origin: Stellar payments for trust lines and Soroban token transfers for Soroban token balances + +### Haven't found what you're looking for? +Join #soroban on the Stellar developer discord From f801c2d057ef5670838c5b118d002182a1194523 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 8 Oct 2022 23:56:47 -0700 Subject: [PATCH 071/248] Add vscode links (#184) --- docs/getting-started/setup.mdx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 2b3beadc4..aa55c960a 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -36,6 +36,16 @@ Many editors have support for Rust. Visit the following link to find out how to configure your editor: https://www.rust-lang.org/tools +A popular editor is Visual Studio Code: + +- [Visual Studio Code] editor. +- [Rust Analyzer] for Rust language support. +- [CodeLLDB] for step-through-debugging. + +[Visual Studio Code]: https://code.visualstudio.com +[Rust Analyzer]: https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer +[CodeLLDB]: https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb + ## Install the Soroban CLI The Soroban CLI can execute Soroban contracts in the same environment the From 71a30f19463c315eeed3050ce788a1a4877170bd Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:03:02 -0700 Subject: [PATCH 072/248] Update versions of sdks and tools (#185) --- docs/getting-started/quick-start.mdx | 4 ++-- docs/getting-started/setup.mdx | 8 +++++--- docs/tutorials/create-a-project.mdx | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index e932bfc0d..1558ed79e 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -42,10 +42,10 @@ crate-type = ["cdylib", "rlib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.1.0" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +soroban-sdk = { version = "0.1.0", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index aa55c960a..e030cb896 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.0.4 soroban-cli +cargo install --locked --version 0.1.0 soroban-cli ``` :::caution @@ -71,8 +71,8 @@ soroban ``` ``` -❯ soroban -soroban 0.0.4 +❯ soroban -h +soroban 0.1.0 https://soroban.stellar.org USAGE: @@ -86,8 +86,10 @@ SUBCOMMANDS: inspect Inspect a WASM file listing contract functions, meta, etc read Print the current value of a contract-data ledger entry serve Run a local webserver for web app development and testing + token Wrap, create, and manage token contracts deploy Deploy a WASM file as a contract gen Generate code client bindings for a contract + xdr Decode xdr version Print version information completion Print shell completion code for the specified shell ``` diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 27e2eb889..faaeea3e7 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.1.0" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +soroban-sdk = { version = "0.1.0", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -97,10 +97,10 @@ crate-type = ["cdylib", "rlib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.0.4" +soroban-sdk = "0.1.0" [dev_dependencies] -soroban-sdk = { version = "0.0.4", features = ["testutils"] } +soroban-sdk = { version = "0.1.0", features = ["testutils"] } [profile.release] opt-level = "z" From cdaa4c1ab04a80250fe8ddee66711decea652411 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:09:02 -0700 Subject: [PATCH 073/248] Remove out-dated recommendation about testutils feature (#187) --- docs/tutorials/testing.mdx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 1cd726f95..53733026b 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -59,16 +59,6 @@ fn test() { -:::info -The above example is a [Rust unit test] that lives inside the `src/` directory. -Note that if you place the test in the `tests/` directory it becomes a [Rust -integration test] with the test being compiled separately. Integration tests -require `#![cfg(feature = "testutils")]` at the top of the file and to be run -with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to -enable the generated Soroban test utilities. -::: - - In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. From e5c8d8143a8da31ac59226c98370becb2d3a76b8 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:11:24 -0700 Subject: [PATCH 074/248] Tweak recommendation --- docs/tutorials/create-a-project.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index faaeea3e7..2f37882f3 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -58,11 +58,10 @@ test utilities to be generated for calling the contract in tests. :::info The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. +tests] inside the same crate as your contract. If you write tests from another +crate, you'll need to require the `testutils` feature for those tests and enable +the `testutils` feature when running your tests with `cargo test +--features testutils` to be able to use those test utilities. ::: ## Configure the `release` Profile From b7a4854f369694ccf35c936e079b6cee8f239fc6 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:16:58 -0700 Subject: [PATCH 075/248] Add details about building with logs to project setup (#188) --- docs/tutorials/create-a-project.mdx | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 2f37882f3..ad93c97a5 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -70,7 +70,8 @@ Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, without these configurations almost always exceed this size. -Add the following to your `Cargo.toml`. +Add the following to your `Cargo.toml` and use the `release` profile when +building. ```toml [profile.release] @@ -84,6 +85,26 @@ codegen-units = 1 lto = true ``` +## Configure the `release-with-logs` Profile + +Configuring a `release-with-logs` profile can be useful for if you need to build +a `.wasm` that has logs enabled for printing debug logs when using the +[`soroban-cli`]. Note that this is not necessary to access debug logs in tests +or to use a step-through-debugger. + +Add the following to your `Cargo.toml` and use the `release-with-logs` profile +when you need logs. + +```toml +[profile.release-with-logs] +inherits = "release" +debug-assertions = true +``` + +See the [logging example] for more information about how to log. + +[logging example]: ../examples/logging.mdx + ## Wrapping it Up The steps below should produce a `Cargo.toml` that looks like so. @@ -110,7 +131,12 @@ debug-assertions = false panic = "abort" codegen-units = 1 lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true ``` [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 6b0b0195094f6af8137cfd9289ba96137d7f58c7 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:19:37 -0700 Subject: [PATCH 076/248] Update the links for reporting issues (#189) --- docs/getting-started/quick-start.mdx | 4 ++-- docs/getting-started/setup.mdx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 1558ed79e..4886f6525 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -29,8 +29,8 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. -:::caution -The `soroban-sdk` is in early development. Report issues +:::info +Report issues and share feedback about the `soroban-sdk` [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). ::: diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index e030cb896..5e3e603d3 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -57,8 +57,8 @@ Install the Soroban CLI using `cargo install`. cargo install --locked --version 0.1.0 soroban-cli ``` -:::caution -The `soroban` is in early development. Report issues +:::info +Report issues and share feedback about the Soroban CLI [here](https://github.com/stellar/soroban/issues/new/choose). ::: From 2c2d793083cfe825380c6370ceb762983c1bf3f4 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sun, 9 Oct 2022 00:32:21 -0700 Subject: [PATCH 077/248] Move the optimized build instructions inside the build page to shorten the list of tutorials (#190) --- docs/tutorials/build-optimized.mdx | 88 ------------------ docs/tutorials/build.mdx | 92 +++++++++++++++++++ ...etwork.mdx => deploy-to-local-network.mdx} | 2 +- .../invoking-contracts-with-transactions.mdx | 82 +++++++++++++++++ 4 files changed, 175 insertions(+), 89 deletions(-) delete mode 100644 docs/tutorials/build-optimized.mdx rename docs/tutorials/{run-on-local-network.mdx => deploy-to-local-network.mdx} (99%) create mode 100644 docs/tutorials/invoking-contracts-with-transactions.mdx diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx deleted file mode 100644 index 55a0a5529..000000000 --- a/docs/tutorials/build-optimized.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 9 -title: Build Optimized ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -Building optimized contracts to be as small as possible requires some additional -tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. - -:::info -Building optimized contracts is only necessary when deploying to network or when -analyzing and profiling a contract to get it as small as possible. If you're -just starting out writing a contract, these steps are not necessary. -::: - -:::info -All contracts are optimized to some degree by the project's `release` profile. -It is highly recommended to use the release profile outlined in [Configure the -Release Profile], otherwise the contract will be too large to deploy or run. -::: - -[Configure the Release Profile]: create-a-project#configure-the-release-profile - -## Install Rust `nightly` - -To install the nightly Rust toolchain use `rustup`. - -```sh -rustup install nightly -rustup target add --toolchain nightly wasm32-unknown-unknown -rustup component add --toolchain nightly rust-src -``` - -## Install `wasm-opt` - -To install `wasm-opt`, install `binaryen`. Depending on your operating system -there may be different ways to install it. - - - - -```sh -brew install binaryen -``` - - - - -For distributions that use `apt`: - -```sh -sudo apt install binaryen -``` - -For other distributions see: -https://github.com/WebAssembly/binaryen/releases - - - - -For install options see: -https://github.com/WebAssembly/binaryen/releases - - - - -## Building with `nightly` and `wasm-opt` - -Then build your contract using nightly, and the additional options that remove -unnecessary information from the contract. - -```sh -cargo +nightly build \ - --target wasm32-unknown-unknown \ - --release \ - -Z build-std=std,panic_abort \ - -Z build-std-features=panic_immediate_abort -``` - -Then additionally use `wasm-opt` to further minimize the size of the `.wasm`. - -```sh -wasm-opt -Oz \ - target/wasm32-unknown-unknown/release/first_project.wasm \ - -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm -``` diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx index b531af4ea..431334fa5 100644 --- a/docs/tutorials/build.mdx +++ b/docs/tutorials/build.mdx @@ -9,6 +9,11 @@ To build a Soroban contract to deploy or run, use the `cargo build` command. cargo build --target wasm32-unknown-unknown --release ``` +:::tip +It is highly recommended to use the `release` profile outlined in [Configure the +Release Profile], otherwise the contract will exceed Soroban's size limits. +::: + A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. @@ -20,3 +25,90 @@ The `.wasm` file contains the logic of the contract, as well as a the contracts specification that can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. + +
Optimizing Builds +

+ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Building optimized contracts to be as small as possible requires some additional +tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. + +Building optimized contracts is only necessary when deploying to a network with +fees or when analyzing and profiling a contract to get it as small as possible. +If you're just starting out writing a contract, these steps are not necessary. + +[Configure the Release Profile]: create-a-project#configure-the-release-profile + +## Install Rust `nightly` + +To install the nightly Rust toolchain use [`rustup`]. + +[`rustup`]: ../getting-started/setup#install-rust + +```sh +rustup install nightly +rustup target add --toolchain nightly wasm32-unknown-unknown +rustup component add --toolchain nightly rust-src +``` + +## Install `wasm-opt` + +To install `wasm-opt`, install [`binaryen`]. Depending on your operating system +there may be different ways to install it. + +[`binaryen`]: https://github.com/WebAssembly/binaryen + + + + +```sh +brew install binaryen +``` + + + + +For distributions that use `apt`: + +```sh +sudo apt install binaryen +``` + +For other distributions see: +https://github.com/WebAssembly/binaryen/releases + + + + +For install options see: +https://github.com/WebAssembly/binaryen/releases + + + + +## Build with `nightly` and `wasm-opt` + +Build your contract using nightly. The additional options instruct the compiler +to remove unnecessary information from the contract. + +```sh +cargo +nightly build \ + --target wasm32-unknown-unknown \ + --release \ + -Z build-std=std,panic_abort \ + -Z build-std-features=panic_immediate_abort +``` + +Use `wasm-opt` to further minimize the size of the `.wasm`. + +```sh +wasm-opt -Oz \ + target/wasm32-unknown-unknown/release/first_project.wasm \ + -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm +``` + + +

+
diff --git a/docs/tutorials/run-on-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx similarity index 99% rename from docs/tutorials/run-on-local-network.mdx rename to docs/tutorials/deploy-to-local-network.mdx index a417ff90d..61de89d35 100644 --- a/docs/tutorials/run-on-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 8 -title: Run on Local Network +title: Deploy to Local Network --- If you have Docker installed, you can run a local standalone network with the diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx new file mode 100644 index 000000000..947ef9de2 --- /dev/null +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 11 +title: Invoking Contracts with Stellar Transactions +--- + +Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the +user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to +the network. + +The `InvokeHostFunctionOp` can be used to invoke host functions. Host functions are built-in to Soroban and give the invoker access to: +- Invoking contract functions. +- Deploying new contracts. +- Deploying token contracts for Stellar Assets. + +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli + +## InvokeHostFunctionOp + +The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found +[here](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L477-L496) +```c++ +enum HostFunction +{ + HOST_FN_INVOKE_CONTRACT = 0, + HOST_FN_CREATE_CONTRACT_WITH_ED25519 = 1, + HOST_FN_CREATE_CONTRACT_WITH_SOURCE_ACCOUNT = 2, + HOST_FN_CREATE_TOKEN_CONTRACT_WITH_SOURCE_ACCOUNT = 3, + HOST_FN_CREATE_TOKEN_CONTRACT_WITH_ASSET = 4 +}; + +struct InvokeHostFunctionOp +{ + // The host function to invoke + HostFunction function; + + // Parameters to the host function + SCVec parameters; + + // The footprint for this invocation + LedgerFootprint footprint; +}; +``` + +### Function +The `parameters` in `InvokeHostFunctionOp` will be forwarded to the +`HostFunction` specifed in `function`. The options are - +1. `HOST_FN_INVOKE_CONTRACT` + - This will call the `call_n` host function, invoking a contract function. + - `parameters` is + expected to contain the contract id, contract function name, and the + parameters to the contract function being invoked. +2. `HOST_FN_CREATE_CONTRACT_WITH_ED25519` + - This is disabled for now. Calling it will result in an error. +3. `HOST_FN_CREATE_CONTRACT_WITH_SOURCE_ACCOUNT` + - This will call the `create_contract_from_source_account` host function, + creating a contract using the stellar source account that submitted the + transaction. The contract id will be the SHA256 hash of + [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L594) `HashIDPreimage`. + - `parameters` is expected to contain two elements: the WASM contract code and a + salt. +4. `HOST_FN_CREATE_TOKEN_CONTRACT_WITH_SOURCE_ACCOUNT` + - This will call the `create_token_from_source_account` host function, + creating a [built-in token contract] using the stellar source account that submitted the + transaction. The contract id will be the SHA256 hash of + [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L594) `HashIDPreimage`. + - `parameters` is expected to contain a salt. +5. `HOST_FN_CREATE_TOKEN_CONTRACT_WITH_ASSET` + - This will call the `create_token_from_asset` host function, creating a + [built-in token contract] that wraps a classic Stellar asset. + The contract id will be the SHA256 hash of + [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L592) `HashIDPreimage`. `create_token_from_asset` will also initialize the token + contract, so the user is not expected to call any intialize functions. + - `parameters` is expected to contain a xdr `Asset`. + +[built-in token contract]: ../built-in-contracts/token-contract.mdx + +### Parameters +This `SCVec` contains the parameters that will be passed to the host function that is being invoked. + +### Footprint +The footprint must contain the `LedgerKeys` that will be read and/or written. More +information about the footprint can be found in the advanced section of [interacting with contracts](interacting-with-contracts#storage-footprint-and-preflight). From 2c31c05d8b6e754179d3c27af634b2ee9baa4ab9 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 11:39:02 -0700 Subject: [PATCH 078/248] Update soroban-cli version (#192) --- docs/getting-started/setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 5e3e603d3..c319439a2 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.1.0 soroban-cli +cargo install --locked --version 0.1.1 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -h -soroban 0.1.0 +soroban 0.1.1 https://soroban.stellar.org USAGE: From 10aed86e4230d7072c4276e9f81c260bd11e4562 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 20:14:27 -0700 Subject: [PATCH 079/248] Fix broken links (#195) --- docs/tutorials/invoking-contracts-with-transactions.mdx | 2 +- docs/tutorials/run-on-sandbox.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index 947ef9de2..0666b7c36 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -79,4 +79,4 @@ This `SCVec` contains the parameters that will be passed to the host function th ### Footprint The footprint must contain the `LedgerKeys` that will be read and/or written. More -information about the footprint can be found in the advanced section of [interacting with contracts](interacting-with-contracts#storage-footprint-and-preflight). +information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx index d4915b7cc..e7800bf43 100644 --- a/docs/tutorials/run-on-sandbox.mdx +++ b/docs/tutorials/run-on-sandbox.mdx @@ -12,7 +12,7 @@ find on a Stellar network. :::info It's also possible to run a contract on a fully featured local network. See -[Run on a Local Network] for more details. +[Deploy to a Local Network] for more details. ::: Using the code we wrote in [Write a Contract] and the resulting `.wasm` file @@ -34,6 +34,6 @@ The following output should appear. ``` [Write a Contract]: write-a-contract -[Run on a Local Network]: run-on-local-network +[Deploy to a Local Network]: deploy-to-local-network [Build]: build [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From d3a8e69dac51cfb7c7b2cdf0e116c8c1b11441f8 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 20:18:49 -0700 Subject: [PATCH 080/248] Fix a typo --- docs/tutorials/deploy-to-local-network.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index 61de89d35..20de04bdb 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 8 -title: Deploy to Local Network +title: Deploy a to Local Network --- If you have Docker installed, you can run a local standalone network with the From 2b9d80c3420f0693549b7ba08e43dff9120d127e Mon Sep 17 00:00:00 2001 From: Dmytro Kozhevin Date: Mon, 10 Oct 2022 23:30:55 -0400 Subject: [PATCH 081/248] Update for built-in token docs (#193) Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> --- docs/tutorials/invoking-contracts-with-transactions.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index 0666b7c36..9c9191011 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -72,7 +72,7 @@ The `parameters` in `InvokeHostFunctionOp` will be forwarded to the contract, so the user is not expected to call any intialize functions. - `parameters` is expected to contain a xdr `Asset`. -[built-in token contract]: ../built-in-contracts/token-contract.mdx +[built-in token contract]: ../built-in-contracts/token ### Parameters This `SCVec` contains the parameters that will be passed to the host function that is being invoked. From deba6d188c74db1084d89ae2f8ac24a16c035a93 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 21:58:55 -0700 Subject: [PATCH 082/248] Fix typo --- docs/tutorials/deploy-to-local-network.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index 20de04bdb..d4da569b1 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 8 -title: Deploy a to Local Network +title: Deploy to a Local Network --- If you have Docker installed, you can run a local standalone network with the From bb44fb7a9028c0143ed4800c496f8f98b13c5016 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 22:00:17 -0700 Subject: [PATCH 083/248] Fix typos in command examples --- docs/tutorials/deploy-to-local-network.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index d4da569b1..7a916530f 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -64,7 +64,7 @@ the `S...` key as the secret key. ```sh soroban deploy \ --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ - --secret-key S... + --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' ``` @@ -87,12 +87,12 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh -soroban invoke - --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 - --secret-key S... - --rpc-url http://localhost:8000/soroban/rpc - --network-passphrase 'Standalone Network ; February 2017' - --fn hello +soroban invoke \ + --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ + --secret-key S... \ + --rpc-url http://localhost:8000/soroban/rpc \ + --network-passphrase 'Standalone Network ; February 2017' \ + --fn hello \ --arg friend ``` From e494adff996f3ffd82041c9a2975c4cedf899c93 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 11 Oct 2022 00:20:03 -0700 Subject: [PATCH 084/248] Update soroban-cli to v0.1.2 (#196) --- docs/getting-started/setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index c319439a2..008297c33 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.1.1 soroban-cli +cargo install --locked --version 0.1.2 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -h -soroban 0.1.1 +soroban 0.1.2 https://soroban.stellar.org USAGE: From 8c7c4bc89fe1cd3778d4cae3f3584cba997b2ca6 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Mon, 10 Oct 2022 17:55:12 -0700 Subject: [PATCH 085/248] Tweaks to pages --- docs/faq.mdx | 2 +- docs/tutorials/deploy-to-futurenet.mdx | 104 +++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 docs/tutorials/deploy-to-futurenet.mdx diff --git a/docs/faq.mdx b/docs/faq.mdx index 954e81ec5..50ed934b5 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 8 +sidebar_position: 9 title: Soroban on Stellar FAQ --- diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx new file mode 100644 index 000000000..1047e8d62 --- /dev/null +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -0,0 +1,104 @@ +--- +sidebar_position: 9 +title: Deploy to Futurenet +--- + +If you have Docker installed, you can run a local node with the [Stellar +Quickstart] Docker image that joins the [Futurenet] network, and then use that +local node to deploy. + +[Futurenet]: ../networks/futurenet + +:::info +It's also possible to run a contract in the local sandbox environment without a +network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. +::: + +To run a local node for the [Futurenet] network with the Stellar Quickstart +Docker image, run the following command. + +```sh +docker run --rm -it \ + -p 8000:8000 \ + --name stellar \ + stellar/quickstart:soroban-dev \ + --futurenet \ + --enable-soroban-rpc +``` + +Once the image is started you can check its status by querying the Horizon API: +```sh +curl http://localhost:8000 +``` + +Generate a key by going to the [Stellar Laboratory]. Make note of both the +`G...` and `S...` keys. The `G...` key is the public key and will also be the +account ID. The `S...` key is the secret key and is that you use to control the +account. + +:::tip +It's a good practice to never use the same keys for testing and development that +you use do for the public Stellar network. Generate new keys for testing and +development and avoid ever using them for other purposes. +::: + +Create an account on the [Futurenet] network by making a request to the +Friendbot. Specify as the `addr` the `G...` key of your account. + +```sh +curl https://friendbot-futurenet.stellar.org/?addr=G... +``` + +Once you have an account on the network, we'll use the code we wrote in [Write a +Contract] and the resulting `.wasm` file we built in [Build] as our contract to +deploy. Run the following commands to deploy the contract to the network. Use +the `S...` key as the secret key. + +```sh +soroban deploy \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --secret-key S... \ + --rpc-url http://localhost:8000/soroban/rpc \ + --network-passphrase 'Test SDF Future Network ; October 2022' +``` + +:::tip +It's good practice to avoid entering secret keys on the command line. You can +also specify the secret key by setting the environment variable +`SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the +future there will be other secure ways to provide a secret key, such as via +hardware keys. +::: + +A contract ID will be outputted. + +``` +cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 +``` + +Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the +`hello` function with a single argument `friend`. + +```sh +soroban invoke + --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 + --secret-key S... + --rpc-url http://localhost:8000/soroban/rpc + --network-passphrase 'Test SDF Future Network ; October 2022' + --fn hello + --arg friend +``` + +The following output should appear. + +```json +["Hello","friend"] +``` + +[Write a Contract]: write-a-contract +[Run on a Local Network]: run-on-local-network +[Build]: build +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test +[Run on Sandbox]: run-on-sandbox +[Stellar Quickstart]: https://github.com/stellar/quickstart From 0f54d2f33f32fe2b7ce8d1af5c1096e57aabe835 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 11 Oct 2022 09:50:30 -0700 Subject: [PATCH 086/248] Fixes to examples and docs (#199) --- docs/getting-started/quick-start.mdx | 2 +- docs/tutorials/build.mdx | 6 +++--- docs/tutorials/deploy-to-futurenet.mdx | 18 +++++++++++------- docs/tutorials/deploy-to-local-network.mdx | 5 +++-- docs/tutorials/run-on-sandbox.mdx | 2 +- docs/tutorials/testing.mdx | 2 +- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 4886f6525..fd6c7cf6a 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -103,7 +103,7 @@ impl Contract { #[cfg(test)] mod test { use super::{Contract, ContractClient}; - use soroban_sdk::{symbol, vec, BytesN, Env}; + use soroban_sdk::{symbol, vec, Env}; #[test] fn test() { diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx index 431334fa5..aa4379e9e 100644 --- a/docs/tutorials/build.mdx +++ b/docs/tutorials/build.mdx @@ -10,15 +10,15 @@ cargo build --target wasm32-unknown-unknown --release ``` :::tip -It is highly recommended to use the `release` profile outlined in [Configure the -Release Profile], otherwise the contract will exceed Soroban's size limits. +Use the `release` profile outlined in [Configure the Release Profile], otherwise +the contract will exceed Soroban's size limits. ::: A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. ``` -target/wasm32-unknown-unknown/release/first_project.wasm +target/wasm32-unknown-unknown/release/[project-name].wasm ``` The `.wasm` file contains the logic of the contract, as well as a the contracts diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 1047e8d62..3d3a72ce5 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -19,6 +19,7 @@ Docker image, run the following command. ```sh docker run --rm -it \ + --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ stellar/quickstart:soroban-dev \ @@ -31,6 +32,9 @@ Once the image is started you can check its status by querying the Horizon API: curl http://localhost:8000 ``` +It takes sometime to join a remote network. Monitor the output of that endpoint +until you see the `core_latest_ledger` become a number above zero. + Generate a key by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the @@ -56,7 +60,7 @@ the `S...` key as the secret key. ```sh soroban deploy \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Test SDF Future Network ; October 2022' @@ -80,12 +84,12 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh -soroban invoke - --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 - --secret-key S... - --rpc-url http://localhost:8000/soroban/rpc - --network-passphrase 'Test SDF Future Network ; October 2022' - --fn hello +soroban invoke \ + --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ + --secret-key S... \ + --rpc-url http://localhost:8000/soroban/rpc \ + --network-passphrase 'Test SDF Future Network ; October 2022' \ + --fn hello \ --arg friend ``` diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index 7a916530f..e64441a8f 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -26,6 +26,7 @@ run the following command. ```sh docker run --rm -it \ + --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ stellar/quickstart:soroban-dev \ @@ -53,7 +54,7 @@ Create an account on the local sandbox environment by making a request to the local Friendbot. Specify as the `addr` the `G...` key of your account. ```sh -curl http://localhost:8000/?addr=G... +curl http://localhost:8000/friendbot?addr=G... ``` Once you have an account on the network, we'll use the code we wrote in [Write a @@ -63,7 +64,7 @@ the `S...` key as the secret key. ```sh soroban deploy \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx index e7800bf43..71008f443 100644 --- a/docs/tutorials/run-on-sandbox.mdx +++ b/docs/tutorials/run-on-sandbox.mdx @@ -21,7 +21,7 @@ function with a single argument `friend`. ```sh soroban invoke \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ + --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --id 1 \ --fn hello \ --arg friend diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 53733026b..6639ab991 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -39,7 +39,7 @@ mod test; #![cfg(test)] use super::{Contract, ContractClient}; -use soroban_sdk::{symbol, vec, BytesN, Env}; +use soroban_sdk::{symbol, vec, Env}; #[test] fn test() { From 81f73158fdca9a82de7968c385eeb20e539b119f Mon Sep 17 00:00:00 2001 From: tomerweller Date: Wed, 12 Oct 2022 18:12:26 +0200 Subject: [PATCH 087/248] Move Build Optimized out of details section (#202) --- docs/tutorials/build-optimized.mdx | 82 ++++++++++++++++++++++++++++ docs/tutorials/build.mdx | 88 ++---------------------------- 2 files changed, 86 insertions(+), 84 deletions(-) create mode 100644 docs/tutorials/build-optimized.mdx diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx new file mode 100644 index 000000000..5df175fcc --- /dev/null +++ b/docs/tutorials/build-optimized.mdx @@ -0,0 +1,82 @@ +--- +sidebar_position: 11 +title: Optimizing Builds +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Building optimized contracts to be as small as possible requires some additional +tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. + +Building optimized contracts is only necessary when deploying to a network with +fees or when analyzing and profiling a contract to get it as small as possible. +If you're just starting out writing a contract, these steps are not necessary. + +### Install Rust `nightly` + +To install the nightly Rust toolchain use [`rustup`]. + +[`rustup`]: ../getting-started/setup#install-rust + +```sh +rustup install nightly +rustup target add --toolchain nightly wasm32-unknown-unknown +rustup component add --toolchain nightly rust-src +``` + +### Install `wasm-opt` + +To install `wasm-opt`, install [`binaryen`]. Depending on your operating system +there may be different ways to install it. + +[`binaryen`]: https://github.com/WebAssembly/binaryen + + + + +```sh +brew install binaryen +``` + + + + +For distributions that use `apt`: + +```sh +sudo apt install binaryen +``` + +For other distributions see: +https://github.com/WebAssembly/binaryen/releases + + + + +For install options see: +https://github.com/WebAssembly/binaryen/releases + + + + +### Build with `nightly` and `wasm-opt` + +Build your contract using nightly. The additional options instruct the compiler +to remove unnecessary information from the contract. + +```sh +cargo +nightly build \ + --target wasm32-unknown-unknown \ + --release \ + -Z build-std=std,panic_abort \ + -Z build-std-features=panic_immediate_abort +``` + +Use `wasm-opt` to further minimize the size of the `.wasm`. + +```sh +wasm-opt -Oz \ + target/wasm32-unknown-unknown/release/first_project.wasm \ + -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm +``` diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx index aa4379e9e..1fd3b71e1 100644 --- a/docs/tutorials/build.mdx +++ b/docs/tutorials/build.mdx @@ -26,89 +26,9 @@ specification that can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. -
Optimizing Builds -

- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -Building optimized contracts to be as small as possible requires some additional -tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. - -Building optimized contracts is only necessary when deploying to a network with -fees or when analyzing and profiling a contract to get it as small as possible. -If you're just starting out writing a contract, these steps are not necessary. +:::tip +To further optimize builds to be as small as possible, see [Optimizing Builds]. +::: [Configure the Release Profile]: create-a-project#configure-the-release-profile - -## Install Rust `nightly` - -To install the nightly Rust toolchain use [`rustup`]. - -[`rustup`]: ../getting-started/setup#install-rust - -```sh -rustup install nightly -rustup target add --toolchain nightly wasm32-unknown-unknown -rustup component add --toolchain nightly rust-src -``` - -## Install `wasm-opt` - -To install `wasm-opt`, install [`binaryen`]. Depending on your operating system -there may be different ways to install it. - -[`binaryen`]: https://github.com/WebAssembly/binaryen - - - - -```sh -brew install binaryen -``` - - - - -For distributions that use `apt`: - -```sh -sudo apt install binaryen -``` - -For other distributions see: -https://github.com/WebAssembly/binaryen/releases - - - - -For install options see: -https://github.com/WebAssembly/binaryen/releases - - - - -## Build with `nightly` and `wasm-opt` - -Build your contract using nightly. The additional options instruct the compiler -to remove unnecessary information from the contract. - -```sh -cargo +nightly build \ - --target wasm32-unknown-unknown \ - --release \ - -Z build-std=std,panic_abort \ - -Z build-std-features=panic_immediate_abort -``` - -Use `wasm-opt` to further minimize the size of the `.wasm`. - -```sh -wasm-opt -Oz \ - target/wasm32-unknown-unknown/release/first_project.wasm \ - -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm -``` - - -

-
+[Optimizing Builds]: build-optimized From 2a1b6124b828351966d657358d439cf173d31530 Mon Sep 17 00:00:00 2001 From: Justin Rice Date: Mon, 17 Oct 2022 17:08:18 -0400 Subject: [PATCH 088/248] fix broken link in setup.mdx (#204) Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> --- docs/getting-started/setup.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 008297c33..dc6697f3a 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -59,7 +59,7 @@ cargo install --locked --version 0.1.2 soroban-cli :::info Report issues and share feedback about the Soroban CLI -[here](https://github.com/stellar/soroban/issues/new/choose). +[here](https://github.com/stellar/soroban-cli/issues/new/choose). ::: ### Usage From d9d1e502ad251bbcad9126ab59ae8a03650cef65 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 20 Oct 2022 09:55:13 -0700 Subject: [PATCH 089/248] Make it clearer that optimization is unnecessary (#205) * Make it clearer that optimization is unnecessary * less words * Update build-optimized.mdx Co-authored-by: Tyler van der Hoeven --- docs/tutorials/build-optimized.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index 5df175fcc..9ccd26bf1 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -9,9 +9,14 @@ import TabItem from '@theme/TabItem'; Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. +:::tip Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. +See [Build] for details on how to build for development. +::: + +[Build]: build.mdx ### Install Rust `nightly` From 840e717203229e3926f1fa213527373d4664b6f5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 29 Oct 2022 00:01:31 -0700 Subject: [PATCH 090/248] Remove recommendation to use the rlib crate type (#212) --- docs/getting-started/quick-start.mdx | 2 +- docs/tutorials/create-a-project.mdx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index fd6c7cf6a..6adda8012 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -36,7 +36,7 @@ Report issues and share feedback about the `soroban-sdk` ```toml [lib] -crate-type = ["cdylib", "rlib"] +crate-type = ["cdylib"] [features] testutils = ["soroban-sdk/testutils"] diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index ad93c97a5..052fce36a 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -29,7 +29,7 @@ Add the `crate-type` configuration, required for building contracts. ```toml [lib] -crate-type = ["cdylib", "rlib"] +crate-type = ["cdylib"] ``` ## Import `soroban-sdk` and Features @@ -111,7 +111,7 @@ The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" [lib] -crate-type = ["cdylib", "rlib"] +crate-type = ["cdylib"] [features] testutils = ["soroban-sdk/testutils"] From 5ae7adf3835f96ffeae92362adb40e9c4393e8a5 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Sat, 29 Oct 2022 00:01:41 -0700 Subject: [PATCH 091/248] Remove recommendation to use the rlib crate type (#212) From c12f4ab3d2a1daffa79c94a6852bc3bc3a6088e3 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 1 Nov 2022 08:32:31 -0700 Subject: [PATCH 092/248] Fix typo (#213) --- docs/tutorials/deploy-to-futurenet.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 3d3a72ce5..274d0a4d0 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -42,7 +42,7 @@ account. :::tip It's a good practice to never use the same keys for testing and development that -you use do for the public Stellar network. Generate new keys for testing and +you use for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. ::: From 3ea1ca7ca99c73e928f3395ba7a48fa5b4f18549 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Nov 2022 20:38:34 -0800 Subject: [PATCH 093/248] Update Examples, SDK and CLI v0.2.1 --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 7 ++++--- docs/tutorials/create-a-project.mdx | 10 +++++----- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 6adda8012..39d40172e 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -21,7 +21,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "first-project" -version = "0.1.0" +version = "0.2.1" edition = "2021" ``` @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index dc6697f3a..e8353dc39 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.1.2 soroban-cli +cargo install --locked --version 0.2.1 soroban-cli ``` :::info @@ -71,8 +71,8 @@ soroban ``` ``` -❯ soroban -h -soroban 0.1.2 +❯ soroban +soroban 0.2.1 https://soroban.stellar.org USAGE: @@ -84,6 +84,7 @@ OPTIONS: SUBCOMMANDS: invoke Invoke a contract function in a WASM file inspect Inspect a WASM file listing contract functions, meta, etc + optimize Optimize a WASM file read Print the current value of a contract-data ledger entry serve Run a local webserver for web app development and testing token Wrap, create, and manage token contracts diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 052fce36a..995e4bc2a 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -19,7 +19,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "project-name" -version = "0.1.0" +version = "0.2.1" edition = "2021" ``` @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [profile.release] opt-level = "z" From 48b730359726b76585b7e88684258c82881d72a6 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Nov 2022 21:00:59 -0800 Subject: [PATCH 094/248] Pin docker image --- docs/tutorials/deploy-to-futurenet.mdx | 2 +- docs/tutorials/deploy-to-local-network.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 274d0a4d0..ff4d4a793 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -22,7 +22,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ --futurenet \ --enable-soroban-rpc ``` diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index e64441a8f..58e39b5f3 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -29,7 +29,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ --standalone \ --enable-soroban-rpc ``` From 52363fdd555ed60caa94a69e8158931d571abc57 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 10 Nov 2022 21:36:07 -0800 Subject: [PATCH 095/248] Update Examples, SDK and CLI v0.2.1, and Quickstart Image (#221) --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 7 ++++--- docs/tutorials/create-a-project.mdx | 10 +++++----- docs/tutorials/deploy-to-futurenet.mdx | 2 +- docs/tutorials/deploy-to-local-network.mdx | 2 +- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 6adda8012..39d40172e 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -21,7 +21,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "first-project" -version = "0.1.0" +version = "0.2.1" edition = "2021" ``` @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index dc6697f3a..e8353dc39 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.1.2 soroban-cli +cargo install --locked --version 0.2.1 soroban-cli ``` :::info @@ -71,8 +71,8 @@ soroban ``` ``` -❯ soroban -h -soroban 0.1.2 +❯ soroban +soroban 0.2.1 https://soroban.stellar.org USAGE: @@ -84,6 +84,7 @@ OPTIONS: SUBCOMMANDS: invoke Invoke a contract function in a WASM file inspect Inspect a WASM file listing contract functions, meta, etc + optimize Optimize a WASM file read Print the current value of a contract-data ledger entry serve Run a local webserver for web app development and testing token Wrap, create, and manage token contracts diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 052fce36a..995e4bc2a 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -19,7 +19,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "project-name" -version = "0.1.0" +version = "0.2.1" edition = "2021" ``` @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.1.0" +soroban-sdk = "0.2.1" [dev_dependencies] -soroban-sdk = { version = "0.1.0", features = ["testutils"] } +soroban-sdk = { version = "0.2.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 274d0a4d0..ff4d4a793 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -22,7 +22,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ --futurenet \ --enable-soroban-rpc ``` diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index e64441a8f..58e39b5f3 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -29,7 +29,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ --standalone \ --enable-soroban-rpc ``` From 668ccff2fe5a0dd5d51736b3d783a1e949bf4c86 Mon Sep 17 00:00:00 2001 From: Matias Wald Date: Sat, 12 Nov 2022 22:08:17 -0400 Subject: [PATCH 096/248] Fix typos (#222) --- docs/tutorials/build.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx index 1fd3b71e1..e2a0ee486 100644 --- a/docs/tutorials/build.mdx +++ b/docs/tutorials/build.mdx @@ -21,7 +21,7 @@ the built contract. target/wasm32-unknown-unknown/release/[project-name].wasm ``` -The `.wasm` file contains the logic of the contract, as well as a the contracts +The `.wasm` file contains the logic of the contract, as well as the contract's specification that can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. From 3f539cbfdde4995f73f526e21cc1f9cc059fb207 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Tue, 15 Nov 2022 21:47:08 -0500 Subject: [PATCH 097/248] add quotes around curl argument (#224) needed for zsh and maybe some other shells --- docs/tutorials/deploy-to-local-network.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index 58e39b5f3..efdf1b5ca 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -54,7 +54,7 @@ Create an account on the local sandbox environment by making a request to the local Friendbot. Specify as the `addr` the `G...` key of your account. ```sh -curl http://localhost:8000/friendbot?addr=G... +curl "http://localhost:8000/friendbot?addr=G..." ``` Once you have an account on the network, we'll use the code we wrote in [Write a From c8837849241ae791bf93136e6e60d8b346c760c9 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Wed, 16 Nov 2022 11:51:37 -0500 Subject: [PATCH 098/248] quote curl argument for zsh & maybe other shells (#226) --- docs/tutorials/deploy-to-futurenet.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index ff4d4a793..3b8d3452a 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -50,7 +50,7 @@ Create an account on the [Futurenet] network by making a request to the Friendbot. Specify as the `addr` the `G...` key of your account. ```sh -curl https://friendbot-futurenet.stellar.org/?addr=G... +curl "https://friendbot-futurenet.stellar.org/?addr=G..." ``` Once you have an account on the network, we'll use the code we wrote in [Write a From 1def2bd22c797c49179f48b3783b33b0fb99610f Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Dec 2022 16:50:09 -0800 Subject: [PATCH 099/248] Update version of SDK (#236) --- docs/getting-started/quick-start.mdx | 6 +++--- docs/tutorials/create-a-project.mdx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 39d40172e..735d3e667 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -21,7 +21,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "first-project" -version = "0.2.1" +version = "0.1.0" edition = "2021" ``` @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 995e4bc2a..6068a88c4 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -19,7 +19,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "project-name" -version = "0.2.1" +version = "0.1.0" edition = "2021" ``` @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [profile.release] opt-level = "z" From a0b6c3b9467e5ad37c314837032152fb4ae5e83e Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Dec 2022 17:06:40 -0800 Subject: [PATCH 100/248] Remove BigInt and replace with i128 (#237) --- docs/tutorials/write-a-contract.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a62..6a2dbe15d 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -26,8 +26,8 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +`Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory +and native capabilities. ```rust pub struct Contract; From 6a829261e8f41c5a60b0fb056ea15175c976f21e Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:04:25 -0800 Subject: [PATCH 101/248] Update soroban-cli to v0.3.1 (#239) --- docs/getting-started/setup.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index e8353dc39..54229aea6 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.2.1 soroban-cli +cargo install --locked --version 0.3.1 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -soroban 0.2.1 +soroban 0.3.1 https://soroban.stellar.org USAGE: @@ -89,6 +89,7 @@ SUBCOMMANDS: serve Run a local webserver for web app development and testing token Wrap, create, and manage token contracts deploy Deploy a WASM file as a contract + install Install a WASM file to the ledger without creating a contract instance gen Generate code client bindings for a contract xdr Decode xdr version Print version information From a965dfa71e552c62b91953bad06f1a72718d144b Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 6 Dec 2022 13:35:08 -0800 Subject: [PATCH 102/248] Next Release Dev Branch (#231) --- docs/getting-started/quick-start.mdx | 6 +++--- docs/getting-started/setup.mdx | 5 +++-- docs/tutorials/create-a-project.mdx | 10 +++++----- docs/tutorials/write-a-contract.mdx | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 39d40172e..735d3e667 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -21,7 +21,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "first-project" -version = "0.2.1" +version = "0.1.0" edition = "2021" ``` @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index e8353dc39..54229aea6 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.2.1 soroban-cli +cargo install --locked --version 0.3.1 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -soroban 0.2.1 +soroban 0.3.1 https://soroban.stellar.org USAGE: @@ -89,6 +89,7 @@ SUBCOMMANDS: serve Run a local webserver for web app development and testing token Wrap, create, and manage token contracts deploy Deploy a WASM file as a contract + install Install a WASM file to the ledger without creating a contract instance gen Generate code client bindings for a contract xdr Decode xdr version Print version information diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 995e4bc2a..6068a88c4 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -19,7 +19,7 @@ Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] name = "project-name" -version = "0.2.1" +version = "0.1.0" edition = "2021" ``` @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.2.1" +soroban-sdk = "0.3.1" [dev_dependencies] -soroban-sdk = { version = "0.2.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.1", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a62..6a2dbe15d 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -26,8 +26,8 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +`Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory +and native capabilities. ```rust pub struct Contract; From 254872251e47139347675e55e1269fdd0b1790bb Mon Sep 17 00:00:00 2001 From: Piyal Basu Date: Tue, 6 Dec 2022 16:37:01 -0500 Subject: [PATCH 103/248] add instructions on how to Sign Transactions with Freighter (#200) --- docs/faq.mdx | 2 +- docs/tutorials/invoking-contracts-with-transactions.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq.mdx b/docs/faq.mdx index 50ed934b5..57e3fd732 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 10 title: Soroban on Stellar FAQ --- diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index 9c9191011..d8e7b5267 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -79,4 +79,4 @@ This `SCVec` contains the parameters that will be passed to the host function th ### Footprint The footprint must contain the `LedgerKeys` that will be read and/or written. More -information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). +information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). \ No newline at end of file From 12e74a0727f7752415e3f965302976ac4f0930e5 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Wed, 7 Dec 2022 11:26:15 -0500 Subject: [PATCH 104/248] Reorder the nav bar (#244) * Update Examples, SDK and CLI v0.2.1 * Pin docker image * Add release notes (#234) * Rename and move releases page * reorder EVERYTHING * reorder Learn between Examples and SDKs * update wallet position Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> --- docs/faq.mdx | 2 +- docs/getting-started/_category_.json | 2 +- docs/tutorials/_category_.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/faq.mdx b/docs/faq.mdx index 57e3fd732..34fca4615 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 100 title: Soroban on Stellar FAQ --- diff --git a/docs/getting-started/_category_.json b/docs/getting-started/_category_.json index 97808849a..6871e3ab3 100644 --- a/docs/getting-started/_category_.json +++ b/docs/getting-started/_category_.json @@ -1,5 +1,5 @@ { - "position": 2, + "position": 10, "label": "Getting Started", "link": { "type": "generated-index" diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json index 8d772d396..74f2f1406 100644 --- a/docs/tutorials/_category_.json +++ b/docs/tutorials/_category_.json @@ -1,5 +1,5 @@ { - "position": 2, + "position": 30, "label": "Tutorials", "link": { "type": "generated-index" From e433db3e25807f0df35c01127ed6e50399cab38b Mon Sep 17 00:00:00 2001 From: Jay Geng Date: Thu, 8 Dec 2022 16:06:53 -0500 Subject: [PATCH 105/248] Update soroban-{sdk, auth, example, cli} versions (#245) --- docs/getting-started/quick-start.mdx | 4 ++-- docs/getting-started/setup.mdx | 4 ++-- docs/tutorials/create-a-project.mdx | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index 735d3e667..df720a30b 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.3.1" +soroban-sdk = "0.3.2" [dev_dependencies] -soroban-sdk = { version = "0.3.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.2", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 54229aea6..befa3e974 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.3.1 soroban-cli +cargo install --locked --version 0.3.3 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -soroban 0.3.1 +soroban 0.3.3 https://soroban.stellar.org USAGE: diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 6068a88c4..7e58a48f8 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.3.1" +soroban-sdk = "0.3.2" [dev_dependencies] -soroban-sdk = { version = "0.3.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.2", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.3.1" +soroban-sdk = "0.3.2" [dev_dependencies] -soroban-sdk = { version = "0.3.1", features = ["testutils"] } +soroban-sdk = { version = "0.3.2", features = ["testutils"] } [profile.release] opt-level = "z" From ea4f09fe5877aa5ade50f92bdd5cdaa912b92591 Mon Sep 17 00:00:00 2001 From: "M. Gaylor" <115509084+mgaylor@users.noreply.github.com> Date: Mon, 12 Dec 2022 08:20:45 -0800 Subject: [PATCH 106/248] added [package] entries (#248) allowing full 'Cargo.toml' code to be copied --- docs/tutorials/create-a-project.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 7e58a48f8..d9e46edbe 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -110,6 +110,11 @@ See the [logging example] for more information about how to log. The steps below should produce a `Cargo.toml` that looks like so. ```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2022" + [lib] crate-type = ["cdylib"] From e96dfaffa4a64c9aa692e55e3b7df67bcf08687e Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Mon, 12 Dec 2022 13:31:05 -0600 Subject: [PATCH 107/248] Updating the futurenet and localnet tutorials with latest quickstart (#249) The previous image hash was used in these two tutorials, but is no longer working (I assume because there are no other nodes running that version). Here, both tutorials are updated to the latest preview version of the quickstart image. Signed-off-by: Elliot Voris Signed-off-by: Elliot Voris --- docs/tutorials/deploy-to-futurenet.mdx | 2 +- docs/tutorials/deploy-to-local-network.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 3b8d3452a..f0d21e4b3 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -22,7 +22,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ + stellar/quickstart:soroban-dev@sha256:8046391718f8e58b2b88b9c379abda3587bb874689fa09b2ed4871a764ebda27 \ --futurenet \ --enable-soroban-rpc ``` diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index efdf1b5ca..da6754446 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -29,7 +29,7 @@ docker run --rm -it \ --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:0993d3350148af6ffeab5dc8f0b835236b28dade6dcae77ff8a09317162f768d \ + stellar/quickstart:soroban-dev@sha256:8046391718f8e58b2b88b9c379abda3587bb874689fa09b2ed4871a764ebda27 \ --standalone \ --enable-soroban-rpc ``` From 2f053204b10da78928161efdff7d35a2e7ac163c Mon Sep 17 00:00:00 2001 From: Dmytro Kozhevin Date: Wed, 21 Dec 2022 18:02:22 -0500 Subject: [PATCH 108/248] Update Soroban transaction document. (#251) --- .../invoking-contracts-with-transactions.mdx | 133 +++++++++++------- 1 file changed, 82 insertions(+), 51 deletions(-) diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index d8e7b5267..ce480a326 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -1,81 +1,112 @@ --- sidebar_position: 11 -title: Invoking Contracts with Stellar Transactions +title: Invoking and Creating Contracts with Stellar Transactions --- Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the -user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to -the network. +user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. -The `InvokeHostFunctionOp` can be used to invoke host functions. Host functions are built-in to Soroban and give the invoker access to: -- Invoking contract functions. -- Deploying new contracts. -- Deploying token contracts for Stellar Assets. +The `InvokeHostFunctionOp` can be used to perform the following Soroban +operations: +- Invoke contract functions. +- Install WASM of the new contracts. +- Deploy new contracts using the installed WASM or built-in implementations ( + this currently includes only the [token contract](../built-in-contracts/token.mdx)). [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli ## InvokeHostFunctionOp The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found -[here](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L477-L496) +[here](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L523-L539) ```c++ -enum HostFunction +union HostFunction switch (HostFunctionType type) { - HOST_FN_INVOKE_CONTRACT = 0, - HOST_FN_CREATE_CONTRACT_WITH_ED25519 = 1, - HOST_FN_CREATE_CONTRACT_WITH_SOURCE_ACCOUNT = 2, - HOST_FN_CREATE_TOKEN_CONTRACT_WITH_SOURCE_ACCOUNT = 3, - HOST_FN_CREATE_TOKEN_CONTRACT_WITH_ASSET = 4 +case HOST_FUNCTION_TYPE_INVOKE_CONTRACT: + SCVec invokeArgs; +case HOST_FUNCTION_TYPE_CREATE_CONTRACT: + CreateContractArgs createContractArgs; +case HOST_FUNCTION_TYPE_INSTALL_CONTRACT_CODE: + InstallContractCodeArgs installContractCodeArgs; }; struct InvokeHostFunctionOp { // The host function to invoke HostFunction function; - - // Parameters to the host function - SCVec parameters; - // The footprint for this invocation LedgerFootprint footprint; }; ``` ### Function -The `parameters` in `InvokeHostFunctionOp` will be forwarded to the -`HostFunction` specifed in `function`. The options are - -1. `HOST_FN_INVOKE_CONTRACT` +The `function` in `InvokeHostFunctionOp` will be executed by the Soroban host +environment. The function arguments are passed as function-dependent XDR. The +options are: +1. `HOST_FUNCTION_TYPE_INVOKE_CONTRACT` - This will call the `call_n` host function, invoking a contract function. - - `parameters` is - expected to contain the contract id, contract function name, and the - parameters to the contract function being invoked. -2. `HOST_FN_CREATE_CONTRACT_WITH_ED25519` - - This is disabled for now. Calling it will result in an error. -3. `HOST_FN_CREATE_CONTRACT_WITH_SOURCE_ACCOUNT` - - This will call the `create_contract_from_source_account` host function, - creating a contract using the stellar source account that submitted the - transaction. The contract id will be the SHA256 hash of - [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L594) `HashIDPreimage`. - - `parameters` is expected to contain two elements: the WASM contract code and a - salt. -4. `HOST_FN_CREATE_TOKEN_CONTRACT_WITH_SOURCE_ACCOUNT` - - This will call the `create_token_from_source_account` host function, - creating a [built-in token contract] using the stellar source account that submitted the - transaction. The contract id will be the SHA256 hash of - [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L594) `HashIDPreimage`. - - `parameters` is expected to contain a salt. -5. `HOST_FN_CREATE_TOKEN_CONTRACT_WITH_ASSET` - - This will call the `create_token_from_asset` host function, creating a - [built-in token contract] that wraps a classic Stellar asset. - The contract id will be the SHA256 hash of - [this](https://github.com/stellar/stellar-xdr-next/blob/161e2e5b64425a49f9ccfef7f732ae742ed5eec4/Stellar-transaction.x#L592) `HashIDPreimage`. `create_token_from_asset` will also initialize the token - contract, so the user is not expected to call any intialize functions. - - `parameters` is expected to contain a xdr `Asset`. - -[built-in token contract]: ../built-in-contracts/token - -### Parameters -This `SCVec` contains the parameters that will be passed to the host function that is being invoked. + - `invokeArgs` is expected to contain the contract id, contract function + name, and the parameters to the contract function being invoked. +2. `HOST_FUNCTION_TYPE_INSTALL_CONTRACT_CODE` + - This will install the contract WASM using the provided `code` blob: + ```c++ + struct InstallContractCodeArgs + { + opaque code; + }; + ``` +3. `HOST_FUNCTION_TYPE_CREATE_CONTRACT` + - This will create a contract instance in the network using the specified + `source` and build a 32-byte contract identifer based on `contractID` value. + ```c++ + struct CreateContractArgs + { + ContractID contractID; + SCContractCode source; + }; + ``` + - `source` can be either a reference to the hash of the installed WASM (to + be more precise, a SHA-256 hash of the `InstallContractCodeArgs` from the operation above) or just specify that a built-in contract has to be used: + ```c++ + union SCContractCode switch (SCContractCodeType type) + { + case SCCONTRACT_CODE_WASM_REF: + Hash wasm_id; + case SCCONTRACT_CODE_TOKEN: + void; + }; + ``` + - `contractID` is defined as following: + ```c++ + union ContractID switch (ContractIDType type) + { + case CONTRACT_ID_FROM_SOURCE_ACCOUNT: + uint256 salt; + case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: + struct + { + uint256 key; + Signature signature; + uint256 salt; + } fromEd25519PublicKey; + case CONTRACT_ID_FROM_ASSET: + Asset asset; + }; + ``` + - The parameters of this value define which the hash preimage that is then hashed + with SHA-256 to get the ID of the created contract. + - `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created + using the Stellar source account and the provided salt. The contract ID + preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_SOURCE_ACCOUNT`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L643-L649). + - `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using + the Stellar asset. This is only suported when + `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist + when this is applied, however the issuer of the asset will be the initial + token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). + - `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be + created using a public ED25519 key. Since this operation is not tied to any + on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR + preimage. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ED25519`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L623-L629). ### Footprint The footprint must contain the `LedgerKeys` that will be read and/or written. More From 3e3de2a90cc2af3af13bc666b02d2031312ec135 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Fri, 6 Jan 2023 11:33:14 -0800 Subject: [PATCH 109/248] Update outdated token terminology --- docs/faq.mdx | 19 +++++++++---------- .../invoking-contracts-with-transactions.mdx | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/docs/faq.mdx b/docs/faq.mdx index 34fca4615..7b69ad193 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -17,12 +17,11 @@ A Soroban contract can be invoked by submitting a transaction that contains the Yes. Stellar accounts are shared with Soroban. Smart contacts have access to Stellar account signer configuration and know the source account that directly invoked them in a transaction. Check out the Auth and Advanced Auth examples for more information. ### Can Soroban contracts interact with Stellar Assets? -Yes. Soroban contains a built-in token contract that is able to import a balance from a Stellar trust line into an equivalent Soroban balance and also to export it back to the Stellar trust line. Check out the built-in token for more information on token capabilities, and the token interface for building your own tokens with custom behaviors. -*Note 1: This means that one account can simultaneously have two balances of the same asset: once in a Stellar trust line and one in a Soroban token balance. This bears some similarity to the relationship between ETH and WETH on Ethereum.* -*Note 2: Tokens that have been issued on Soroban can not be exported to a Stellar trust line.* +Yes. Soroban contains a built-in Stellar Asset Contract that is able to interact +with classic trustlines. Read more about this [here](built-in-contracts/stellar-asset-contract.mdx). -### Do Issuers of Stellar Assets maintain their authorization over an asset that has been imported to Soroban? (AUTH_REQUIRED, AUTH_REVOCABLE, AUTH_CLAWBACK) -Yes. Issuers retain the same level of control on Soroban as they have on Classic . This functionality is accessible through a set of admin functions (freeze, burn) on the built in Soroban token contract. +### Do Issuers of Stellar Assets maintain their authorization over an asset that has been sent to a non-account identifer in Soroban? (AUTH_REQUIRED, AUTH_REVOCABLE, AUTH_CLAWBACK) +Yes. Issuers retain the same level of control on Soroban as they have on Classic. This functionality is accessible through a set of admin functions (clawback, set_auth) on the built-in Stellar Asset Contract. ### Can Soroban contracts interact with any other Stellar operations? No. Aside from the interactions with Accounts and Assets as mentioned above. This means that Soroban contracts can not interact with SDEX, AMMs, Claimable Balances or Sponsorships. @@ -30,11 +29,11 @@ No. Aside from the interactions with Accounts and Assets as mentioned above. Thi ### Does the Stellar base reserve apply to Soroban contracts? No. Soroban has a different fee structure and ledger entries that are allocated by Soroban contracts do not add to an account's required minimal balance. -### Should I issue my token as a Stellar Asset or a Soroban token? -We recommend, to the extent possible, issuing tokens as Stellar assets. These tokens will benefit from being interopable with the existing ecosystem of tools available in the Stellar ecosystem, and will be usable on Soroban through import/export functionality. - -### How should Wallets handle Accounts having a Stellar and Soroban balance? -Best practices are still being explored. At this time we recommend: (1) displaying separate balances for Soroban and Stellar Assets, (2) allowing users to import/export between them and (3) executing payments based on the origin: Stellar payments for trust lines and Soroban token transfers for Soroban token balances +### Should I issue my token as a Stellar Asset or a custom Soroban token? +We recommend, to the extent possible, issuing tokens as Stellar assets. These +tokens will benefit from being interopable with the existing ecosystem of tools +available in the Stellar ecosystem, as well as being more performant because the +Stellar Asset Contract is built into the host. ### Haven't found what you're looking for? Join #soroban on the Stellar developer discord diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index ce480a326..3d8aafff7 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -11,7 +11,7 @@ operations: - Invoke contract functions. - Install WASM of the new contracts. - Deploy new contracts using the installed WASM or built-in implementations ( - this currently includes only the [token contract](../built-in-contracts/token.mdx)). + this currently includes only the [token contract](../built-in-contracts/stellar-asset-contract.mdx)). [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From cee975f6d0062ad891395081bd7c705b831b06ae Mon Sep 17 00:00:00 2001 From: Jay Geng Date: Mon, 9 Jan 2023 14:17:12 -0500 Subject: [PATCH 110/248] Update various sdk, auth, examples versions from 0.3.2 to 0.4.2 --- docs/getting-started/quick-start.mdx | 4 ++-- docs/tutorials/create-a-project.mdx | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index df720a30b..e8610a861 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -42,10 +42,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.3.2" +soroban-sdk = "0.4.2" [dev_dependencies] -soroban-sdk = { version = "0.3.2", features = ["testutils"] } +soroban-sdk = { version = "0.4.2", features = ["testutils"] } [profile.release] opt-level = "z" diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index d9e46edbe..9fdc80082 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -44,10 +44,10 @@ The `soroban-sdk` is in early development. Report issues ```toml [dependencies] -soroban-sdk = "0.3.2" +soroban-sdk = "0.4.2" [dev_dependencies] -soroban-sdk = { version = "0.3.2", features = ["testutils"] } +soroban-sdk = { version = "0.4.2", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -122,10 +122,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.3.2" +soroban-sdk = "0.4.2" [dev_dependencies] -soroban-sdk = { version = "0.3.2", features = ["testutils"] } +soroban-sdk = { version = "0.4.2", features = ["testutils"] } [profile.release] opt-level = "z" From 2084cbb1db711b3fd826697212a5f98735367aeb Mon Sep 17 00:00:00 2001 From: tsachiherman <24438559+tsachiherman@users.noreply.github.com> Date: Mon, 9 Jan 2023 17:25:04 -0500 Subject: [PATCH 111/248] fix doc --- docs/getting-started/setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index befa3e974..dc87df65d 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.3.3 soroban-cli +cargo install --locked --version 0.4.0 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -soroban 0.3.3 +soroban 0.4.0 https://soroban.stellar.org USAGE: From aa9783f40c40749ffa402cb385a18d650eb48697 Mon Sep 17 00:00:00 2001 From: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> Date: Mon, 9 Jan 2023 17:34:38 -0500 Subject: [PATCH 112/248] fix doc (#268) --- docs/getting-started/setup.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index befa3e974..dc87df65d 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -54,7 +54,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.3.3 soroban-cli +cargo install --locked --version 0.4.0 soroban-cli ``` :::info @@ -72,7 +72,7 @@ soroban ``` ❯ soroban -soroban 0.3.3 +soroban 0.4.0 https://soroban.stellar.org USAGE: From f7b5d280df434c8959582232bda663e1b56c3a57 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Tue, 17 Jan 2023 10:46:58 -0800 Subject: [PATCH 113/248] Support arm64 images in docs for quickstart (#274) --- docs/tutorials/deploy-to-futurenet.mdx | 3 +-- docs/tutorials/deploy-to-local-network.mdx | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index f0d21e4b3..9795e32c1 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -19,10 +19,9 @@ Docker image, run the following command. ```sh docker run --rm -it \ - --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:8046391718f8e58b2b88b9c379abda3587bb874689fa09b2ed4871a764ebda27 \ + stellar/quickstart:soroban-dev \ --futurenet \ --enable-soroban-rpc ``` diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index da6754446..ac9927686 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -26,10 +26,9 @@ run the following command. ```sh docker run --rm -it \ - --platform linux/amd64 \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:8046391718f8e58b2b88b9c379abda3587bb874689fa09b2ed4871a764ebda27 \ + stellar/quickstart:soroban-dev \ --standalone \ --enable-soroban-rpc ``` From a7e6c5b82ecc58f12fa1c51d6582331695e4da8e Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 3 Feb 2023 14:47:55 -0500 Subject: [PATCH 114/248] update all admonitions such that prettier doesn't yell --- docs/faq.mdx | 2 ++ docs/getting-started/quick-start.mdx | 6 ++++++ docs/getting-started/setup.mdx | 2 ++ docs/tutorials/build-optimized.mdx | 2 ++ docs/tutorials/build.mdx | 4 ++++ docs/tutorials/create-a-project.mdx | 4 ++++ docs/tutorials/deploy-to-futurenet.mdx | 6 ++++++ docs/tutorials/deploy-to-local-network.mdx | 6 ++++++ docs/tutorials/run-on-sandbox.mdx | 2 ++ 9 files changed, 34 insertions(+) diff --git a/docs/faq.mdx b/docs/faq.mdx index 7b69ad193..874db107a 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -4,7 +4,9 @@ title: Soroban on Stellar FAQ --- :::caution + Soroban's Stellar integration is under active-development and may change. + ::: ### What is Soroban to Stellar? Is it a new blockchain? diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index e8610a861..fc5107edf 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -30,8 +30,10 @@ edition = "2021" Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. :::info + Report issues and share feedback about the `soroban-sdk` [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). + ::: ```toml @@ -66,12 +68,14 @@ The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. :::info + The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write [Rust integration tests], or write tests from another crate, you'll need to add `#[cfg(feature = "testutils")]` to those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. + ::: The config for the `release` profile configures the Rust toolchain to produce @@ -150,7 +154,9 @@ target/wasm32-unknown-unknown/release/first_project.wasm ``` :::info + Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. + ::: ## Run the Contract diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index dc87df65d..97c91d2b6 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -58,8 +58,10 @@ cargo install --locked --version 0.4.0 soroban-cli ``` :::info + Report issues and share feedback about the Soroban CLI [here](https://github.com/stellar/soroban-cli/issues/new/choose). + ::: ### Usage diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index 9ccd26bf1..89683ae39 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -10,10 +10,12 @@ Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. :::tip + Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. See [Build] for details on how to build for development. + ::: [Build]: build.mdx diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx index e2a0ee486..b351bf251 100644 --- a/docs/tutorials/build.mdx +++ b/docs/tutorials/build.mdx @@ -10,8 +10,10 @@ cargo build --target wasm32-unknown-unknown --release ``` :::tip + Use the `release` profile outlined in [Configure the Release Profile], otherwise the contract will exceed Soroban's size limits. + ::: A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is @@ -27,7 +29,9 @@ This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. :::tip + To further optimize builds to be as small as possible, see [Optimizing Builds]. + ::: [Configure the Release Profile]: create-a-project#configure-the-release-profile diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 9fdc80082..0fa2252f8 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -38,8 +38,10 @@ Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. :::caution + The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). + ::: ```toml @@ -57,11 +59,13 @@ The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. :::info + The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write tests from another crate, you'll need to require the `testutils` feature for those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. + ::: ## Configure the `release` Profile diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 9795e32c1..77d0f7fb5 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -10,8 +10,10 @@ local node to deploy. [Futurenet]: ../networks/futurenet :::info + It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. + ::: To run a local node for the [Futurenet] network with the Stellar Quickstart @@ -40,9 +42,11 @@ account ID. The `S...` key is the secret key and is that you use to control the account. :::tip + It's a good practice to never use the same keys for testing and development that you use for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. + ::: Create an account on the [Futurenet] network by making a request to the @@ -66,11 +70,13 @@ soroban deploy \ ``` :::tip + It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. + ::: A contract ID will be outputted. diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index ac9927686..3c57aeaa3 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -17,8 +17,10 @@ finalizes ledgers. networks. :::info + It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. + ::: To run a local standalone network with the Stellar Quickstart Docker image, @@ -44,9 +46,11 @@ public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. :::tip + It's a good practice to never use the same keys for testing and development that you use do for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. + ::: Create an account on the local sandbox environment by making a request to the @@ -70,11 +74,13 @@ soroban deploy \ ``` :::tip + It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. + ::: A contract ID will be outputted. diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx index 71008f443..0c6aa7d44 100644 --- a/docs/tutorials/run-on-sandbox.mdx +++ b/docs/tutorials/run-on-sandbox.mdx @@ -11,8 +11,10 @@ Stellar networks, but it runs without nodes, and without the other features you find on a Stellar network. :::info + It's also possible to run a contract on a fully featured local network. See [Deploy to a Local Network] for more details. + ::: Using the code we wrote in [Write a Contract] and the resulting `.wasm` file From b2643e7a4992fdcf99890237c72889d2dcc44e70 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 3 Feb 2023 14:54:27 -0500 Subject: [PATCH 115/248] Lots of formatting --- docs/faq.mdx | 15 ++- docs/getting-started/quick-start.mdx | 3 +- docs/getting-started/setup.mdx | 1 - docs/tutorials/build-optimized.mdx | 4 +- docs/tutorials/create-a-project.mdx | 2 +- docs/tutorials/deploy-to-futurenet.mdx | 3 +- docs/tutorials/deploy-to-local-network.mdx | 7 +- .../invoking-contracts-with-transactions.mdx | 100 ++++++++++-------- docs/tutorials/run-on-sandbox.mdx | 4 +- docs/tutorials/testing.mdx | 6 +- docs/tutorials/write-a-contract.mdx | 1 + 11 files changed, 81 insertions(+), 65 deletions(-) diff --git a/docs/faq.mdx b/docs/faq.mdx index 874db107a..13b6afee6 100644 --- a/docs/faq.mdx +++ b/docs/faq.mdx @@ -10,32 +10,41 @@ Soroban's Stellar integration is under active-development and may change. ::: ### What is Soroban to Stellar? Is it a new blockchain? -Soroban is not a new blockchain. Soroban is a Smart contract platform that is integrated into the existing Stellar blockchain. It is an *additive* feature that lives alongside, and doesn't replace, the existing set of Stellar operations. + +Soroban is not a new blockchain. Soroban is a Smart contract platform that is integrated into the existing Stellar blockchain. It is an _additive_ feature that lives alongside, and doesn't replace, the existing set of Stellar operations. ### How do I invoke a Soroban contract on Stellar? + A Soroban contract can be invoked by submitting a transaction that contains the new operation: `InvokeContractOp`. ### Can Soroban contracts use Stellar accounts for authentication? -Yes. Stellar accounts are shared with Soroban. Smart contacts have access to Stellar account signer configuration and know the source account that directly invoked them in a transaction. Check out the Auth and Advanced Auth examples for more information. + +Yes. Stellar accounts are shared with Soroban. Smart contacts have access to Stellar account signer configuration and know the source account that directly invoked them in a transaction. Check out the Auth and Advanced Auth examples for more information. ### Can Soroban contracts interact with Stellar Assets? + Yes. Soroban contains a built-in Stellar Asset Contract that is able to interact with classic trustlines. Read more about this [here](built-in-contracts/stellar-asset-contract.mdx). ### Do Issuers of Stellar Assets maintain their authorization over an asset that has been sent to a non-account identifer in Soroban? (AUTH_REQUIRED, AUTH_REVOCABLE, AUTH_CLAWBACK) + Yes. Issuers retain the same level of control on Soroban as they have on Classic. This functionality is accessible through a set of admin functions (clawback, set_auth) on the built-in Stellar Asset Contract. ### Can Soroban contracts interact with any other Stellar operations? -No. Aside from the interactions with Accounts and Assets as mentioned above. This means that Soroban contracts can not interact with SDEX, AMMs, Claimable Balances or Sponsorships. + +No. Aside from the interactions with Accounts and Assets as mentioned above. This means that Soroban contracts can not interact with SDEX, AMMs, Claimable Balances or Sponsorships. ### Does the Stellar base reserve apply to Soroban contracts? + No. Soroban has a different fee structure and ledger entries that are allocated by Soroban contracts do not add to an account's required minimal balance. ### Should I issue my token as a Stellar Asset or a custom Soroban token? + We recommend, to the extent possible, issuing tokens as Stellar assets. These tokens will benefit from being interopable with the existing ecosystem of tools available in the Stellar ecosystem, as well as being more performant because the Stellar Asset Contract is built into the host. ### Haven't found what you're looking for? + Join #soroban on the Stellar developer discord diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx index fc5107edf..2f3fe9cea 100644 --- a/docs/getting-started/quick-start.mdx +++ b/docs/getting-started/quick-start.mdx @@ -175,10 +175,9 @@ soroban invoke \ You should see the following output: ```json -["Hello","friend"] +["Hello", "friend"] ``` [`soroban-cli`]: setup#install-the-soroban-cli - [Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html [Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 97c91d2b6..0e7ebf18d 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -98,6 +98,5 @@ SUBCOMMANDS: completion Print shell completion code for the specified shell ``` - [Rust]: https://www.rust-lang.org/ [Soroban CLI]: setup#install-the-soroban-cli diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx index 89683ae39..efb72fe33 100644 --- a/docs/tutorials/build-optimized.mdx +++ b/docs/tutorials/build-optimized.mdx @@ -3,8 +3,8 @@ sidebar_position: 11 title: Optimizing Builds --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx index 0fa2252f8..2ba56f608 100644 --- a/docs/tutorials/create-a-project.mdx +++ b/docs/tutorials/create-a-project.mdx @@ -93,7 +93,7 @@ lto = true Configuring a `release-with-logs` profile can be useful for if you need to build a `.wasm` that has logs enabled for printing debug logs when using the -[`soroban-cli`]. Note that this is not necessary to access debug logs in tests +[`soroban-cli`]. Note that this is not necessary to access debug logs in tests or to use a step-through-debugger. Add the following to your `Cargo.toml` and use the `release-with-logs` profile diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/tutorials/deploy-to-futurenet.mdx index 77d0f7fb5..e14a4bb62 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/tutorials/deploy-to-futurenet.mdx @@ -29,6 +29,7 @@ docker run --rm -it \ ``` Once the image is started you can check its status by querying the Horizon API: + ```sh curl http://localhost:8000 ``` @@ -101,7 +102,7 @@ soroban invoke \ The following output should appear. ```json -["Hello","friend"] +["Hello", "friend"] ``` [Write a Contract]: write-a-contract diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/tutorials/deploy-to-local-network.mdx index 3c57aeaa3..dcf7db5f1 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/tutorials/deploy-to-local-network.mdx @@ -10,11 +10,11 @@ The Quickstart image is a single container that runs everything you need to test against a fully featured network. It contains: - Stellar Core – Node software that runs the network, coordinates consensus, and -finalizes ledgers. + finalizes ledgers. - Soroban RPC server – JSON RPC server for interacting with Soroban contracts. - Horizon server – HTTP API for access ledger state and historical transactions. - Friendbot server – HTTP API for creating and funding new accounts on test -networks. + networks. :::info @@ -36,6 +36,7 @@ docker run --rm -it \ ``` Once the image is started you can check its status by querying the Horizon API: + ```sh curl http://localhost:8000 ``` @@ -105,7 +106,7 @@ soroban invoke \ The following output should appear. ```json -["Hello","friend"] +["Hello", "friend"] ``` [Write a Contract]: write-a-contract diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx index 3d8aafff7..2ac446627 100644 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ b/docs/tutorials/invoking-contracts-with-transactions.mdx @@ -6,8 +6,9 @@ title: Invoking and Creating Contracts with Stellar Transactions Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. -The `InvokeHostFunctionOp` can be used to perform the following Soroban +The `InvokeHostFunctionOp` can be used to perform the following Soroban operations: + - Invoke contract functions. - Install WASM of the new contracts. - Deploy new contracts using the installed WASM or built-in implementations ( @@ -19,6 +20,7 @@ operations: The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found [here](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L523-L539) + ```c++ union HostFunction switch (HostFunctionType type) { @@ -40,32 +42,34 @@ struct InvokeHostFunctionOp ``` ### Function -The `function` in `InvokeHostFunctionOp` will be executed by the Soroban host + +The `function` in `InvokeHostFunctionOp` will be executed by the Soroban host environment. The function arguments are passed as function-dependent XDR. The options are: + 1. `HOST_FUNCTION_TYPE_INVOKE_CONTRACT` - This will call the `call_n` host function, invoking a contract function. - - `invokeArgs` is expected to contain the contract id, contract function - name, and the parameters to the contract function being invoked. + - `invokeArgs` is expected to contain the contract id, contract function + name, and the parameters to the contract function being invoked. 2. `HOST_FUNCTION_TYPE_INSTALL_CONTRACT_CODE` - This will install the contract WASM using the provided `code` blob: - ```c++ - struct InstallContractCodeArgs - { - opaque code; - }; - ``` + ```c++ + struct InstallContractCodeArgs + { + opaque code; + }; + ``` 3. `HOST_FUNCTION_TYPE_CREATE_CONTRACT` - This will create a contract instance in the network using the specified `source` and build a 32-byte contract identifer based on `contractID` value. - ```c++ - struct CreateContractArgs - { - ContractID contractID; - SCContractCode source; - }; - ``` - - `source` can be either a reference to the hash of the installed WASM (to + ```c++ + struct CreateContractArgs + { + ContractID contractID; + SCContractCode source; + }; + ``` + - `source` can be either a reference to the hash of the installed WASM (to be more precise, a SHA-256 hash of the `InstallContractCodeArgs` from the operation above) or just specify that a built-in contract has to be used: ```c++ union SCContractCode switch (SCContractCodeType type) @@ -76,38 +80,40 @@ options are: void; }; ``` - - `contractID` is defined as following: - ```c++ - union ContractID switch (ContractIDType type) - { - case CONTRACT_ID_FROM_SOURCE_ACCOUNT: - uint256 salt; - case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: - struct - { - uint256 key; - Signature signature; - uint256 salt; - } fromEd25519PublicKey; - case CONTRACT_ID_FROM_ASSET: - Asset asset; - }; - ``` - - The parameters of this value define which the hash preimage that is then hashed - with SHA-256 to get the ID of the created contract. - - `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created - using the Stellar source account and the provided salt. The contract ID + +- `contractID` is defined as following: + ```c++ + union ContractID switch (ContractIDType type) + { + case CONTRACT_ID_FROM_SOURCE_ACCOUNT: + uint256 salt; + case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: + struct + { + uint256 key; + Signature signature; + uint256 salt; + } fromEd25519PublicKey; + case CONTRACT_ID_FROM_ASSET: + Asset asset; + }; + ``` +- The parameters of this value define which the hash preimage that is then hashed + with SHA-256 to get the ID of the created contract. +- `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created + using the Stellar source account and the provided salt. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_SOURCE_ACCOUNT`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L643-L649). - - `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using - the Stellar asset. This is only suported when - `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist - when this is applied, however the issuer of the asset will be the initial - token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). - - `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be +- `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using + the Stellar asset. This is only suported when + `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist + when this is applied, however the issuer of the asset will be the initial + token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). +- `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be created using a public ED25519 key. Since this operation is not tied to any - on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR + on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR preimage. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ED25519`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L623-L629). ### Footprint + The footprint must contain the `LedgerKeys` that will be read and/or written. More -information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). \ No newline at end of file +information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx index 0c6aa7d44..2cc3237cf 100644 --- a/docs/tutorials/run-on-sandbox.mdx +++ b/docs/tutorials/run-on-sandbox.mdx @@ -12,7 +12,7 @@ find on a Stellar network. :::info -It's also possible to run a contract on a fully featured local network. See +It's also possible to run a contract on a fully featured local network. See [Deploy to a Local Network] for more details. ::: @@ -32,7 +32,7 @@ soroban invoke \ The following output should appear. ```json -["Hello","friend"] +["Hello", "friend"] ``` [Write a Contract]: write-a-contract diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx index 6639ab991..248a458a5 100644 --- a/docs/tutorials/testing.mdx +++ b/docs/tutorials/testing.mdx @@ -3,8 +3,8 @@ sidebar_position: 5 title: Testing --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. @@ -55,7 +55,6 @@ fn test() { } ``` - @@ -86,6 +85,7 @@ let words = client.hello(&symbol!("Dev")); ``` The values returned by functions can be asserted on: + ```rust assert_eq!( words, diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index 6a2dbe15d..2d377cd4c 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -61,4 +61,5 @@ impl Contract { } } ``` + [Create a Project]: create-a-project.mdx From b28dfa7ecb29b44e6df8e8f97fc41dad73440823 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Tue, 7 Feb 2023 16:32:46 -0500 Subject: [PATCH 116/248] Reorg (#290) * Change SDK section to Reference section * Adding JS SDK to list of SDKs * Adding Overcat's Python SDK to list of SDKs * Moving Networks -> Futurenet to Reference section * Moving Releases to Reference section * Delete Networks from main nav Networks now lives under Reference section * Deleting as Releases now live in Reference section * Changing sidebar position Temporary, this will eventually move to How-To Guides * Update byo.mdx * Edited Quick Start to 1. Hello World Includes Tutorials -> Create a Project / Write a Contract / Test / Build / Run on Sandbox / Optimizing Builds * Move Storing Data from Examples to Getting Started * Move Deploy to Local Network to Getting Started Moved this section from Tutorials to Getting Started * Move Freighter wallet tutorial to Getting Started * Update and rename 6.-connect-Freighter-wallet.mdx to 4. Connect Freighter Wallet * Move Deploy to Futurenet to Getting Started * Rename 4. Connect Freighter Wallet to 4. Connect Freighter Wallet.mdx * Moved to Getting Started * Moved to Getting Started Removing this section * Moved to Getting Started Removing this as it has been moved to Getting Started * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * Moved to Getting Started Removing due to this section being moved * Update Examples to How-To Guides * Move BYO SDK to How-To Guides * Moved to How-To Guides * Moved invoking contracts with transactions to How-To Guides * Removing because it's moved to How-To Guides * Moved Token Interface to Token How-To Guide * Remove Token Interface Token Interface has been moved to How-To Guides -> Token * Move Stellar Asset Contract to How-To Guides * Delete docs/built-in-contracts directory Moved to How-To Guides * Move Stellar FAQs to Learn * Delete faq.mdx Moved to Learn * Update authorization.mdx Alphabetize sidebar * Update contract-lifecycle.mdx Alphabetizing sidebar * Update custom-types.mdx Alphabetizing sidebar * Update rust-dialect.mdx Alphabetizing sidebar * Update debugging.mdx Alphabetizing sidebar * Update environment-concepts.mdx Alphabetizing sidebar * Update errors.mdx Alphabetizing sidebar * Update events.mdx Alphabetizing sidebar * Update gas-and-metering.mdx Alphabetizing sidebar * Update interacting-with-contracts.mdx Alphabetizing sidebar * Update persisting-data.mdx Alphabetizing sidebar * Update high-level-overview.mdx Update spelling * formatting * formatting * formatting * formatting * Update faq.mdx * fixed broken links * fix broken links * fix broken links * moar link fixes * fixed some broken links * added sorobanathon homepage * add google tag manager * Content edits made * back to original * Content Edit * button location * Content & Eligibility guidelines added * Update sorobanathon.js * update all admonitions such that prettier doesn't yell * Lots of formatting * --prose-wrap preserve * Update releases.mdx * update prettier * fixed the callouts * formatting * fix module import * Update sorobanathon.js * Fixed Reorg PR Fixed links, moved sections, deleted double sections * Update index.js * Updating Sorobanathon Info * Fixed links Many links. * Formatting * Change SDK section to Reference section * Adding JS SDK to list of SDKs * Adding Overcat's Python SDK to list of SDKs * Moving Networks -> Futurenet to Reference section * Moving Releases to Reference section * Delete Networks from main nav Networks now lives under Reference section * Deleting as Releases now live in Reference section * Changing sidebar position Temporary, this will eventually move to How-To Guides * Update byo.mdx * formatting * fix broken links * Edited Quick Start to 1. Hello World Includes Tutorials -> Create a Project / Write a Contract / Test / Build / Run on Sandbox / Optimizing Builds * Move Storing Data from Examples to Getting Started * Move Deploy to Local Network to Getting Started Moved this section from Tutorials to Getting Started * Move Freighter wallet tutorial to Getting Started * Update and rename 6.-connect-Freighter-wallet.mdx to 4. Connect Freighter Wallet * Move Deploy to Futurenet to Getting Started * Rename 4. Connect Freighter Wallet to 4. Connect Freighter Wallet.mdx * Moved to Getting Started Removing this as it has been moved to Getting Started * Moved to Getting Started -> Hello World * Moved to Getting Started -> Hello World * formatting * fix broken links * moar link fixes * Update Examples to How-To Guides * Move BYO SDK to How-To Guides * Moved invoking contracts with transactions to How-To Guides * Moved Token Interface to Token How-To Guide * Remove Token Interface Token Interface has been moved to How-To Guides -> Token * Move Stellar Asset Contract to How-To Guides * Delete docs/built-in-contracts directory Moved to How-To Guides * formatting * fixed broken links * Move Stellar FAQs to Learn * Update authorization.mdx Alphabetize sidebar * Update contract-lifecycle.mdx Alphabetizing sidebar * Update custom-types.mdx Alphabetizing sidebar * Update rust-dialect.mdx Alphabetizing sidebar * Update debugging.mdx Alphabetizing sidebar * Update environment-concepts.mdx Alphabetizing sidebar * Update errors.mdx Alphabetizing sidebar * Update events.mdx Alphabetizing sidebar * Update gas-and-metering.mdx Alphabetizing sidebar * Update interacting-with-contracts.mdx Alphabetizing sidebar * Update persisting-data.mdx Alphabetizing sidebar * Update high-level-overview.mdx Update spelling * formatting * Update faq.mdx * fixed some broken links * Update releases.mdx * update prettier * fixed the callouts * formatting * fix module import * Fixed Reorg PR Fixed links, moved sections, deleted double sections * Fixed links Many links. * Formatting * Merge cleanup * More cleanup * Formatting * some small design tweaks * copy tweaks --------- Co-authored-by: Bri <92327786+briwylde08@users.noreply.github.com> Co-authored-by: Anuxhya <36203801+achallagundla@users.noreply.github.com> --- docs/faq.mdx | 50 -- .../connect-freighter-wallet.mdx | 18 + .../deploy-to-a-local-network.mdx} | 54 +-- .../deploy-to-futurenet.mdx | 51 +-- docs/getting-started/hello-world.mdx | 427 ++++++++++++++++++ docs/getting-started/quick-start.mdx | 183 -------- docs/getting-started/storing-data.mdx | 207 +++++++++ docs/tutorials/_category_.json | 7 - docs/tutorials/build-optimized.mdx | 89 ---- docs/tutorials/build.mdx | 38 -- docs/tutorials/create-a-project.mdx | 151 ------- .../invoking-contracts-with-transactions.mdx | 119 ----- docs/tutorials/run-on-sandbox.mdx | 41 -- docs/tutorials/testing.mdx | 112 ----- docs/tutorials/write-a-contract.mdx | 65 --- 15 files changed, 685 insertions(+), 927 deletions(-) delete mode 100644 docs/faq.mdx create mode 100644 docs/getting-started/connect-freighter-wallet.mdx rename docs/{tutorials/deploy-to-local-network.mdx => getting-started/deploy-to-a-local-network.mdx} (60%) rename docs/{tutorials => getting-started}/deploy-to-futurenet.mdx (57%) create mode 100644 docs/getting-started/hello-world.mdx delete mode 100644 docs/getting-started/quick-start.mdx create mode 100644 docs/getting-started/storing-data.mdx delete mode 100644 docs/tutorials/_category_.json delete mode 100644 docs/tutorials/build-optimized.mdx delete mode 100644 docs/tutorials/build.mdx delete mode 100644 docs/tutorials/create-a-project.mdx delete mode 100644 docs/tutorials/invoking-contracts-with-transactions.mdx delete mode 100644 docs/tutorials/run-on-sandbox.mdx delete mode 100644 docs/tutorials/testing.mdx delete mode 100644 docs/tutorials/write-a-contract.mdx diff --git a/docs/faq.mdx b/docs/faq.mdx deleted file mode 100644 index 13b6afee6..000000000 --- a/docs/faq.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -sidebar_position: 100 -title: Soroban on Stellar FAQ ---- - -:::caution - -Soroban's Stellar integration is under active-development and may change. - -::: - -### What is Soroban to Stellar? Is it a new blockchain? - -Soroban is not a new blockchain. Soroban is a Smart contract platform that is integrated into the existing Stellar blockchain. It is an _additive_ feature that lives alongside, and doesn't replace, the existing set of Stellar operations. - -### How do I invoke a Soroban contract on Stellar? - -A Soroban contract can be invoked by submitting a transaction that contains the new operation: `InvokeContractOp`. - -### Can Soroban contracts use Stellar accounts for authentication? - -Yes. Stellar accounts are shared with Soroban. Smart contacts have access to Stellar account signer configuration and know the source account that directly invoked them in a transaction. Check out the Auth and Advanced Auth examples for more information. - -### Can Soroban contracts interact with Stellar Assets? - -Yes. Soroban contains a built-in Stellar Asset Contract that is able to interact -with classic trustlines. Read more about this [here](built-in-contracts/stellar-asset-contract.mdx). - -### Do Issuers of Stellar Assets maintain their authorization over an asset that has been sent to a non-account identifer in Soroban? (AUTH_REQUIRED, AUTH_REVOCABLE, AUTH_CLAWBACK) - -Yes. Issuers retain the same level of control on Soroban as they have on Classic. This functionality is accessible through a set of admin functions (clawback, set_auth) on the built-in Stellar Asset Contract. - -### Can Soroban contracts interact with any other Stellar operations? - -No. Aside from the interactions with Accounts and Assets as mentioned above. This means that Soroban contracts can not interact with SDEX, AMMs, Claimable Balances or Sponsorships. - -### Does the Stellar base reserve apply to Soroban contracts? - -No. Soroban has a different fee structure and ledger entries that are allocated by Soroban contracts do not add to an account's required minimal balance. - -### Should I issue my token as a Stellar Asset or a custom Soroban token? - -We recommend, to the extent possible, issuing tokens as Stellar assets. These -tokens will benefit from being interopable with the existing ecosystem of tools -available in the Stellar ecosystem, as well as being more performant because the -Stellar Asset Contract is built into the host. - -### Haven't found what you're looking for? - -Join #soroban on the Stellar developer discord diff --git a/docs/getting-started/connect-freighter-wallet.mdx b/docs/getting-started/connect-freighter-wallet.mdx new file mode 100644 index 000000000..a0e29e632 --- /dev/null +++ b/docs/getting-started/connect-freighter-wallet.mdx @@ -0,0 +1,18 @@ +--- +sidebar_position: 6 +title: 4. Connect Freighter Wallet +--- + +## Signing Transactions with Freighter + +If you're building a JS dapp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): + +1. Install the Freighter browser extension. + +2. Create a keypair or import an existing account using a mnemonic phrase to complete setup. + +3. Next, switch to Experimental Mode to enable the Soroban SDK. In the extension, click the gear in the lower right corner and then navigate to `Preferences`. Toggle on `Experimental Mode`. + +4. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dapp to sign Soroban XDR's using the account in Freighter. + +Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dapp. diff --git a/docs/tutorials/deploy-to-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx similarity index 60% rename from docs/tutorials/deploy-to-local-network.mdx rename to docs/getting-started/deploy-to-a-local-network.mdx index dcf7db5f1..8874260a2 100644 --- a/docs/tutorials/deploy-to-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -1,30 +1,24 @@ --- -sidebar_position: 8 -title: Deploy to a Local Network +sidebar_position: 5 +title: 3. Deploy to a Local Network --- -If you have Docker installed, you can run a local standalone network with the -[Stellar Quickstart] Docker image. +If you have Docker installed, you can run a local standalone network with the [Stellar Quickstart] Docker image. -The Quickstart image is a single container that runs everything you need to test -against a fully featured network. It contains: +The Quickstart image is a single container that runs everything you need to test against a fully featured network. It contains: -- Stellar Core – Node software that runs the network, coordinates consensus, and - finalizes ledgers. +- Stellar Core – Node software that runs the network, coordinates consensus, and finalizes ledgers. - Soroban RPC server – JSON RPC server for interacting with Soroban contracts. - Horizon server – HTTP API for access ledger state and historical transactions. -- Friendbot server – HTTP API for creating and funding new accounts on test - networks. +- Friendbot server – HTTP API for creating and funding new accounts on test networks. :::info -It's also possible to run a contract in the local sandbox environment without a -network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. +It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. ::: -To run a local standalone network with the Stellar Quickstart Docker image, -run the following command. +To run a local standalone network with the Stellar Quickstart Docker image, run the following command. ```sh docker run --rm -it \ @@ -41,30 +35,21 @@ Once the image is started you can check its status by querying the Horizon API: curl http://localhost:8000 ``` -Generate a key for use on the local sandbox environment by going to the [Stellar -Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the -public key and will also be the account ID. The `S...` key is the secret key and -is that you use to control the account. +Generate a key for use on the local sandbox environment by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. :::tip -It's a good practice to never use the same keys for testing and development that -you use do for the public Stellar network. Generate new keys for testing and -development and avoid ever using them for other purposes. +It's a good practice to never use the same keys for testing and development that you use do for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. ::: -Create an account on the local sandbox environment by making a request to the -local Friendbot. Specify as the `addr` the `G...` key of your account. +Create an account on the local sandbox environment by making a request to the local Friendbot. Specify as the `addr` the `G...` key of your account. ```sh curl "http://localhost:8000/friendbot?addr=G..." ``` -Once you have an account on the network, we'll use the code we wrote in [Write a -Contract] and the resulting `.wasm` file we built in [Build] as our contract to -deploy. Run the following commands to deploy the contract to the network. Use -the `S...` key as the secret key. +Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. ```sh soroban deploy \ @@ -76,11 +61,7 @@ soroban deploy \ :::tip -It's good practice to avoid entering secret keys on the command line. You can -also specify the secret key by setting the environment variable -`SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the -future there will be other secure ways to provide a secret key, such as via -hardware keys. +It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. ::: @@ -90,8 +71,7 @@ A contract ID will be outputted. cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 ``` -Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the -`hello` function with a single argument `friend`. +Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh soroban invoke \ @@ -109,10 +89,10 @@ The following output should appear. ["Hello", "friend"] ``` -[Write a Contract]: write-a-contract +[Write a Contract]: hello-world#write-a-contract [Run on a Local Network]: run-on-local-network -[Build]: build +[Build]: hello-world#build [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli [Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test -[Run on Sandbox]: run-on-sandbox +[Run on Sandbox]: hello-world#run-on-sandbox [Stellar Quickstart]: https://github.com/stellar/quickstart diff --git a/docs/tutorials/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx similarity index 57% rename from docs/tutorials/deploy-to-futurenet.mdx rename to docs/getting-started/deploy-to-futurenet.mdx index e14a4bb62..4dce42719 100644 --- a/docs/tutorials/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -1,23 +1,19 @@ --- -sidebar_position: 9 -title: Deploy to Futurenet +sidebar_position: 7 +title: 5. Deploy to Futurenet --- -If you have Docker installed, you can run a local node with the [Stellar -Quickstart] Docker image that joins the [Futurenet] network, and then use that -local node to deploy. +If you have Docker installed, you can run a local node with the [Stellar Quickstart] Docker image that joins the [Futurenet] network, and then use that local node to deploy. -[Futurenet]: ../networks/futurenet +[Futurenet]: ../reference/futurenet :::info -It's also possible to run a contract in the local sandbox environment without a -network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. +It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. ::: -To run a local node for the [Futurenet] network with the Stellar Quickstart -Docker image, run the following command. +To run a local node for the [Futurenet] network with the Stellar Quickstart Docker image, run the following command. ```sh docker run --rm -it \ @@ -34,33 +30,23 @@ Once the image is started you can check its status by querying the Horizon API: curl http://localhost:8000 ``` -It takes sometime to join a remote network. Monitor the output of that endpoint -until you see the `core_latest_ledger` become a number above zero. +It takes sometime to join a remote network. Monitor the output of that endpoint until you see the `core_latest_ledger` become a number above zero. -Generate a key by going to the [Stellar Laboratory]. Make note of both the -`G...` and `S...` keys. The `G...` key is the public key and will also be the -account ID. The `S...` key is the secret key and is that you use to control the -account. +Generate a key by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. :::tip -It's a good practice to never use the same keys for testing and development that -you use for the public Stellar network. Generate new keys for testing and -development and avoid ever using them for other purposes. +It's a good practice to never use the same keys for testing and development that you use for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. ::: -Create an account on the [Futurenet] network by making a request to the -Friendbot. Specify as the `addr` the `G...` key of your account. +Create an account on the [Futurenet] network by making a request to the Friendbot. Specify as the `addr` the `G...` key of your account. ```sh curl "https://friendbot-futurenet.stellar.org/?addr=G..." ``` -Once you have an account on the network, we'll use the code we wrote in [Write a -Contract] and the resulting `.wasm` file we built in [Build] as our contract to -deploy. Run the following commands to deploy the contract to the network. Use -the `S...` key as the secret key. +Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. ```sh soroban deploy \ @@ -72,11 +58,7 @@ soroban deploy \ :::tip -It's good practice to avoid entering secret keys on the command line. You can -also specify the secret key by setting the environment variable -`SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the -future there will be other secure ways to provide a secret key, such as via -hardware keys. +It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. ::: @@ -86,8 +68,7 @@ A contract ID will be outputted. cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 ``` -Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the -`hello` function with a single argument `friend`. +Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh soroban invoke \ @@ -105,10 +86,10 @@ The following output should appear. ["Hello", "friend"] ``` -[Write a Contract]: write-a-contract +[Write a Contract]: hello-world#write-a-contract [Run on a Local Network]: run-on-local-network -[Build]: build +[Build]: hello-world#build [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli [Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test -[Run on Sandbox]: run-on-sandbox +[Run on Sandbox]: hello-world#run-on-sandbox [Stellar Quickstart]: https://github.com/stellar/quickstart diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx new file mode 100644 index 000000000..4720467b1 --- /dev/null +++ b/docs/getting-started/hello-world.mdx @@ -0,0 +1,427 @@ +--- +sidebar_position: 3 +title: 1. Hello World +--- + +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +Once you've [Setup] your development environment, you're ready to create your first Soroban contract. + +[Setup]: setup.mdx + +## Create New Project + +Create a new Rust library using the `cargo new` command. + +```sh +cargo new --lib [project-name] +``` + +Open the `Cargo.toml`, it should look something like this: + +```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2021" +``` + +### Configure the Library Type + +Add the `crate-type` configuration, required for building contracts. + +```toml +[lib] +crate-type = ["cdylib"] +``` + +### Import `soroban-sdk` and Features + +Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`, and configure a set of features explained below. + +:::caution + +The `soroban-sdk` is in early development. Report issues [here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). + +::: + +```toml +[dependencies] +soroban-sdk = "0.4.2" + +[dev_dependencies] +soroban-sdk = { version = "0.4.2", features = ["testutils"] } + +[features] +testutils = ["soroban-sdk/testutils"] +``` + +The `features` list includes a `testutils` feature, which will cause additional test utilities to be generated for calling the contract in tests. + +:::info + +The `testutils` test utilities are automatically enabled inside [Rust unit tests] inside the same crate as your contract. If you write tests from another crate, you'll need to require the `testutils` feature for those tests and enable the `testutils` feature when running your tests with `cargo test --features testutils` to be able to use those test utilities. + +::: + +### Configure the `release` Profile + +Configuring the `release` profile to optimize the contract build is critical. Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, without these configurations almost always exceed this size. + +Add the following to your `Cargo.toml` and use the `release` profile when building. + +```toml +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true +``` + +### Configure the `release-with-logs` Profile + +Configuring a `release-with-logs` profile can be useful for if you need to build a `.wasm` that has logs enabled for printing debug logs when using the [`soroban-cli`]. Note that this is not necessary to access debug logs in tests or to use a step-through-debugger. + +Add the following to your `Cargo.toml` and use the `release-with-logs` profile when you need logs. + +```toml +[profile.release-with-logs] +inherits = "release" +debug-assertions = true +``` + +See the [logging example] for more information about how to log. + +[logging example]: ../how-to guides/logging.mdx + +### Wrapping it Up + +The steps below should produce a `Cargo.toml` that looks like so. + +```toml title="Cargo.toml" +[package] +name = "project-name" +version = "0.1.0" +edition = "2022" + +[lib] +crate-type = ["cdylib"] + +[features] +testutils = ["soroban-sdk/testutils"] + +[dependencies] +soroban-sdk = "0.4.2" + +[dev_dependencies] +soroban-sdk = { version = "0.4.2", features = ["testutils"] } + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true +``` + +[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli + +## Write a Contract + +Once you've created a project, writing a contract involves writing Rust code in the projects `lib.rs` file. + +```rust +#![no_std] +``` + +All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains. + +```rust +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +``` + +The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project] to see how to setup a project. + +Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. + +```rust +pub struct Contract; + +#[contractimpl] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + todo!() + } +} +``` + +Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. + +Putting those pieces together a simple contract will look like this. + +```rust title="src/lib.rs" +#![no_std] +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; + +pub struct Contract; + +#[contractimpl] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + vec![&env, symbol!("Hello"), to] + } +} +``` + +## Testing + +Writing tests for Soroban contracts involves writing Rust code using the test facilities and toolchain that you'd use for testing any Rust code. + +Given a simple contract like the contract demonstrated in the Write a Contract section, a simple test will look like this. + + + + +```rust +#![no_std] +use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; + +pub struct Contract; + +#[contractimpl] +impl Contract { + pub fn hello(env: Env, to: Symbol) -> Vec { + vec![&env, symbol!("Hello"), to] + } +} + +#[cfg(test)] +mod test; +``` + + + + +```rust +#![cfg(test)] + +use super::{Contract, ContractClient}; +use soroban_sdk::{symbol, vec, Env}; + +#[test] +fn test() { + let env = Env::default(); + let contract_id = env.register_contract(None, Contract); + let client = ContractClient::new(&env, &contract_id); + + let words = client.hello(&symbol!("Dev")); + assert_eq!( + words, + vec![&env, symbol!("Hello"), symbol!("Dev"),] + ); +} +``` + + + + +In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run inside of. + +```rust +let env = Env::default(); +``` + +The contract is registered with the environment using the contract type. Contracts can specify a fixed contract ID as the first argument, or provide `None` and one will be generated. + +```rust +let contract_id = env.register_contract(None, Contract); +``` + +All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `Contract`, and the client is named `ContractClient`. + +```rust +let client = ContractClient::new(&env, &contract_id); +let words = client.hello(&symbol!("Dev")); +``` + +The values returned by functions can be asserted on: + +```rust +assert_eq!( + words, + vec![&env, symbol!("Hello"), symbol!("Dev"),] +); +``` + +### Run the Tests + +Run `cargo test` and watch the contract run. You should see the following output: + +```sh +cargo test +``` + +``` +running 1 test +test test::test ... ok +``` + +Try changing the values in the test to see how it works. + +[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html +[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html + +## Build + +To build a Soroban contract to deploy or run, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +:::tip + +Use the `release` profile outlined in [Configure the Release Profile], otherwise the contract will exceed Soroban's size limits. + +::: + +A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. + +``` +target/wasm32-unknown-unknown/release/[project-name].wasm +``` + +The `.wasm` file contains the logic of the contract, as well as the contract's specification that can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. + +:::tip + +To further optimize builds to be as small as possible, see [Optimizing Builds]. + +::: + +[Configure the Release Profile]: #configure-the-release-profile +[Optimizing Builds]: #optimizing-builds + +## Run on Sandbox + +If you have the [`soroban-cli`] installed, you can run contracts in a local sandbox environment. + +The Soroban sandbox environment is the same Soroban environment that runs on Stellar networks, but it runs without nodes, and without the other features you find on a Stellar network. + +:::info + +It's also possible to run a contract on a fully featured local network. See [Deploy to a Local Network] for more details. + +::: + +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] run the following command to invoke the `hello` function with a single argument `friend`. + +```sh +soroban invoke \ + --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ + --id 1 \ + --fn hello \ + --arg friend +``` + +The following output should appear. + +```json +["Hello", "friend"] +``` + +[Write a Contract]: #write-a-contract +[Deploy to a Local Network]: deploy-to-a-local-network +[Build]: #build +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli + +## Optimizing Builds + +Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. + +:::tip + +Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. See [Build] for details on how to build for development. + +::: + +[Build]: #build + +### Install Rust `nightly` + +To install the nightly Rust toolchain use [`rustup`]. + +[`rustup`]: ../getting-started/setup#install-rust + +```sh +rustup install nightly +rustup target add --toolchain nightly wasm32-unknown-unknown +rustup component add --toolchain nightly rust-src +``` + +### Install `wasm-opt` + +To install `wasm-opt`, install [`binaryen`]. Depending on your operating system there may be different ways to install it. + +[`binaryen`]: https://github.com/WebAssembly/binaryen + + + + +```sh +brew install binaryen +``` + + + + +For distributions that use `apt`: + +```sh +sudo apt install binaryen +``` + +For other distributions see: +https://github.com/WebAssembly/binaryen/releases + + + + +For install options see: https://github.com/WebAssembly/binaryen/releases + + + + +### Build with `nightly` and `wasm-opt` + +Build your contract using nightly. The additional options instruct the compiler to remove unnecessary information from the contract. + +```sh +cargo +nightly build \ + --target wasm32-unknown-unknown \ + --release \ + -Z build-std=std,panic_abort \ + -Z build-std-features=panic_immediate_abort +``` + +Use `wasm-opt` to further minimize the size of the `.wasm`. + +```sh +wasm-opt -Oz \ + target/wasm32-unknown-unknown/release/first_project.wasm \ + -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm +``` diff --git a/docs/getting-started/quick-start.mdx b/docs/getting-started/quick-start.mdx deleted file mode 100644 index 2f3fe9cea..000000000 --- a/docs/getting-started/quick-start.mdx +++ /dev/null @@ -1,183 +0,0 @@ ---- -sidebar_position: 3 -title: Quick Start ---- - -Once you've [Setup] your development environment, you're ready to create your -first Soroban contract. - -[Setup]: setup.mdx - -## Create New Project - -Start by creating a new Rust library using the `cargo new` command. - -```sh -cargo new --lib first-project -``` - -Open the `Cargo.toml`, it should look something like this: - -```toml title="Cargo.toml" -[package] -name = "first-project" -version = "0.1.0" -edition = "2021" -``` - -## Add `soroban-sdk` Dependency - -Add the following sections to the `Cargo.toml` that will import the `soroban-sdk`. - -:::info - -Report issues and share feedback about the `soroban-sdk` -[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). - -::: - -```toml -[lib] -crate-type = ["cdylib"] - -[features] -testutils = ["soroban-sdk/testutils"] - -[dependencies] -soroban-sdk = "0.4.2" - -[dev_dependencies] -soroban-sdk = { version = "0.4.2", features = ["testutils"] } - -[profile.release] -opt-level = "z" -overflow-checks = true -debug = 0 -strip = "symbols" -debug-assertions = false -panic = "abort" -codegen-units = 1 -lto = true - -[profile.release-with-logs] -inherits = "release" -debug-assertions = true -``` - -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info - -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write [Rust integration -tests], or write tests from another crate, you'll need to add `#[cfg(feature = -"testutils")]` to those tests and enable the `testutils` feature when running -your tests with `cargo test --features testutils` to be able to use those test -utilities. - -::: - -The config for the `release` profile configures the Rust toolchain to produce -smaller contracts when built with the `--release` or `--profile release` option. - -The config for the `release-with-logs` profile enables contract logs when -building with `--profile release-with-logs` option. See the [logging example] -for more details. - -[logging example]: ../examples/logging - -## Write the Code - -Open the `src/lib.rs` file, and copy-paste the following code. - -```rust -#![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; - -pub struct Contract; - -#[contractimpl] -impl Contract { - pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] - } -} - -#[cfg(test)] -mod test { - use super::{Contract, ContractClient}; - use soroban_sdk::{symbol, vec, Env}; - - #[test] - fn test() { - let env = Env::default(); - let contract_id = env.register_contract(None, Contract); - let client = ContractClient::new(&env, &contract_id); - - let words = client.hello(&symbol!("Dev")); - assert_eq!( - words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] - ); - } -} -``` - -## Run the Tests - -Run `cargo test` and watch the contract run. You should see the following output: - -```sh -cargo test -``` - -``` -running 1 test -test test::test ... ok -``` - -Try changing the values in the test to see how it works. - -## Build the Contract - -To build the contract into a `.wasm` file, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -A `.wasm` file should be outputted in the `target` directory: - -``` -target/wasm32-unknown-unknown/release/first_project.wasm -``` - -:::info - -Hyphens in Rust crate names are replaced by underscores in code and generated file names, so `first-project` is outputted as `first_project.wasm`. - -::: - -## Run the Contract - -If you have [`soroban-cli`] installed, you can invoke contract functions in the -contract. - -```sh -soroban invoke \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm \ - --id 1 \ - --fn hello \ - --arg friend -``` - -You should see the following output: - -```json -["Hello", "friend"] -``` - -[`soroban-cli`]: setup#install-the-soroban-cli -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx new file mode 100644 index 000000000..6a38e9365 --- /dev/null +++ b/docs/getting-started/storing-data.mdx @@ -0,0 +1,207 @@ +--- +sidebar_position: 4 +title: 2. Storing Data +--- + +The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.4.2 + +[increment example]: https://github.com/stellar/soroban-examples/tree/v0.4.2/increment + +## Run the Example + +First go through the [Setup] process to get your development environment configured, then clone the `v0.4.2` tag of `soroban-examples` repository: + +[Setup]: setup.mdx + +``` +git clone -b v0.4.2 https://github.com/stellar/soroban-examples +``` + +Or, skip the development environment setup and open this example in [Gitpod][oigp]. + +To run the tests for the example, navigate to the `increment` directory, and use `cargo test`. + +``` +cd increment +cargo test -- --nocapture +``` + +You should see the output: + +``` +running 1 test +count: U32(0) +count: U32(1) +count: U32(2) +test test::test ... ok +``` + +## Code + +```rust title="increment/src/lib.rs" +const COUNTER: Symbol = symbol!("COUNTER"); + +pub struct IncrementContract; + +#[contractimpl] +impl IncrementContract { + pub fn increment(env: Env) -> u32 { + let mut count: u32 = env + .storage() + .get(COUNTER) + .unwrap_or(Ok(0)) // If no value set, assume 0. + .unwrap(); // Panic if the value of COUNTER is not u32. + log!(&env, "count: {}", count); + count += 1; + env.storage().set(COUNTER, count); + count + } +} +``` + +Ref: https://github.com/stellar/soroban-examples/tree/v0.4.2/increment + +## How it Works + +Open the `increment/src/lib.rs` file to follow along. + +### Contract Data Keys + +Contract data is associated with a key. The key is the value that can be used at a later time to lookup the value. + +`Symbol`s are a space and execution efficient value to use as static keys or names of things. They can also be used as short strings. When produced using `symbol!(...)` they are computed at compile time and stored in code as a 64-bit value. Their maximum character length is 10. + +```rust +const COUNTER: Symbol = symbol!("COUNTER"); +``` + +### Contract Data Access + +The `Env` `data()` function is used to retrieve access and update a counter. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data. + +The `get()` function gets the current value associated with the counter key. + +```rust +let mut count: u32 = env + .storage() + .get(COUNTER) + .unwrap_or(Ok(0)) // If no value set, assume 0. + .unwrap(); // Panic if the value of COUNTER is not u32. +``` + +If no value is currently stored, the value given to `unwrap_or(...)` is returned instead. + +Values stored as contract data and retrieved are transmitted from the environment and expanded into the type specified. In this case a `u32`. If the value can be expanded the type returned will be an `Ok(u32)`, otherwise the type returned will be an `Err(_)`. The final `unwrap()` in the above code snippet is assuming the value will always be a `u32`. If a developer caused it to be some other type a panic would occur at the unwrap. + +The `set()` function stores the new count value against the key, replacing the existing value. + +```rust +env.storage().set(COUNTER, count); +``` + +## Tests + +Open the `increment/src/test.rs` file to follow along. + +```rust title="increment/src/test.rs" +#[test] +fn test() { + let env = Env::default(); + let contract_id = env.register_contract(None, IncrementContract); + let client = IncrementContractClient::new(&env, &contract_id); + + assert_eq!(client.increment(), 1); + assert_eq!(client.increment(), 2); + assert_eq!(client.increment(), 3); +} +``` + +In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in. + +```rust +let env = Env::default(); +``` + +The contract is registered with the environment using the contract type. + +```rust +let contract_id = env.register_contract(None, IncrementContract); +``` + +All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `IncrementContract`, and the client is named `IncrementContractClient`. + +```rust +let client = IncrementContractClient::new(&env, &contract_id); +``` + +The values returned by functions can be asserted on: + +```rust +assert_eq!(client.increment(), 1); +``` + +## Build the Contract + +To build the contract, use the `cargo build` command. + +```sh +cargo build --target wasm32-unknown-unknown --release +``` + +A `.wasm` file should be outputted in the `../target` directory: + +``` +../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm +``` + +## Run the Contract + +If you have [`soroban-cli`] installed, you can invoke contract functions in the WASM using it. + +```sh +soroban invoke \ + --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ + --id 1 \ + --fn increment +``` + +The following output should occur using the code above. + +``` +1 +``` + +Rerun the invoke with the `--footprint` option to view the [footprint] of the invocation, which is the ledger entries that the contract will have read or written to. + +```sh +soroban invoke \ + --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ + --id 1 \ + --fn increment \ + --footprint +``` + +``` +Footprint: {"readOnly":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"static":"ledgerKeyContractCode"}}}],"readWrite":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"symbol":[67,79,85,78,84,69,82]}}}]} +``` + +:::info + +Soroban is a pre-release and at this time outputs footprints in an unstable JSON format. + +::: + +[footprint]: ../learn/persisting-data.mdx#footprints-and-parallel-contention + +Run it a few more times to watch the count change. + +Use the `soroban` to inspect what the counter is after a few runs. + +```sh +soroban read --id 1 --key COUNTER +``` + +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli diff --git a/docs/tutorials/_category_.json b/docs/tutorials/_category_.json deleted file mode 100644 index 74f2f1406..000000000 --- a/docs/tutorials/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "position": 30, - "label": "Tutorials", - "link": { - "type": "generated-index" - } -} diff --git a/docs/tutorials/build-optimized.mdx b/docs/tutorials/build-optimized.mdx deleted file mode 100644 index efb72fe33..000000000 --- a/docs/tutorials/build-optimized.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 11 -title: Optimizing Builds ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -Building optimized contracts to be as small as possible requires some additional -tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. - -:::tip - -Building optimized contracts is only necessary when deploying to a network with -fees or when analyzing and profiling a contract to get it as small as possible. -If you're just starting out writing a contract, these steps are not necessary. -See [Build] for details on how to build for development. - -::: - -[Build]: build.mdx - -### Install Rust `nightly` - -To install the nightly Rust toolchain use [`rustup`]. - -[`rustup`]: ../getting-started/setup#install-rust - -```sh -rustup install nightly -rustup target add --toolchain nightly wasm32-unknown-unknown -rustup component add --toolchain nightly rust-src -``` - -### Install `wasm-opt` - -To install `wasm-opt`, install [`binaryen`]. Depending on your operating system -there may be different ways to install it. - -[`binaryen`]: https://github.com/WebAssembly/binaryen - - - - -```sh -brew install binaryen -``` - - - - -For distributions that use `apt`: - -```sh -sudo apt install binaryen -``` - -For other distributions see: -https://github.com/WebAssembly/binaryen/releases - - - - -For install options see: -https://github.com/WebAssembly/binaryen/releases - - - - -### Build with `nightly` and `wasm-opt` - -Build your contract using nightly. The additional options instruct the compiler -to remove unnecessary information from the contract. - -```sh -cargo +nightly build \ - --target wasm32-unknown-unknown \ - --release \ - -Z build-std=std,panic_abort \ - -Z build-std-features=panic_immediate_abort -``` - -Use `wasm-opt` to further minimize the size of the `.wasm`. - -```sh -wasm-opt -Oz \ - target/wasm32-unknown-unknown/release/first_project.wasm \ - -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm -``` diff --git a/docs/tutorials/build.mdx b/docs/tutorials/build.mdx deleted file mode 100644 index b351bf251..000000000 --- a/docs/tutorials/build.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -sidebar_position: 6 -title: Build ---- - -To build a Soroban contract to deploy or run, use the `cargo build` command. - -```sh -cargo build --target wasm32-unknown-unknown --release -``` - -:::tip - -Use the `release` profile outlined in [Configure the Release Profile], otherwise -the contract will exceed Soroban's size limits. - -::: - -A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is -the built contract. - -``` -target/wasm32-unknown-unknown/release/[project-name].wasm -``` - -The `.wasm` file contains the logic of the contract, as well as the contract's -specification that can be imported into other contracts who wish to call it. -This is the only artifact needed to deploy the contract, share the interface -with others, or integration test against the contract. - -:::tip - -To further optimize builds to be as small as possible, see [Optimizing Builds]. - -::: - -[Configure the Release Profile]: create-a-project#configure-the-release-profile -[Optimizing Builds]: build-optimized diff --git a/docs/tutorials/create-a-project.mdx b/docs/tutorials/create-a-project.mdx deleted file mode 100644 index 2ba56f608..000000000 --- a/docs/tutorials/create-a-project.mdx +++ /dev/null @@ -1,151 +0,0 @@ ---- -sidebar_position: 1 -title: Create a Project ---- - -Once you've [Setup] your development environment, you're ready to create Soroban -contracts. Creating projects is done using the Rust tool, `cargo`. - -[Setup]: ../getting-started/setup.mdx - -Create a new Rust library using the `cargo new` command. - -```sh -cargo new --lib [project-name] -``` - -Open the `Cargo.toml`, it should look something like this: - -```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2021" -``` - -## Configure the Library Type - -Add the `crate-type` configuration, required for building contracts. - -```toml -[lib] -crate-type = ["cdylib"] -``` - -## Import `soroban-sdk` and Features - -Add the following sections to the `Cargo.toml` that will import the -`soroban-sdk`, and configure a set of features explained below. - -:::caution - -The `soroban-sdk` is in early development. Report issues -[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose). - -::: - -```toml -[dependencies] -soroban-sdk = "0.4.2" - -[dev_dependencies] -soroban-sdk = { version = "0.4.2", features = ["testutils"] } - -[features] -testutils = ["soroban-sdk/testutils"] -``` - -The `features` list includes a `testutils` feature, which will cause additional -test utilities to be generated for calling the contract in tests. - -:::info - -The `testutils` test utilities are automatically enabled inside [Rust unit -tests] inside the same crate as your contract. If you write tests from another -crate, you'll need to require the `testutils` feature for those tests and enable -the `testutils` feature when running your tests with `cargo test ---features testutils` to be able to use those test utilities. - -::: - -## Configure the `release` Profile - -Configuring the `release` profile to optimize the contract build is critical. -Soroban contracts have a maximum size of 256KB. Rust programs, even small ones, -without these configurations almost always exceed this size. - -Add the following to your `Cargo.toml` and use the `release` profile when -building. - -```toml -[profile.release] -opt-level = "z" -overflow-checks = true -debug = 0 -strip = "symbols" -debug-assertions = false -panic = "abort" -codegen-units = 1 -lto = true -``` - -## Configure the `release-with-logs` Profile - -Configuring a `release-with-logs` profile can be useful for if you need to build -a `.wasm` that has logs enabled for printing debug logs when using the -[`soroban-cli`]. Note that this is not necessary to access debug logs in tests -or to use a step-through-debugger. - -Add the following to your `Cargo.toml` and use the `release-with-logs` profile -when you need logs. - -```toml -[profile.release-with-logs] -inherits = "release" -debug-assertions = true -``` - -See the [logging example] for more information about how to log. - -[logging example]: ../examples/logging.mdx - -## Wrapping it Up - -The steps below should produce a `Cargo.toml` that looks like so. - -```toml title="Cargo.toml" -[package] -name = "project-name" -version = "0.1.0" -edition = "2022" - -[lib] -crate-type = ["cdylib"] - -[features] -testutils = ["soroban-sdk/testutils"] - -[dependencies] -soroban-sdk = "0.4.2" - -[dev_dependencies] -soroban-sdk = { version = "0.4.2", features = ["testutils"] } - -[profile.release] -opt-level = "z" -overflow-checks = true -debug = 0 -strip = "symbols" -debug-assertions = false -panic = "abort" -codegen-units = 1 -lto = true - -[profile.release-with-logs] -inherits = "release" -debug-assertions = true -``` - -[Rust unit tests]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration tests]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli diff --git a/docs/tutorials/invoking-contracts-with-transactions.mdx b/docs/tutorials/invoking-contracts-with-transactions.mdx deleted file mode 100644 index 2ac446627..000000000 --- a/docs/tutorials/invoking-contracts-with-transactions.mdx +++ /dev/null @@ -1,119 +0,0 @@ ---- -sidebar_position: 11 -title: Invoking and Creating Contracts with Stellar Transactions ---- - -Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the -user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. - -The `InvokeHostFunctionOp` can be used to perform the following Soroban -operations: - -- Invoke contract functions. -- Install WASM of the new contracts. -- Deploy new contracts using the installed WASM or built-in implementations ( - this currently includes only the [token contract](../built-in-contracts/stellar-asset-contract.mdx)). - -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli - -## InvokeHostFunctionOp - -The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found -[here](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L523-L539) - -```c++ -union HostFunction switch (HostFunctionType type) -{ -case HOST_FUNCTION_TYPE_INVOKE_CONTRACT: - SCVec invokeArgs; -case HOST_FUNCTION_TYPE_CREATE_CONTRACT: - CreateContractArgs createContractArgs; -case HOST_FUNCTION_TYPE_INSTALL_CONTRACT_CODE: - InstallContractCodeArgs installContractCodeArgs; -}; - -struct InvokeHostFunctionOp -{ - // The host function to invoke - HostFunction function; - // The footprint for this invocation - LedgerFootprint footprint; -}; -``` - -### Function - -The `function` in `InvokeHostFunctionOp` will be executed by the Soroban host -environment. The function arguments are passed as function-dependent XDR. The -options are: - -1. `HOST_FUNCTION_TYPE_INVOKE_CONTRACT` - - This will call the `call_n` host function, invoking a contract function. - - `invokeArgs` is expected to contain the contract id, contract function - name, and the parameters to the contract function being invoked. -2. `HOST_FUNCTION_TYPE_INSTALL_CONTRACT_CODE` - - This will install the contract WASM using the provided `code` blob: - ```c++ - struct InstallContractCodeArgs - { - opaque code; - }; - ``` -3. `HOST_FUNCTION_TYPE_CREATE_CONTRACT` - - This will create a contract instance in the network using the specified - `source` and build a 32-byte contract identifer based on `contractID` value. - ```c++ - struct CreateContractArgs - { - ContractID contractID; - SCContractCode source; - }; - ``` - - `source` can be either a reference to the hash of the installed WASM (to - be more precise, a SHA-256 hash of the `InstallContractCodeArgs` from the operation above) or just specify that a built-in contract has to be used: - ```c++ - union SCContractCode switch (SCContractCodeType type) - { - case SCCONTRACT_CODE_WASM_REF: - Hash wasm_id; - case SCCONTRACT_CODE_TOKEN: - void; - }; - ``` - -- `contractID` is defined as following: - ```c++ - union ContractID switch (ContractIDType type) - { - case CONTRACT_ID_FROM_SOURCE_ACCOUNT: - uint256 salt; - case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: - struct - { - uint256 key; - Signature signature; - uint256 salt; - } fromEd25519PublicKey; - case CONTRACT_ID_FROM_ASSET: - Asset asset; - }; - ``` -- The parameters of this value define which the hash preimage that is then hashed - with SHA-256 to get the ID of the created contract. -- `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created - using the Stellar source account and the provided salt. The contract ID - preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_SOURCE_ACCOUNT`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L643-L649). -- `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using - the Stellar asset. This is only suported when - `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist - when this is applied, however the issuer of the asset will be the initial - token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). -- `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be - created using a public ED25519 key. Since this operation is not tied to any - on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR - preimage. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ED25519`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L623-L629). - -### Footprint - -The footprint must contain the `LedgerKeys` that will be read and/or written. More -information about the footprint can be found in the advanced section of [interacting with contracts](../learn/interacting-with-contracts#storage-footprint-and-preflight). diff --git a/docs/tutorials/run-on-sandbox.mdx b/docs/tutorials/run-on-sandbox.mdx deleted file mode 100644 index 2cc3237cf..000000000 --- a/docs/tutorials/run-on-sandbox.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -sidebar_position: 7 -title: Run on Sandbox ---- - -If you have the [`soroban-cli`] installed, you can run contracts in a local -sandbox environment. - -The Soroban sandbox environment is the same Soroban environment that runs on -Stellar networks, but it runs without nodes, and without the other features you -find on a Stellar network. - -:::info - -It's also possible to run a contract on a fully featured local network. See -[Deploy to a Local Network] for more details. - -::: - -Using the code we wrote in [Write a Contract] and the resulting `.wasm` file -we built in [Build] run the following command to invoke the `hello` -function with a single argument `friend`. - -```sh -soroban invoke \ - --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ - --id 1 \ - --fn hello \ - --arg friend -``` - -The following output should appear. - -```json -["Hello", "friend"] -``` - -[Write a Contract]: write-a-contract -[Deploy to a Local Network]: deploy-to-local-network -[Build]: build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli diff --git a/docs/tutorials/testing.mdx b/docs/tutorials/testing.mdx deleted file mode 100644 index 248a458a5..000000000 --- a/docs/tutorials/testing.mdx +++ /dev/null @@ -1,112 +0,0 @@ ---- -sidebar_position: 5 -title: Testing ---- - -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; - -Writing tests for Soroban contracts involves writing Rust code using the test -facilities and toolchain that you'd use for testing any Rust code. - -Given a simple contract like the contract demonstrated in [Write a -Contract](write-a-contract.mdx), a simple test will look like this. - - - - -```rust -#![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; - -pub struct Contract; - -#[contractimpl] -impl Contract { - pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] - } -} - -#[cfg(test)] -mod test; -``` - - - - -```rust -#![cfg(test)] - -use super::{Contract, ContractClient}; -use soroban_sdk::{symbol, vec, Env}; - -#[test] -fn test() { - let env = Env::default(); - let contract_id = env.register_contract(None, Contract); - let client = ContractClient::new(&env, &contract_id); - - let words = client.hello(&symbol!("Dev")); - assert_eq!( - words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] - ); -} -``` - - - - -In any test the first thing that is always required is an `Env`, which is the -Soroban environment that the contract will run inside of. - -```rust -let env = Env::default(); -``` - -The contract is registered with the environment using the contract type. -Contracts can specify a fixed contract ID as the first argument, or provide -`None` and one will be generated. - -```rust -let contract_id = env.register_contract(None, Contract); -``` - -All public functions within an `impl` block that is annotated with the -`#[contractimpl]` attribute have a corresponding function generated in a -generated client type. The client type will be named the same as the contract -type with `Client` appended. For example, in our contract the contract type is -`Contract`, and the client is named `ContractClient`. - -```rust -let client = ContractClient::new(&env, &contract_id); -let words = client.hello(&symbol!("Dev")); -``` - -The values returned by functions can be asserted on: - -```rust -assert_eq!( - words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] -); -``` - -## Run the Tests - -Run `cargo test` and watch the contract run. You should see the following output: - -```sh -cargo test -``` - -``` -running 1 test -test test::test ... ok -``` - -Try changing the values in the test to see how it works. - -[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html -[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx deleted file mode 100644 index 2d377cd4c..000000000 --- a/docs/tutorials/write-a-contract.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -sidebar_position: 4 -title: Write a Contract ---- - -Once you have a project setup, like how we setup a project in [Create a Project], writing a contract involves writing Rust code in -the projects `lib.rs` file. - -```rust -#![no_std] -``` - -All contracts should begin with `#![no_std]` to ensure that the Rust standard -library is not included in the build. The Rust standard library is large and not -well suited to being deployed into small programs like those deployed to -blockchains. - -```rust -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; -``` - -The contract will need to import the types and macros that it needs from the -`soroban-sdk` crate. Take a look at [Create a Project] to see -how to setup a project. - -Many of the types available in typical Rust programs, such as `std::vec::Vec`, -are not available, as there is no allocator and no heap memory in Soroban -contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory -and native capabilities. - -```rust -pub struct Contract; - -#[contractimpl] -impl Contract { - pub fn hello(env: Env, to: Symbol) -> Vec { - todo!() - } -} -``` - -Contract functions live inside an `impl` for a struct. The `impl` block is -annotated with `#[contractimpl]`. Functions that are intended to be called -externally should be marked with `pub` visibility. The first argument can be -an `Env` argument to get a copy of the Soroban environment, which is necessary -for most things. - -Putting those pieces together a simple contract will look like this. - -```rust title="src/lib.rs" -#![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; - -pub struct Contract; - -#[contractimpl] -impl Contract { - pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] - } -} -``` - -[Create a Project]: create-a-project.mdx From f3735f94b1e74dba13ead4ec224a98327087d3c1 Mon Sep 17 00:00:00 2001 From: lmorgan824 <63170084+lmorgan824@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:13:35 +0000 Subject: [PATCH 117/248] Update setup.mdx (#279) I had one of my devs try the Windows install and when you look at the existing docs, it looks like installing the wasm target is just for macOS/Linux/Unix-like systems. Moving it below the Windows section and making it it's own section might help. --- docs/getting-started/setup.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 0e7ebf18d..3458f5989 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -21,15 +21,17 @@ command. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -And install the `wasm32-unknown-unknown` target. +If you use Windows, or need an alternative method of installing Rust, check out: +https://www.rust-lang.org/tools/install + +## Install the target + +Install the `wasm32-unknown-unknown` target. ```sh rustup target add wasm32-unknown-unknown ``` -If you use Windows, or need an alternative method of installing Rust, check out: -https://www.rust-lang.org/tools/install - ## Configure an Editor Many editors have support for Rust. Visit the following link to find out how to From 1c7507812c6f0ad8105aeb34155bc5c3edd0cfc1 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Thu, 9 Feb 2023 12:16:13 -0600 Subject: [PATCH 118/248] Including a hyphen in `how-to-guides` directory (#298) * Including a hyphen in `how-to-guides` directory This removes any spaces from generated URLs for the pages contained therein, and is a bit more consistent with the existing directory structure. Signed-off-by: Elliot Voris * Changing links `how-to guides` -> `how-to-guides` Signed-off-by: Elliot Voris --------- Signed-off-by: Elliot Voris --- docs/getting-started/hello-world.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 4720467b1..c7ee5eb3e 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -97,7 +97,7 @@ debug-assertions = true See the [logging example] for more information about how to log. -[logging example]: ../how-to guides/logging.mdx +[logging example]: ../how-to-guides/logging.mdx ### Wrapping it Up @@ -395,7 +395,7 @@ For distributions that use `apt`: sudo apt install binaryen ``` -For other distributions see: +For other distributions see: https://github.com/WebAssembly/binaryen/releases From 78b867d606612bec6bfc2e13dbdd4f4f49348cee Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:55:02 -0500 Subject: [PATCH 119/248] Update hello-world.mdx (#304) --- docs/getting-started/hello-world.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index c7ee5eb3e..27e76c12e 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -154,7 +154,7 @@ All contracts should begin with `#![no_std]` to ensure that the Rust standard li use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; ``` -The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project] to see how to setup a project. +The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project](#create-new-project) to see how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. From ab5d1e8161a1c75b238e49b2e7f1aeebdd355d38 Mon Sep 17 00:00:00 2001 From: tsachiherman <24438559+tsachiherman@users.noreply.github.com> Date: Wed, 15 Feb 2023 10:29:15 -0500 Subject: [PATCH 120/248] update setup instructions. --- docs/getting-started/setup.mdx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 3458f5989..814c24da7 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -56,7 +56,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.4.0 soroban-cli +cargo install --locked --version 0.6.0 soroban-cli ``` :::info @@ -76,7 +76,7 @@ soroban ``` ❯ soroban -soroban 0.4.0 +soroban 0.6.0 https://soroban.stellar.org USAGE: @@ -86,16 +86,11 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - optimize Optimize a WASM file - read Print the current value of a contract-data ledger entry + contract Tools for smart contract developers + config Read and update config serve Run a local webserver for web app development and testing - token Wrap, create, and manage token contracts - deploy Deploy a WASM file as a contract - install Install a WASM file to the ledger without creating a contract instance - gen Generate code client bindings for a contract - xdr Decode xdr + events Watch the network for contract events + lab Experiment with early features and expert tools version Print version information completion Print shell completion code for the specified shell ``` From f31a71fb15107b6b2b7cb29b1573df046ea553ca Mon Sep 17 00:00:00 2001 From: Dmytro Kozhevin Date: Wed, 15 Feb 2023 16:50:00 -0500 Subject: [PATCH 121/248] Merge dev docs to main (#316) * proposed auth-next support for simulateTransaction method * Add note about multiple results * auth is an array * Updated example docs for Auth Next. (#306) * Updated example docs for Auth Next. * Update token documentation for Auth Next (#307) * Update token doc to use auth next. * Add AUTH_REQUIRED section * Mention set_auth and link to classic docs * feat: update for upcoming CLI version * feat: CLI reference page * Update optimize contracts section (#310) * Update hello-world.mdx * Update hello-world.mdx * don't need to manually install wasm-opt via binaryen * remove the -Z flags * More Auth Next docs updates (#311) * Remove rust-auth.mdx * Update authorization docs and `Address` type info. * Added auth info to transactions doc. * Added a document about migrating to auth next. * Add some high-level docs for Auth Next preflight (#312) * Add some preflight information for Auth Next * Update docs/reference/command-line.mdx * Update docs/reference/releases.mdx * Update docs/reference/releases.mdx * Update simulateTransaction.mdx * Update examples to point to 0.6.0 * Update releases page to current state * Add change log for cli and rpc * Added a note on the breaking auth changes to the release notes. (#315) --------- Co-authored-by: Paul Bellamy Co-authored-by: Siddharth Suresh Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Co-authored-by: Willem Wyndham Co-authored-by: Tyler van der Hoeven Co-authored-by: Paul Bellamy --- .../deploy-to-a-local-network.mdx | 7 +- docs/getting-started/deploy-to-futurenet.mdx | 7 +- docs/getting-started/hello-world.mdx | 89 ++++--------------- docs/getting-started/setup.mdx | 18 ++-- docs/getting-started/storing-data.mdx | 16 ++-- 5 files changed, 42 insertions(+), 95 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index 8874260a2..b8b4ab64b 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -52,7 +52,7 @@ curl "http://localhost:8000/friendbot?addr=G..." Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. ```sh -soroban deploy \ +soroban contract deploy \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ @@ -74,13 +74,14 @@ cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh -soroban invoke \ +soroban contract invoke \ --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' \ --fn hello \ - --arg friend + -- \ + --to friend ``` The following output should appear. diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 4dce42719..ecb2979e0 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -49,7 +49,7 @@ curl "https://friendbot-futurenet.stellar.org/?addr=G..." Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. ```sh -soroban deploy \ +soroban contract deploy \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ @@ -71,13 +71,14 @@ cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. ```sh -soroban invoke \ +soroban contract invoke \ --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ --secret-key S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Test SDF Future Network ; October 2022' \ --fn hello \ - --arg friend + -- \ + --to friend ``` The following output should appear. diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 27e76c12e..faec9a5c5 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -328,14 +328,15 @@ It's also possible to run a contract on a fully featured local network. See [Dep ::: -Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] run the following command to invoke the `hello` function with a single argument `friend`. +Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build], run the following command to invoke the `hello` function. Here we're setting the `to` argument to `friend`: ```sh -soroban invoke \ +soroban contract invoke \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --id 1 \ --fn hello \ - --arg friend + -- \ + --to friend ``` The following output should appear. @@ -344,84 +345,32 @@ The following output should appear. ["Hello", "friend"] ``` -[Write a Contract]: #write-a-contract -[Deploy to a Local Network]: deploy-to-a-local-network -[Build]: #build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +:::info The `--` double-dash is required! -## Optimizing Builds +This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean) used by other commands like [cargo run](https://doc.rust-lang.org/cargo/commands/cargo-run.html). Everything after the `--`, sometimes called [slop](https://github.com/clap-rs/clap/issues/971), is passed to a child process. In this case, `soroban contract invoke` builds an _implicit CLI_ on-the-fly for the `hello` method in your contract. It can do this because Soroban SDK embeds your contract's schema / interface types right in the `.wasm` file that gets deployed on-chain. Try this, too: -Building optimized contracts to be as small as possible requires some additional tools, and requires installing the `nightly` Rust toolchain and `wasm-opt`. - -:::tip - -Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. See [Build] for details on how to build for development. + soroban contract invoke ... --fn hello -- --help ::: -[Build]: #build - -### Install Rust `nightly` - -To install the nightly Rust toolchain use [`rustup`]. - -[`rustup`]: ../getting-started/setup#install-rust - -```sh -rustup install nightly -rustup target add --toolchain nightly wasm32-unknown-unknown -rustup component add --toolchain nightly rust-src -``` - -### Install `wasm-opt` - -To install `wasm-opt`, install [`binaryen`]. Depending on your operating system there may be different ways to install it. - -[`binaryen`]: https://github.com/WebAssembly/binaryen - - - - -```sh -brew install binaryen -``` - - - +## Optimizing Builds -For distributions that use `apt`: +Use `soroban contract optimize` to further minimize the size of the `.wasm`. ```sh -sudo apt install binaryen +soroban contract optimize \ + --wasm target/wasm32-unknown-unknown/release/first_project.wasm ``` -For other distributions see: -https://github.com/WebAssembly/binaryen/releases - - - - -For install options see: https://github.com/WebAssembly/binaryen/releases - - - - -### Build with `nightly` and `wasm-opt` +This will optimize and output a new `first_project.optimized.wasm` file in the same location as the input `.wasm`. -Build your contract using nightly. The additional options instruct the compiler to remove unnecessary information from the contract. +:::tip -```sh -cargo +nightly build \ - --target wasm32-unknown-unknown \ - --release \ - -Z build-std=std,panic_abort \ - -Z build-std-features=panic_immediate_abort -``` +Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. See [Build] for details on how to build for development. -Use `wasm-opt` to further minimize the size of the `.wasm`. +::: -```sh -wasm-opt -Oz \ - target/wasm32-unknown-unknown/release/first_project.wasm \ - -o target/wasm32-unknown-unknown/release/first_project_optimized.wasm -``` +[Write a Contract]: #write-a-contract +[Deploy to a Local Network]: deploy-to-a-local-network +[Build]: #build +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli \ No newline at end of file diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 3458f5989..b9a6988b9 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -56,7 +56,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.4.0 soroban-cli +cargo install --locked --version 0.5.0 soroban-cli ``` :::info @@ -76,7 +76,8 @@ soroban ``` ❯ soroban -soroban 0.4.0 +soroban +soroban 0.5.0 https://soroban.stellar.org USAGE: @@ -86,16 +87,11 @@ OPTIONS: -h, --help Print help information SUBCOMMANDS: - invoke Invoke a contract function in a WASM file - inspect Inspect a WASM file listing contract functions, meta, etc - optimize Optimize a WASM file - read Print the current value of a contract-data ledger entry + contract Tools for smart contract developers + config Read and update config serve Run a local webserver for web app development and testing - token Wrap, create, and manage token contracts - deploy Deploy a WASM file as a contract - install Install a WASM file to the ledger without creating a contract instance - gen Generate code client bindings for a contract - xdr Decode xdr + events Watch the network for contract events + lab Experiment with early features and expert tools version Print version information completion Print shell completion code for the specified shell ``` diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 6a38e9365..d374f1856 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -6,18 +6,18 @@ title: 2. Storing Data The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.4.2 +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.6.0 -[increment example]: https://github.com/stellar/soroban-examples/tree/v0.4.2/increment +[increment example]: https://github.com/stellar/soroban-examples/tree/v0.6.0/increment ## Run the Example -First go through the [Setup] process to get your development environment configured, then clone the `v0.4.2` tag of `soroban-examples` repository: +First go through the [Setup] process to get your development environment configured, then clone the `v0.6.0` tag of `soroban-examples` repository: [Setup]: setup.mdx ``` -git clone -b v0.4.2 https://github.com/stellar/soroban-examples +git clone -b v0.6.0 https://github.com/stellar/soroban-examples ``` Or, skip the development environment setup and open this example in [Gitpod][oigp]. @@ -62,7 +62,7 @@ impl IncrementContract { } ``` -Ref: https://github.com/stellar/soroban-examples/tree/v0.4.2/increment +Ref: https://github.com/stellar/soroban-examples/tree/v0.6.0/increment ## How it Works @@ -162,7 +162,7 @@ A `.wasm` file should be outputted in the `../target` directory: If you have [`soroban-cli`] installed, you can invoke contract functions in the WASM using it. ```sh -soroban invoke \ +soroban contract invoke \ --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ --fn increment @@ -177,7 +177,7 @@ The following output should occur using the code above. Rerun the invoke with the `--footprint` option to view the [footprint] of the invocation, which is the ledger entries that the contract will have read or written to. ```sh -soroban invoke \ +soroban contract invoke \ --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ --fn increment \ @@ -201,7 +201,7 @@ Run it a few more times to watch the count change. Use the `soroban` to inspect what the counter is after a few runs. ```sh -soroban read --id 1 --key COUNTER +soroban contract read --id 1 --key COUNTER ``` [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 55d277781805618cd464fbeb0c9f32c9c4e89e0f Mon Sep 17 00:00:00 2001 From: Arthur Ming Date: Wed, 22 Feb 2023 05:41:18 +0800 Subject: [PATCH 122/248] Use soroban-sdk the lasted version `0.6.0` in hello world example (#326) --- docs/getting-started/hello-world.mdx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index faec9a5c5..d5ac18255 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -48,10 +48,10 @@ The `soroban-sdk` is in early development. Report issues [here](https://github.c ```toml [dependencies] -soroban-sdk = "0.4.2" +soroban-sdk = "0.6.0" [dev_dependencies] -soroban-sdk = { version = "0.4.2", features = ["testutils"] } +soroban-sdk = { version = "0.6.0", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -116,10 +116,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.4.2" +soroban-sdk = "0.6.0" [dev_dependencies] -soroban-sdk = { version = "0.4.2", features = ["testutils"] } +soroban-sdk = { version = "0.6.0", features = ["testutils"] } [profile.release] opt-level = "z" @@ -373,4 +373,4 @@ Building optimized contracts is only necessary when deploying to a network with [Write a Contract]: #write-a-contract [Deploy to a Local Network]: deploy-to-a-local-network [Build]: #build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli \ No newline at end of file +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 064364ce3b6e41aeba2c19d246dcd1189077292a Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:03:51 -0400 Subject: [PATCH 123/248] Combine Hello World sections (#345) --- docs/getting-started/hello-world.mdx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index d5ac18255..0d24b0f2b 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -156,7 +156,9 @@ use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project](#create-new-project) to see how to setup a project. -Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. +Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory and native capabilities. Primitive values like `u128`, `i128`, `u64`, `i64`, `u32`, `i32`, and `bool` can also be used. Floats and floating point math are not supported. + +Contract inputs must not be references. ```rust pub struct Contract; @@ -169,7 +171,7 @@ impl Contract { } ``` -Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Contract functions must be given names that are no more than 10 characters long. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. Putting those pieces together a simple contract will look like this. @@ -353,6 +355,15 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w ::: +## Hello World Example + +The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.6.0 + +[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.6.0/hello_world + ## Optimizing Builds Use `soroban contract optimize` to further minimize the size of the `.wasm`. From 4ba8f1dc52cc9d231e0940b3c9e1e525cea1213f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 23 Mar 2023 11:18:16 -0500 Subject: [PATCH 124/248] Clean up page descriptions in category indexes (#348) * Add descriptions to docs that appear in generated category indexes. * Add category indexes and descriptions for SDKs and interfaces * Clean up descriptions of API documents. * compile -> create * remove apostrophe * added oxford comma * capitalization * added oxford comma --------- Co-authored-by: Bri <92327786+briwylde08@users.noreply.github.com> --- docs/getting-started/connect-freighter-wallet.mdx | 1 + docs/getting-started/deploy-to-a-local-network.mdx | 1 + docs/getting-started/deploy-to-futurenet.mdx | 1 + docs/getting-started/hello-world.mdx | 1 + docs/getting-started/setup.mdx | 1 + docs/getting-started/storing-data.mdx | 1 + 6 files changed, 6 insertions(+) diff --git a/docs/getting-started/connect-freighter-wallet.mdx b/docs/getting-started/connect-freighter-wallet.mdx index a0e29e632..1fe60db42 100644 --- a/docs/getting-started/connect-freighter-wallet.mdx +++ b/docs/getting-started/connect-freighter-wallet.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 6 title: 4. Connect Freighter Wallet +description: Freighter is a browser extension that can sign Soroban transactions. --- ## Signing Transactions with Freighter diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index b8b4ab64b..9b369ed52 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 5 title: 3. Deploy to a Local Network +description: Use Docker and the Stellar Quickstart image to run a local network. --- If you have Docker installed, you can run a local standalone network with the [Stellar Quickstart] Docker image. diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index ecb2979e0..524733ff7 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 7 title: 5. Deploy to Futurenet +description: Use Docker and the Stellar Quickstart image to deploy to the live test network. --- If you have Docker installed, you can run a local node with the [Stellar Quickstart] Docker image that joins the [Futurenet] network, and then use that local node to deploy. diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 0d24b0f2b..744829d95 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 3 title: 1. Hello World +description: Create your first Soroban contract. --- import Tabs from "@theme/Tabs"; diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 814c24da7..d27d47e45 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 1 title: Setup +description: Install and configure Rust and the Soroban CLI. --- Soroban contracts are small programs written in the [Rust] programming language. diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index d374f1856..e12f7ec2d 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -1,6 +1,7 @@ --- sidebar_position: 4 title: 2. Storing Data +description: Write a simple Soroban contract that stores and retrieves data. --- The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. From 50e281a8733581d9d1b2f41d7a66f3b69b5fd090 Mon Sep 17 00:00:00 2001 From: Dmytro Kozhevin Date: Thu, 23 Mar 2023 12:48:02 -0400 Subject: [PATCH 125/248] Update symbol functions and some related docs. --- docs/getting-started/hello-world.mdx | 12 ++++++------ docs/getting-started/storing-data.mdx | 14 ++++++++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 744829d95..222d41ba9 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -185,7 +185,7 @@ pub struct Contract; #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + vec![&env, Symbol::short("Hello"), to] } } ``` @@ -208,7 +208,7 @@ pub struct Contract; #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, symbol!("Hello"), to] + vec![&env, Symbol::short("Hello"), to] } } @@ -231,10 +231,10 @@ fn test() { let contract_id = env.register_contract(None, Contract); let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&symbol!("Dev")); + let words = client.hello(&Symbol::short("Dev")); assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::short("Hello"), Symbol::short("Dev"),] ); } ``` @@ -258,7 +258,7 @@ All public functions within an `impl` block that is annotated with the `#[contra ```rust let client = ContractClient::new(&env, &contract_id); -let words = client.hello(&symbol!("Dev")); +let words = client.hello(&Symbol::short("Dev")); ``` The values returned by functions can be asserted on: @@ -266,7 +266,7 @@ The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, symbol!("Hello"), symbol!("Dev"),] + vec![&env, Symbol::short("Hello"), Symbol::short("Dev"),] ); ``` diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index e12f7ec2d..3b663b175 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -43,7 +43,7 @@ test test::test ... ok ## Code ```rust title="increment/src/lib.rs" -const COUNTER: Symbol = symbol!("COUNTER"); +const COUNTER: Symbol = Symbol::short("COUNTER"); pub struct IncrementContract; @@ -71,12 +71,18 @@ Open the `increment/src/lib.rs` file to follow along. ### Contract Data Keys -Contract data is associated with a key. The key is the value that can be used at a later time to lookup the value. +Contract data is associated with a key. The key is the value that can be used at +a later time to lookup the value. -`Symbol`s are a space and execution efficient value to use as static keys or names of things. They can also be used as short strings. When produced using `symbol!(...)` they are computed at compile time and stored in code as a 64-bit value. Their maximum character length is 10. +`Symbol` is a short (up to 32 characters long) string type with limited +character space (only `a-zA-z0-9_` characters are allowed). Identifiers like +contract function names are represented by `Symbol`s. + +Short `Symbol`s up to 9 characters long can be pre-computed at compile time using +`Symbol::short`. ```rust -const COUNTER: Symbol = symbol!("COUNTER"); +const COUNTER: Symbol = Symbol::short("COUNTER"); ``` ### Contract Data Access From f2458c136fc2b6ad939bd9e1d5000cca6e2c2af4 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Mon, 3 Apr 2023 15:35:12 -0700 Subject: [PATCH 126/248] bump examples to 0.7.0 --- docs/getting-started/hello-world.mdx | 4 ++-- docs/getting-started/storing-data.mdx | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 222d41ba9..35f8803ce 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -361,9 +361,9 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.6.0 +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 -[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.6.0/hello_world +[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/hello_world ## Optimizing Builds diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 3b663b175..413b39728 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -7,18 +7,18 @@ description: Write a simple Soroban contract that stores and retrieves data. The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.6.0 +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 -[increment example]: https://github.com/stellar/soroban-examples/tree/v0.6.0/increment +[increment example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/increment ## Run the Example -First go through the [Setup] process to get your development environment configured, then clone the `v0.6.0` tag of `soroban-examples` repository: +First go through the [Setup] process to get your development environment configured, then clone the `v0.7.0` tag of `soroban-examples` repository: [Setup]: setup.mdx ``` -git clone -b v0.6.0 https://github.com/stellar/soroban-examples +git clone -b v0.7.0 https://github.com/stellar/soroban-examples ``` Or, skip the development environment setup and open this example in [Gitpod][oigp]. @@ -63,7 +63,7 @@ impl IncrementContract { } ``` -Ref: https://github.com/stellar/soroban-examples/tree/v0.6.0/increment +Ref: https://github.com/stellar/soroban-examples/tree/v0.7.0/increment ## How it Works From 0c440400c525424dd364255462bfbee1ce3164cf Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Wed, 5 Apr 2023 17:49:32 -0400 Subject: [PATCH 127/248] Update setup with 0.7.0 (#364) --- docs/getting-started/setup.mdx | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d27d47e45..689753a37 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -57,7 +57,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.6.0 soroban-cli +cargo install --locked --version 0.7.0 soroban-cli ``` :::info @@ -77,23 +77,24 @@ soroban ``` ❯ soroban -soroban 0.6.0 -https://soroban.stellar.org - -USAGE: - soroban - -OPTIONS: - -h, --help Print help information - -SUBCOMMANDS: - contract Tools for smart contract developers - config Read and update config - serve Run a local webserver for web app development and testing - events Watch the network for contract events - lab Experiment with early features and expert tools - version Print version information - completion Print shell completion code for the specified shell +Build, deploy, & interact with contracts; set identities to sign with; configure networks; generate keys; and more. + +Intro: https://soroban.stellar.org +CLI Reference: https://github.com/stellar/soroban-tools/tree/main/docs/soroban-cli-full-docs.md + +Usage: soroban + +Commands: + contract Tools for smart contract developers + config Read and update config + events Watch the network for contract events + lab Experiment with early features and expert tools + version Print version information + completion Print shell completion code for the specified shell + +Options: + -h, --help Print help (see more with '--help') + -V, --version Print version ``` [Rust]: https://www.rust-lang.org/ From c88cb41b1965c209ec5452af44d25ad5bb76fa8d Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 5 Apr 2023 14:50:49 -0700 Subject: [PATCH 128/248] Pin docker images to release version (#365) --- docs/getting-started/deploy-to-a-local-network.mdx | 2 +- docs/getting-started/deploy-to-futurenet.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index 9b369ed52..bd6be2782 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -25,7 +25,7 @@ To run a local standalone network with the Stellar Quickstart Docker image, run docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ --standalone \ --enable-soroban-rpc ``` diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 524733ff7..b8c6635dd 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -20,7 +20,7 @@ To run a local node for the [Futurenet] network with the Stellar Quickstart Dock docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev \ + stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ --futurenet \ --enable-soroban-rpc ``` From eb38b99b40a7d24489c9e923c6a8c7cfe265104a Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 7 Apr 2023 16:06:10 +0100 Subject: [PATCH 129/248] Update the cli docs for preview 8 release (#371) --- docs/getting-started/deploy-to-a-local-network.mdx | 6 +++--- docs/getting-started/deploy-to-futurenet.mdx | 6 +++--- docs/getting-started/hello-world.mdx | 12 ++++++------ docs/getting-started/storing-data.mdx | 8 +++++--- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index bd6be2782..e13bb6d27 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -55,7 +55,7 @@ Once you have an account on the network, we'll use the code we wrote in [Write a ```sh soroban contract deploy \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ - --secret-key S... \ + --source S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' ``` @@ -77,11 +77,11 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the ```sh soroban contract invoke \ --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ - --secret-key S... \ + --source S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Standalone Network ; February 2017' \ - --fn hello \ -- \ + hello \ --to friend ``` diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index b8c6635dd..f0448a394 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -52,7 +52,7 @@ Once you have an account on the network, we'll use the code we wrote in [Write a ```sh soroban contract deploy \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ - --secret-key S... \ + --source S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Test SDF Future Network ; October 2022' ``` @@ -74,11 +74,11 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the ```sh soroban contract invoke \ --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ - --secret-key S... \ + --source S... \ --rpc-url http://localhost:8000/soroban/rpc \ --network-passphrase 'Test SDF Future Network ; October 2022' \ - --fn hello \ -- \ + hello \ --to friend ``` diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 35f8803ce..5a41872b6 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -49,10 +49,10 @@ The `soroban-sdk` is in early development. Report issues [here](https://github.c ```toml [dependencies] -soroban-sdk = "0.6.0" +soroban-sdk = "0.7.0" [dev_dependencies] -soroban-sdk = { version = "0.6.0", features = ["testutils"] } +soroban-sdk = { version = "0.7.0", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.6.0" +soroban-sdk = "0.7.0" [dev_dependencies] -soroban-sdk = { version = "0.6.0", features = ["testutils"] } +soroban-sdk = { version = "0.7.0", features = ["testutils"] } [profile.release] opt-level = "z" @@ -337,8 +337,8 @@ Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we soroban contract invoke \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --id 1 \ - --fn hello \ -- \ + hello \ --to friend ``` @@ -352,7 +352,7 @@ The following output should appear. This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean) used by other commands like [cargo run](https://doc.rust-lang.org/cargo/commands/cargo-run.html). Everything after the `--`, sometimes called [slop](https://github.com/clap-rs/clap/issues/971), is passed to a child process. In this case, `soroban contract invoke` builds an _implicit CLI_ on-the-fly for the `hello` method in your contract. It can do this because Soroban SDK embeds your contract's schema / interface types right in the `.wasm` file that gets deployed on-chain. Try this, too: - soroban contract invoke ... --fn hello -- --help + soroban contract invoke ... -- hello --help ::: diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 413b39728..760a0c6a4 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -172,7 +172,8 @@ If you have [`soroban-cli`] installed, you can invoke contract functions in the soroban contract invoke \ --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ - --fn increment + -- \ + increment ``` The following output should occur using the code above. @@ -187,8 +188,9 @@ Rerun the invoke with the `--footprint` option to view the [footprint] of the in soroban contract invoke \ --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ - --fn increment \ - --footprint + --footprint \ + -- \ + increment ``` ``` From 64b43ae3dd0d291b8b7d128f869d26adcc5eb667 Mon Sep 17 00:00:00 2001 From: tomerweller Date: Fri, 7 Apr 2023 13:52:57 -0700 Subject: [PATCH 130/248] Update deploy-to-futurenet to use public rpc (#372) --- docs/getting-started/deploy-to-futurenet.mdx | 37 +++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index f0448a394..2872c7af4 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -14,25 +14,6 @@ It's also possible to run a contract in the local sandbox environment without a ::: -To run a local node for the [Futurenet] network with the Stellar Quickstart Docker image, run the following command. - -```sh -docker run --rm -it \ - -p 8000:8000 \ - --name stellar \ - stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ - --futurenet \ - --enable-soroban-rpc -``` - -Once the image is started you can check its status by querying the Horizon API: - -```sh -curl http://localhost:8000 -``` - -It takes sometime to join a remote network. Monitor the output of that endpoint until you see the `core_latest_ledger` become a number above zero. - Generate a key by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. :::tip @@ -53,10 +34,26 @@ Once you have an account on the network, we'll use the code we wrote in [Write a soroban contract deploy \ --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ --source S... \ - --rpc-url http://localhost:8000/soroban/rpc \ + --rpc-url https://rpc-futurenet.stellar.org:443 \ --network-passphrase 'Test SDF Future Network ; October 2022' ``` +:::caution + +The above command uses a futurenet soroban-rpc instance maintained by the Stellar Development Foundation. When interacting with the network in production you should run your own soroban-rpc or use a third party infrastructure provider. + +To run your own soroban-rpc locally, use the following command, and rpc-url `http://localhost:8000/soroban/rpc`: +``` +docker run --rm -it \ + -p 8000:8000 \ + --name stellar \ + stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ + --futurenet \ + --enable-soroban-rpc +``` + +::: + :::tip It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. From 588a29cdd2f6e94a31df5be3e19b9b69e68c0e60 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:39:42 -0700 Subject: [PATCH 131/248] Create Run an RPC Adding a new page for the RPC --- docs/getting-started/Run an RPC | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 docs/getting-started/Run an RPC diff --git a/docs/getting-started/Run an RPC b/docs/getting-started/Run an RPC new file mode 100644 index 000000000..dc7efabb5 --- /dev/null +++ b/docs/getting-started/Run an RPC @@ -0,0 +1,17 @@ +--- +sidebar_position: 8 +title: 6. Soroban RPC +description: Run an RPC Service +--- + +The RPC service allows you to communicate directly with the Soroban runtime via a JSON RPC interface. + +For example, you can build an application and have it directly send a transaction, get contract and event data or simulate transactions. + +Details on all available methods are [here](https://soroban.stellar.org/api/methods). + +## Run your own instance +You can download and run a local instance via Docker and run a standalone network or set the network to Futurenet (and soon to come, Testnet and Mainnet). + +## RPC Providers +Connect with several of our hosted instances already available for the community listed here. From 2c47ec9bbd8ebcc8745c0356705fa3ec75d4f938 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:41:45 -0700 Subject: [PATCH 132/248] Rename Run an RPC to run-rpc --- docs/getting-started/{Run an RPC => run-rpc} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/getting-started/{Run an RPC => run-rpc} (100%) diff --git a/docs/getting-started/Run an RPC b/docs/getting-started/run-rpc similarity index 100% rename from docs/getting-started/Run an RPC rename to docs/getting-started/run-rpc From 8c9f4d1f086395fe9a8edd0cec6ba4771f39d53f Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:44:14 -0700 Subject: [PATCH 133/248] Rename run-rpc to run-rpc.mdx --- docs/getting-started/{run-rpc => run-rpc.mdx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/getting-started/{run-rpc => run-rpc.mdx} (100%) diff --git a/docs/getting-started/run-rpc b/docs/getting-started/run-rpc.mdx similarity index 100% rename from docs/getting-started/run-rpc rename to docs/getting-started/run-rpc.mdx From a52abffa685799b1af039f0de505d08c668fd391 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:52:26 -0700 Subject: [PATCH 134/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index dc7efabb5..46a58da76 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -4,14 +4,16 @@ title: 6. Soroban RPC description: Run an RPC Service --- -The RPC service allows you to communicate directly with the Soroban runtime via a JSON RPC interface. +The RPC service allows you to communicate directly with the Soroban via a JSON RPC interface. For example, you can build an application and have it directly send a transaction, get contract and event data or simulate transactions. Details on all available methods are [here](https://soroban.stellar.org/api/methods). ## Run your own instance -You can download and run a local instance via Docker and run a standalone network or set the network to Futurenet (and soon to come, Testnet and Mainnet). +You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone](https://github.com/stellar/quickstart#soroban-development) network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). + +[Futurenet]: deploy-to-futurenet.mdx ## RPC Providers Connect with several of our hosted instances already available for the community listed here. From 50f87db91c0d33aacc0a6baef65159a1313d2ff4 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:53:21 -0700 Subject: [PATCH 135/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 46a58da76..83441545e 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -4,7 +4,7 @@ title: 6. Soroban RPC description: Run an RPC Service --- -The RPC service allows you to communicate directly with the Soroban via a JSON RPC interface. +The RPC service allows you to communicate directly with the Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). For example, you can build an application and have it directly send a transaction, get contract and event data or simulate transactions. From c036b919429405ec09e4de61bba7b47bf6e9e521 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:58:12 -0700 Subject: [PATCH 136/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 83441545e..cd02386d8 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -11,9 +11,12 @@ For example, you can build an application and have it directly send a transactio Details on all available methods are [here](https://soroban.stellar.org/api/methods). ## Run your own instance -You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone](https://github.com/stellar/quickstart#soroban-development) network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). +You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). -[Futurenet]: deploy-to-futurenet.mdx +[standalone]: deploy-to-a-local-network.mdx +[Futurenet]: ../reference/futurenet.mdx ## RPC Providers -Connect with several of our hosted instances already available for the community listed here. +Connect to several of our [hosted instances] already available for the community. + +[hosted instances]: ../references/rpc-providers.mdx From 52158cff18de4bc3426c315e04b0034b0f7d0f2c Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 15:58:30 -0700 Subject: [PATCH 137/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index cd02386d8..e43732395 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -4,7 +4,7 @@ title: 6. Soroban RPC description: Run an RPC Service --- -The RPC service allows you to communicate directly with the Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). +The RPC service allows you to communicate directly with Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). For example, you can build an application and have it directly send a transaction, get contract and event data or simulate transactions. From 521b41dd9452878dbea68d7a306538dfd54bef34 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:07:38 -0700 Subject: [PATCH 138/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index e43732395..d04242072 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -6,7 +6,7 @@ description: Run an RPC Service The RPC service allows you to communicate directly with Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). -For example, you can build an application and have it directly send a transaction, get contract and event data or simulate transactions. +For example, you can build an application and have it directly [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). Details on all available methods are [here](https://soroban.stellar.org/api/methods). From 13a4a7b3b58b663efce742d7d316aa59aad41e30 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:18:00 -0700 Subject: [PATCH 139/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index d04242072..36f307bf1 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -8,7 +8,7 @@ The RPC service allows you to communicate directly with Soroban via a [JSON RPC For example, you can build an application and have it directly [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). -Details on all available methods are [here](https://soroban.stellar.org/api/methods). +Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [Soroban JS SDK](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. ## Run your own instance You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). From ca7065a9e0f295704a2e8a163ad76d8d08238b39 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:18:49 -0700 Subject: [PATCH 140/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 36f307bf1..ce59083a3 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -8,7 +8,7 @@ The RPC service allows you to communicate directly with Soroban via a [JSON RPC For example, you can build an application and have it directly [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). -Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [Soroban JS SDK](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. +Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. ## Run your own instance You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). From d888d80df6b1c29887aa74fda08fdb75669c8670 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:19:12 -0700 Subject: [PATCH 141/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index ce59083a3..1abc8c349 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -6,7 +6,7 @@ description: Run an RPC Service The RPC service allows you to communicate directly with Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). -For example, you can build an application and have it directly [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). +For example, you can build an application and have it [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. From f573e1f7cabf709ed016a068d3de427cc4fa175c Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:19:59 -0700 Subject: [PATCH 142/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 1abc8c349..28829852e 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -11,7 +11,7 @@ For example, you can build an application and have it [send a transaction](https Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. ## Run your own instance -You can download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). +Download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx From 171d40287b6f1b7dce019717bd7256f88a421b02 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:20:35 -0700 Subject: [PATCH 143/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 28829852e..548b78028 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -17,6 +17,6 @@ Download and run a local instance via [Docker Quickstart](https://github.com/ste [Futurenet]: ../reference/futurenet.mdx ## RPC Providers -Connect to several of our [hosted instances] already available for the community. +Connect to several of our [hosted instances] available for the community. [hosted instances]: ../references/rpc-providers.mdx From 008db85d48cd97ac57e8505261358e626b1c8f4e Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:22:36 -0700 Subject: [PATCH 144/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 548b78028..1f1370a95 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -1,7 +1,7 @@ --- sidebar_position: 8 title: 6. Soroban RPC -description: Run an RPC Service +description: Get an RPC Service --- The RPC service allows you to communicate directly with Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). From 56aa53437602ff8fe94dcf892c87805e9f121520 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:32:16 -0700 Subject: [PATCH 145/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 1f1370a95..83adfcbce 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -11,7 +11,7 @@ For example, you can build an application and have it [send a transaction](https Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. ## Run your own instance -Download and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). +[Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx From c9f357e9f63b88ac7a24d5cb62303a296b2c67d1 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:33:56 -0700 Subject: [PATCH 146/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 83adfcbce..8a883da6a 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -11,7 +11,7 @@ For example, you can build an application and have it [send a transaction](https Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. ## Run your own instance -[Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live network such as [Futurenet] (and soon to come, Testnet and Mainnet). +[Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx From 7c0288b76691b28a0fa73d05316286de1cfa12d6 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:41:27 -0700 Subject: [PATCH 147/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 8a883da6a..4cf8c04b7 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -13,6 +13,8 @@ Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stella ## Run your own instance [Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). +For local development, RPC service can run on a standard laptop with 16GB of RAM and has minimal storage and CPU requirements. + [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx From 994733a2ced1aa987411761ac80d493eb8c5b8b5 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:45:04 -0700 Subject: [PATCH 148/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 4cf8c04b7..f3da2ee28 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -19,6 +19,6 @@ For local development, RPC service can run on a standard laptop with 16GB of RAM [Futurenet]: ../reference/futurenet.mdx ## RPC Providers -Connect to several of our [hosted instances] available for the community. +Connect to available [hosted instances] for the community to use. [hosted instances]: ../references/rpc-providers.mdx From 6968715ba8e42e15dc15f97f1ed2837e99e955dd Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:45:47 -0700 Subject: [PATCH 149/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index f3da2ee28..5cf4d608b 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -13,7 +13,7 @@ Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stella ## Run your own instance [Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). -For local development, RPC service can run on a standard laptop with 16GB of RAM and has minimal storage and CPU requirements. +For local development, an RPC service can run on a standard laptop with 16GB of RAM and has minimal storage and CPU requirements. [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx From 7860f711820ce276667de78fe1062adb2219a9bb Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:46:29 -0700 Subject: [PATCH 150/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 5cf4d608b..de4783ad6 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -8,7 +8,7 @@ The RPC service allows you to communicate directly with Soroban via a [JSON RPC For example, you can build an application and have it [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). -Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will communicate with an RPC instance. +Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance. ## Run your own instance [Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). From 9ef899d53172dce7316f0ed48c925a40c4630421 Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:49:04 -0700 Subject: [PATCH 151/248] Update run-rpc.mdx --- docs/getting-started/run-rpc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index de4783ad6..40ddf8d07 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -8,7 +8,7 @@ The RPC service allows you to communicate directly with Soroban via a [JSON RPC For example, you can build an application and have it [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). -Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance. +Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance to access the network. ## Run your own instance [Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). From 1804cca00e254097c991ad0f5a9b3be8f3c83fb5 Mon Sep 17 00:00:00 2001 From: tomerweller Date: Tue, 11 Apr 2023 11:43:51 -0700 Subject: [PATCH 152/248] unbork docs (#377) --- docs/getting-started/run-rpc.mdx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 40ddf8d07..2039b06e6 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -17,8 +17,3 @@ For local development, an RPC service can run on a standard laptop with 16GB of [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx - -## RPC Providers -Connect to available [hosted instances] for the community to use. - -[hosted instances]: ../references/rpc-providers.mdx From ad85eef10e6e08eee1784d658f778228c57c23a2 Mon Sep 17 00:00:00 2001 From: anupsdf <127880479+anupsdf@users.noreply.github.com> Date: Wed, 12 Apr 2023 12:35:52 -0700 Subject: [PATCH 153/248] a Removed symbol from soroban-sdk imports (#380) --- docs/getting-started/hello-world.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 5a41872b6..0497d1ee5 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -152,7 +152,7 @@ Once you've created a project, writing a contract involves writing Rust code in All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project](#create-new-project) to see how to setup a project. @@ -178,7 +178,7 @@ Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; @@ -201,7 +201,7 @@ Given a simple contract like the contract demonstrated in the Write a Contract s ```rust #![no_std] -use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec}; +use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; pub struct Contract; @@ -223,7 +223,7 @@ mod test; #![cfg(test)] use super::{Contract, ContractClient}; -use soroban_sdk::{symbol, vec, Env}; +use soroban_sdk::{vec, Env}; #[test] fn test() { From 8cdb0fcf7a09318f69ae7bb23900d59df4b2d34c Mon Sep 17 00:00:00 2001 From: anupsdf <127880479+anupsdf@users.noreply.github.com> Date: Thu, 13 Apr 2023 09:47:57 -0700 Subject: [PATCH 154/248] Fix rpc-url for Futurenet deployment (#383) * a Removed symbol from soroban-sdk imports * Fix the rpc-url for Futurenet deployment --- docs/getting-started/deploy-to-futurenet.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 2872c7af4..5b4063328 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -72,7 +72,7 @@ Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the soroban contract invoke \ --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ --source S... \ - --rpc-url http://localhost:8000/soroban/rpc \ + --rpc-url https://rpc-futurenet.stellar.org:443 \ --network-passphrase 'Test SDF Future Network ; October 2022' \ -- \ hello \ From 36409f49ceab35e3d4a85eae162c67355e5f73e4 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Thu, 13 Apr 2023 19:14:11 -0600 Subject: [PATCH 155/248] Anup doc updates (#378) * Updates per Anup's instructions * 10 -> 32 characters * 10 -> 32 character limit * 10 -> 32 characters * A comes before B * Update docs/how-to-guides/cross-contract-call.mdx Co-authored-by: Elliot Voris * changed wording --------- Co-authored-by: Elliot Voris --- docs/getting-started/hello-world.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 0497d1ee5..f422e8a5b 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -172,7 +172,7 @@ impl Contract { } ``` -Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Contract functions must be given names that are no more than 10 characters long. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Contract functions must be given names that are no more than 32 characters long. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. Putting those pieces together a simple contract will look like this. From ba5fae29560d0626bca2c95c44ac6c621ae4906b Mon Sep 17 00:00:00 2001 From: jcx120 <91218921+jcx120@users.noreply.github.com> Date: Mon, 17 Apr 2023 09:52:33 -0700 Subject: [PATCH 156/248] Update run-rpc.mdx (#386) Added back section RPC providers list (w/ fixed typo for URL reference) --- docs/getting-started/run-rpc.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 2039b06e6..56c75a0d9 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -17,3 +17,8 @@ For local development, an RPC service can run on a standard laptop with 16GB of [standalone]: deploy-to-a-local-network.mdx [Futurenet]: ../reference/futurenet.mdx + +## RPC Providers +Connect to available [hosted instances] for the community to use. + +[hosted instances]: ../reference/rpc-providers.mdx From 790e713d6375f55b93d9408bee5724b7858607cf Mon Sep 17 00:00:00 2001 From: Piyal Basu Date: Tue, 18 Apr 2023 15:41:28 -0400 Subject: [PATCH 157/248] add Freighter instructions (#390) --- .../connect-freighter-wallet.mdx | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/connect-freighter-wallet.mdx b/docs/getting-started/connect-freighter-wallet.mdx index 1fe60db42..6ca70c1cd 100644 --- a/docs/getting-started/connect-freighter-wallet.mdx +++ b/docs/getting-started/connect-freighter-wallet.mdx @@ -4,16 +4,62 @@ title: 4. Connect Freighter Wallet description: Freighter is a browser extension that can sign Soroban transactions. --- -## Signing Transactions with Freighter +[Freighter](https://www.freighter.app/) is a browser extension wallet provided by the Stellar Development Foundation. It provides users a way to interact with Soroban tokens directly from your web browser. -If you're building a JS dapp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): +## Setup 1. Install the Freighter browser extension. 2. Create a keypair or import an existing account using a mnemonic phrase to complete setup. -3. Next, switch to Experimental Mode to enable the Soroban SDK. In the extension, click the gear in the lower right corner and then navigate to `Preferences`. Toggle on `Experimental Mode`. +3. Next, switch to `Experimental Mode` to enable the Soroban SDK. In the extension, click the gear in the lower right corner and then navigate to `Preferences`. Toggle on `Experimental Mode`. + +4. After switching to `Experimental Mode`, you should automatically be switched to the Futurenet network. Fund your account on Futurenet using Friendbot. For convenience, you can do so in the Stellar [Laboratory](https://laboratory.stellar.org/#account-creator?network=futurenet). + +## Enable Soroban Tokens + +With a funded Futurenet account and `Experimental Mode` enabled, you can now add Soroban tokens to your Freighter wallet. + +1. On the Freighter account screen, click this `Manage Assets` button at the bottom of the screen. + +2. You will now see a button to `Add Soroban token` at the bottom of the screen. Click this `Add Soroban token` button. + +3. On the next screen, enter the Token ID of the token you want to add to Freighter and click `Add New Token`. + +4. You will now see your token's balance on Freighter's account page. Clicking on the balance will show a history of payments sent using this token. + +## Send Token Payments + +Once you have added a Soroban token to your Freighter wallet, you can now send a payment of that token directly from Freighter. + +1. On the Freighter account screen, click the `Send Payment` icon in the upper right of the screen. + +2. Enter a recipient public key. Click `Continue`. + +3. Select your token from the asset dropdown at the bottom of the screen and enter a token amount. Click `Continue`. + +4. Enter a memo (optional). Click `Review Send`. + +5. Review the details of your payment. Click `Send`. + +## Sign Soroban XDR's + +With a funded Futurenet account and `Experimental Mode` enabled, you can now sign Soroban XDR's using dapps that are integrated with Freighter. An example of an integrated dapp is Stellar's [Laboratory](https://laboratory.stellar.org/#txsigner?network=futurenet). + +1. On the Lab's transaction signer, enter a Soroban XDR into the form field. + +2. Click `Sign with Freighter`. + +3. Freighter will open with the details of the XDR. Click `Approve` to sign or `Reject` to dismiss without a signature. + +4. If approved, Freighter will transmit a signed XDR back to the Lab. + +## As a dapp Provider, Prompt Freighter to Sign Transactions (Advanced) + +If you're building a JS dapp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): + +1. Follow the setup instructions above. -4. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dapp to sign Soroban XDR's using the account in Freighter. +2. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dapp to sign Soroban XDR's using the account in Freighter. -Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dapp. +3. Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dapp. From 1a5ad89a7627a308bd1bcdb2f8b9cb8048b3174d Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Mon, 24 Apr 2023 07:01:43 -0700 Subject: [PATCH 158/248] edition version (#393) --- docs/getting-started/hello-world.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index f422e8a5b..77393f3d0 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -108,7 +108,7 @@ The steps below should produce a `Cargo.toml` that looks like so. [package] name = "project-name" version = "0.1.0" -edition = "2022" +edition = "2021" [lib] crate-type = ["cdylib"] @@ -360,8 +360,7 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 [hello world example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/hello_world From 83ac2bb4ab673c322cc8b4d7facc9b56c5283ba1 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Fri, 5 May 2023 13:11:59 -0700 Subject: [PATCH 159/248] fixes malformed hello world link (#412) --- docs/getting-started/hello-world.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 77393f3d0..ec264ba29 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -360,8 +360,9 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 [hello world example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/hello_world ## Optimizing Builds From 67e309717973a0a1af359d7cc9ec99503ca11a4d Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Wed, 24 May 2023 10:16:23 -0700 Subject: [PATCH 160/248] Release preview 9 (#447) * update target directories (#405) * Add some basic documentation on fees & limits. (#417) * Add code and contract metadata (#418) * Update alloc crate for SDK v0.8.4 (#420) * Update atomic swap example for SDK v0.8.4 (#421) * Update atomic swap example for SDK v0.8.4 (#422) * Update auth example for SDK v0.8.4 (#423) * Add note about contract meta to build-your-own-sdk page (#424) * Add note about contract meta to build-your-own-sdk page * add link * Update cross-contract example for SDK v0.8.4 (#425) * Update custom account example for SDK v0.8.4 (#426) * Update custom types example for SDK v0.8.4 (#427) * Update deployer example for SDK v0.8.4 (#428) * Update errors example for SDK v0.8.4 (#429) * Update events example for SDK v0.8.4 (#430) * Update liqpool example for SDK v0.8.4 (#431) * Update logging example for SDK v0.8.4 (#432) * Update single-offer-sale example for SDK v0.8.4 (#433) * Update stellar asset contract page for SDK v0.8.4 (#434) * Update timelock example for SDK v0.8.4 (#435) * Update token example for SDK v0.8.4 (#436) * Update contractmeta! page for SDK v0.8.4 (#437) * Update getting started setup page for SDK v0.8.4 (#438) * update soroban-cli and example versions (#441) * update soroban-cli and example versions * update token contract interface link * update-release-page (#446) * update-release-page * add changelog * Add explaination to metering (#443) --------- Co-authored-by: Dmytro Kozhevin Co-authored-by: Siddharth Suresh Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Co-authored-by: Jay Geng --- docs/getting-started/hello-world.mdx | 14 +++++++------- docs/getting-started/setup.mdx | 2 +- docs/getting-started/storing-data.mdx | 18 +++++++++--------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index ec264ba29..2cdf44e3b 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -49,10 +49,10 @@ The `soroban-sdk` is in early development. Report issues [here](https://github.c ```toml [dependencies] -soroban-sdk = "0.7.0" +soroban-sdk = "0.8.4" [dev_dependencies] -soroban-sdk = { version = "0.7.0", features = ["testutils"] } +soroban-sdk = { version = "0.8.4", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.7.0" +soroban-sdk = "0.8.4" [dev_dependencies] -soroban-sdk = { version = "0.7.0", features = ["testutils"] } +soroban-sdk = { version = "0.8.4", features = ["testutils"] } [profile.release] opt-level = "z" @@ -361,9 +361,9 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] - -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 -[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/hello_world + +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.8.4 +[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.8.4/hello_world ## Optimizing Builds diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 689753a37..4ed9c7abf 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -57,7 +57,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.7.0 soroban-cli +cargo install --locked --version 0.8.0 soroban-cli ``` :::info diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 760a0c6a4..6c345e79d 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -7,18 +7,18 @@ description: Write a simple Soroban contract that stores and retrieves data. The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.7.0 +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.8.4 -[increment example]: https://github.com/stellar/soroban-examples/tree/v0.7.0/increment +[increment example]: https://github.com/stellar/soroban-examples/tree/v0.8.4/increment ## Run the Example -First go through the [Setup] process to get your development environment configured, then clone the `v0.7.0` tag of `soroban-examples` repository: +First go through the [Setup] process to get your development environment configured, then clone the `v0.8.4` tag of `soroban-examples` repository: [Setup]: setup.mdx ``` -git clone -b v0.7.0 https://github.com/stellar/soroban-examples +git clone -b v0.8.4 https://github.com/stellar/soroban-examples ``` Or, skip the development environment setup and open this example in [Gitpod][oigp]. @@ -63,7 +63,7 @@ impl IncrementContract { } ``` -Ref: https://github.com/stellar/soroban-examples/tree/v0.7.0/increment +Ref: https://github.com/stellar/soroban-examples/tree/v0.8.4/increment ## How it Works @@ -158,10 +158,10 @@ To build the contract, use the `cargo build` command. cargo build --target wasm32-unknown-unknown --release ``` -A `.wasm` file should be outputted in the `../target` directory: +A `.wasm` file should be outputted in the `target` directory: ``` -../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm +target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm ``` ## Run the Contract @@ -170,7 +170,7 @@ If you have [`soroban-cli`] installed, you can invoke contract functions in the ```sh soroban contract invoke \ - --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ + --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ -- \ increment @@ -186,7 +186,7 @@ Rerun the invoke with the `--footprint` option to view the [footprint] of the in ```sh soroban contract invoke \ - --wasm ../target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ + --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ --id 1 \ --footprint \ -- \ From 585f1b8813eed26f7d07152a5648b1d129f0b868 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Thu, 25 May 2023 09:39:47 -0700 Subject: [PATCH 161/248] update quickstart hash (#456) --- docs/getting-started/deploy-to-a-local-network.mdx | 2 +- docs/getting-started/deploy-to-futurenet.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index e13bb6d27..72742fef7 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -25,7 +25,7 @@ To run a local standalone network with the Stellar Quickstart Docker image, run docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ + stellar/quickstart:soroban-dev@sha256:1b7317be1eadc28461f4cc9ac93b5c223ccd638b2628b3693bcec6ac46fbc618 \ --standalone \ --enable-soroban-rpc ``` diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 5b4063328..0913ca09a 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -47,7 +47,7 @@ To run your own soroban-rpc locally, use the following command, and rpc-url `htt docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:a057ec6f06c6702c005693f8265ed1261e901b153a754e97cf18b0962257e872 \ + stellar/quickstart:soroban-dev@sha256:1b7317be1eadc28461f4cc9ac93b5c223ccd638b2628b3693bcec6ac46fbc618 \ --futurenet \ --enable-soroban-rpc ``` From 2fe21d244bf7f589acadd85ab881abc46cf8c893 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Fri, 26 May 2023 09:19:07 -0700 Subject: [PATCH 162/248] updates quickstart versions (#459) --- docs/getting-started/deploy-to-a-local-network.mdx | 2 +- docs/getting-started/deploy-to-futurenet.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index 72742fef7..099dd7671 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -25,7 +25,7 @@ To run a local standalone network with the Stellar Quickstart Docker image, run docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:1b7317be1eadc28461f4cc9ac93b5c223ccd638b2628b3693bcec6ac46fbc618 \ + stellar/quickstart:soroban-dev@sha256:57e8ab498bfa14c65595fbb01cb94b1cdee9637ef2e6634e59d54f6958c05bdb \ --standalone \ --enable-soroban-rpc ``` diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 0913ca09a..aef2a328b 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -47,7 +47,7 @@ To run your own soroban-rpc locally, use the following command, and rpc-url `htt docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:1b7317be1eadc28461f4cc9ac93b5c223ccd638b2628b3693bcec6ac46fbc618 \ + stellar/quickstart:soroban-dev@sha256:57e8ab498bfa14c65595fbb01cb94b1cdee9637ef2e6634e59d54f6958c05bdb \ --futurenet \ --enable-soroban-rpc ``` From 7cc43420df23bf2b54047a7dbe5612f28ebcbb29 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Tue, 30 May 2023 10:50:26 -0700 Subject: [PATCH 163/248] Evm to Soroban (#409) * initial commit * add code breakdown * add mdx * remove mdx * update Rust SC * add advanced concepts * add vault contract and tests * Update solidity-and-rust-advanced-concepts.mdx * remove un tabbed code * update vault.rs; add shell cmds * update yield amount * add vault deployment and interaction * add wdraw message * fix script sequence * add EVM comparison * update error handling * 1st round review * Update script descroption * add solidity to approved languages * fixed a broken link * move file folder; add token inheritance * update links * fixed broken links * update Soroban Description * nit: spelling * Fix bytes and arrays * spelling errors * spelling errors * no capitalization on build * grammar spelling errors * spelling and grammar errors * fixes; post PR review * macros description * Correction: Data Types * update Symbol Definition * update traits definition: fix Solidity Contract * Merge main into evm-to-soroban (#414) * update code block (#400) * additional copy changes to site (#401) * copy edits from Dom (#403) * update broken link (#404) * update token interface (#406) * update token intereface Interface was referenced from : https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/token.rs * update fn description * nit: update fn description * nit: format * nit: bracket format * fix event topics * update events * revert per PR to fix event name https://github.com/stellar/rs-soroban-env/pull/778/files * Improve Failure Condition Handling in Token Interface (#394) * Add Error Handling Section * update authorization info * add more context to authorization * nit: call not specific to callers address * Add event docs (#375) * Add event docs * Remove note * Add link to events example * fixes malformed hello world link (#412) * Remove derive Default (#413) --------- Co-authored-by: Tyler van der Hoeven Co-authored-by: Bri <92327786+briwylde08@users.noreply.github.com> Co-authored-by: Siddharth Suresh Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> * fix spelling and add string example * move evm-to-soroban * resolve conflict * add auth section. Add comparison for addresses * embolden main point about replay prevention * nit update section * nit wording * improve Address and Auth Callouts * update contract deposit fn. Update ID to addr conversion * nit: var placeholders * example vault update * update vault example to 8.1 * update to align w main * updates Env:: to env. ; nits * add section on composability * nit: update soroban-sdk version * update example to use sdk 8.4 * remove admin from mint * nit: grammar; update tx messages --------- Co-authored-by: Tyler van der Hoeven Co-authored-by: Bri <92327786+briwylde08@users.noreply.github.com> Co-authored-by: Siddharth Suresh Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> --- docs/getting-started/hello-world.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 2cdf44e3b..96b139d5d 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -385,4 +385,4 @@ Building optimized contracts is only necessary when deploying to a network with [Write a Contract]: #write-a-contract [Deploy to a Local Network]: deploy-to-a-local-network [Build]: #build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli \ No newline at end of file From ef4719441a8299f06b0faddd432e835ff7bdd58d Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Mon, 12 Jun 2023 15:07:54 -0600 Subject: [PATCH 164/248] copy edits (#467) * copy edits * Update connect-freighter-wallet.mdx * Update run-rpc.mdx --- docs/getting-started/connect-freighter-wallet.mdx | 14 +++++++------- docs/getting-started/run-rpc.mdx | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/getting-started/connect-freighter-wallet.mdx b/docs/getting-started/connect-freighter-wallet.mdx index 6ca70c1cd..bdb03c358 100644 --- a/docs/getting-started/connect-freighter-wallet.mdx +++ b/docs/getting-started/connect-freighter-wallet.mdx @@ -4,7 +4,7 @@ title: 4. Connect Freighter Wallet description: Freighter is a browser extension that can sign Soroban transactions. --- -[Freighter](https://www.freighter.app/) is a browser extension wallet provided by the Stellar Development Foundation. It provides users a way to interact with Soroban tokens directly from your web browser. +[Freighter](https://www.freighter.app/) is a browser extension wallet provided by the Stellar Development Foundation. It provides users a way to interact with Soroban tokens directly from the web browser. ## Setup @@ -42,9 +42,9 @@ Once you have added a Soroban token to your Freighter wallet, you can now send a 5. Review the details of your payment. Click `Send`. -## Sign Soroban XDR's +## Sign Soroban XDRs -With a funded Futurenet account and `Experimental Mode` enabled, you can now sign Soroban XDR's using dapps that are integrated with Freighter. An example of an integrated dapp is Stellar's [Laboratory](https://laboratory.stellar.org/#txsigner?network=futurenet). +With a funded Futurenet account and `Experimental Mode` enabled, you can now sign Soroban XDRs using dApps that are integrated with Freighter. An example of an integrated dApp is Stellar's [Laboratory](https://laboratory.stellar.org/#txsigner?network=futurenet). 1. On the Lab's transaction signer, enter a Soroban XDR into the form field. @@ -54,12 +54,12 @@ With a funded Futurenet account and `Experimental Mode` enabled, you can now sig 4. If approved, Freighter will transmit a signed XDR back to the Lab. -## As a dapp Provider, Prompt Freighter to Sign Transactions (Advanced) +## As a dApp Provider, Prompt Freighter to Sign Transactions (Advanced) -If you're building a JS dapp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): +If you're building a JS dApp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): 1. Follow the setup instructions above. -2. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dapp to sign Soroban XDR's using the account in Freighter. +2. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dApp to sign Soroban XDRs using the account in Freighter. -3. Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dapp. +3. Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dApp. diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 56c75a0d9..976e9712a 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -10,7 +10,7 @@ For example, you can build an application and have it [send a transaction](https Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance to access the network. -## Run your own instance +## Run Your Own Instance [Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). For local development, an RPC service can run on a standard laptop with 16GB of RAM and has minimal storage and CPU requirements. From 3ed263ffdde0b92c0c98136a285bc99fa267213c Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Tue, 20 Jun 2023 14:42:14 -0600 Subject: [PATCH 165/248] docs reorg 2.0 (#474) * docs reorg 2.0 * fixed links --- docs/getting-started/hello-world.mdx | 2 +- .../invoking-contracts-with-transactions.mdx | 244 ++++++++++++++++++ docs/getting-started/run-rpc.mdx | 4 +- docs/getting-started/storing-data.mdx | 2 +- 4 files changed, 248 insertions(+), 4 deletions(-) create mode 100644 docs/getting-started/invoking-contracts-with-transactions.mdx diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 96b139d5d..088efd12c 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -98,7 +98,7 @@ debug-assertions = true See the [logging example] for more information about how to log. -[logging example]: ../how-to-guides/logging.mdx +[logging example]: ../basic-tutorials/logging.mdx ### Wrapping it Up diff --git a/docs/getting-started/invoking-contracts-with-transactions.mdx b/docs/getting-started/invoking-contracts-with-transactions.mdx new file mode 100644 index 000000000..43cb99d12 --- /dev/null +++ b/docs/getting-started/invoking-contracts-with-transactions.mdx @@ -0,0 +1,244 @@ +--- +sidebar_position: 8 +title: 6. Invoke and Deploy Contracts with Stellar Transactions +description: A description of the InvokeHostFunctionOp operation. +--- + +Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. + +The `InvokeHostFunctionOp` can be used to perform the following Soroban operations: + +- Invoke contract functions. +- Upload Wasm of the new contracts. +- Deploy new contracts using the uploaded Wasm or built-in implementations (this currently includes only the [token contract](../advanced-tutorials/stellar-asset-contract.mdx)). + +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli + +## InvokeHostFunctionOp + +The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found +[here][XDR]. + +[XDR]: https://github.com/stellar/stellar-xdr/blob/c2e702c70951ff59a1eff257f08cf38d47210e5f/Stellar-transaction.x#L550 + +```c++ +union HostFunctionArgs switch (HostFunctionType type) +{ +case HOST_FUNCTION_TYPE_INVOKE_CONTRACT: + SCVec invokeContract; +case HOST_FUNCTION_TYPE_CREATE_CONTRACT: + CreateContractArgs createContract; +case HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM: + UploadContractWasmArgs uploadContractWasm; +}; + +struct HostFunction { + // Arguments of the function to call defined by the function + // type. + HostFunctionArgs args; + // Per-address authorizations for this host fn + // Currently only supported for INVOKE_CONTRACT function + ContractAuth auth<>; +}; + +struct InvokeHostFunctionOp +{ + // The host functions to invoke. The functions will be executed + // in the same fashion as operations: either all functions will + // be successfully applied or all fail if at least one of them + // fails. + HostFunction functions; +}; +``` + +### Function + +The `functions` in `InvokeHostFunctionOp` will be executed by the Soroban host environment. The function arguments are passed as function-dependent XDR. The options are: + +1. `HOST_FUNCTION_TYPE_INVOKE_CONTRACT` + - This will call the `call_n` host function, invoking a contract function. + - `invokeArgs` is expected to contain the contract id, contract function name, and the parameters to the contract function being invoked. +2. `HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM` + - This will upload the contract Wasm using the provided `code` blob: + ```c++ + struct UploadContractWasmArgs + { + opaque code; + }; + ``` +3. `HOST_FUNCTION_TYPE_CREATE_CONTRACT` + - This will create a contract instance in the network using the specified `source` and build a 32-byte contract identifer based on `contractID` value. + ```c++ + struct CreateContractArgs + { + ContractID contractID; + SCContractCode source; + }; + ``` + - `source` can be either a reference to the hash of the installed WASM (to be more precise, a SHA-256 hash of the `InstallContractCodeArgs` from the operation above) or just specify that a built-in contract has to be used: + ```c++ + union SCContractCode switch (SCContractCodeType type) + { + case SCCONTRACT_CODE_WASM_REF: + Hash wasm_id; + case SCCONTRACT_CODE_TOKEN: + void; + }; + ``` + +- `contractID` is defined as following: + ```c++ + union ContractID switch (ContractIDType type) + { + case CONTRACT_ID_FROM_SOURCE_ACCOUNT: + uint256 salt; + case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: + struct + { + uint256 key; + Signature signature; + uint256 salt; + } fromEd25519PublicKey; + case CONTRACT_ID_FROM_ASSET: + Asset asset; + }; + ``` +- The parameters of this value define which the hash preimage that is then hashed with SHA-256 to get the ID of the created contract. +- `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created using the Stellar source account and the provided salt. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_SOURCE_ACCOUNT`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L643-L649). +- `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using the Stellar asset. This is only supported when `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist when this is applied, however the issuer of the asset will be the initial token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). +- `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be created using a public ED25519 key. Since this operation is not tied to any on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR preimage. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ED25519`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L623-L629). + +### Authorization Data + +This is currently only supported for `HOST_FUNCTION_TYPE_INVOKE_CONTRACT`. + +Soroban [authorization framework](../fundamentals-and-concepts/authorization.mdx) provides a +standardized way for passing authorization data to the contract invocations via +`ContractAuth` structures. + +```c++ +struct AddressWithNonce +{ + SCAddress address; + uint64 nonce; +}; + +struct ContractAuth +{ + AddressWithNonce* addressWithNonce; // not present for invoker + AuthorizedInvocation rootInvocation; + SCVec signatureArgs; +}; +``` + +`ContractAuth` contains a tree of invocations authorized by an `Address` and +the corresponding signature (in `Address`-dependent format). + +In order to build a `ContractAuth` the following is required: + +- `Address` that authorizes the invocations and the corresponding `nonce`. + - When `addressWithNonce` is missing, then it means that the transaction + source account (or operation source when present) authorizes these + invocations. `signatureArgs` have to be skipped as well in this case. + - `nonce` has to correspond to the `contractID` of the `rootInvocation`. It + is stored in the ledger entry with `CONTRACT_DATA` key with `contractID` from + `rootInvocation` and `SCVal` `key` with the following value: + `ScVal::LedgerKeyNonce(ScNonceKey{ nonce_address })` (when not present, nonce + is equal to `0`). +- `rootInvocation` structure corresponding to the authorized invocation tree +- `signatureArgs` - signature (or multiple signatures) that sign the 32-byte +payload that is a SHA-256 hash of `ENVELOPE_TYPE_CONTRACT_AUTH` preimage +([XDR][envelope-xdr]). The signature structure is defined by the `Address` (see +below for the Stellar account signatures). This should be empty if +`addressWithNonce` is not present (as transaction/operation signature is used +instead). + +`AuthorizedInvocation` defines a node in the authorized invocation tree: + +```c++ +struct AuthorizedInvocation +{ + Hash contractID; + SCSymbol functionName; + SCVec args; + AuthorizedInvocation subInvocations<>; +}; +``` + +`AuthorizedInvocation` needs to include a contract, contract function, arguments +of `require_auth`/`require_auth_for_args` call and all the authorized +sub-contract invocations originating from the current node. Building +`AuthorizedInvocation` trees may be simplified by using the recording auth mode +in Soroban preflight (see the [docs][preflight-doc] for more details). + +[envelope-xdr]: https://github.com/stellar/stellar-xdr/blob/df18148747e807618acf4639db41c4fd6f0be9fc/Stellar-transaction.x#L681 +[preflight-doc]: ../fundamentals-and-concepts/interacting-with-contracts.mdx#authorization + +#### Stellar Account Signatures + +`signatureArgs` format is user-defined for the [custom accounts], but it is +protocol-defined for the Stellar accounts. + +The signatures for the Stellar account are a vector of the following Soroban +[structures] in the Soroban SDK format: + +```rust +#[contracttype] +pub struct AccountEd25519Signature { + pub public_key: BytesN<32>, + pub signature: BytesN<64>, +} +``` + +[structures]: https://github.com/stellar/rs-soroban-env/blob/main/soroban-env-host/src/native_contract/account_contract.rs#L33 +[custom accounts]: ../fundamentals-and-concepts/authorization.mdx#account-abstraction + +## Transaction resources + +Every Soroban transaction has to have a `SorobanTransactionData` transaction +[extension] populated. This is needed to compute the +[Soroban resource fee](../fundamentals-and-concepts/fees-and-metering.mdx). + +[extension]: https://github.com/stellar/stellar-xdr/blob/c2e702c70951ff59a1eff257f08cf38d47210e5f/Stellar-transaction.x#L874 + +The Soroban transaction data is defined as follows: + +```c++ +struct SorobanResources +{ + // The ledger footprint of the transaction. + LedgerFootprint footprint; + // The maximum number of instructions this transaction can use + uint32 instructions; + + // The maximum number of bytes this transaction can read from ledger + uint32 readBytes; + // The maximum number of bytes this transaction can write to ledger + uint32 writeBytes; + + // Maximum size of dynamic metadata produced by this contract ( + // currently only includes the events). + uint32 extendedMetaDataSizeBytes; +}; + +struct SorobanTransactionData +{ + SorobanResources resources; + // Portion of transaction `fee` allocated to refundable fees. + int64 refundableFee; + ExtensionPoint ext; +}; +``` + +This data comprises two parts: Soroban resources and the refundableFee. The +`refundableFee` is the portion of the transaction fee eligible for refund. It +should currently be no less than the metadata fee of the transaction. + +The `SorobanResources` structure includes the ledger footprint and the resource +values, which together determine the resource consumption limit and the +resource fee. The footprint must contain the `LedgerKey`s that will be read +and/or written. + +The simplest method to determine the values in `SorobanResources` is to use the +transaction simulation with +[preflight service](../fundamentals-and-concepts/interacting-with-contracts.mdx#preflight). \ No newline at end of file diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 976e9712a..0353eafd6 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -1,6 +1,6 @@ --- -sidebar_position: 8 -title: 6. Soroban RPC +sidebar_position: 9 +title: 7. Soroban RPC description: Get an RPC Service --- diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 6c345e79d..96d25e593 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -203,7 +203,7 @@ Soroban is a pre-release and at this time outputs footprints in an unstable JSON ::: -[footprint]: ../learn/persisting-data.mdx#footprints-and-parallel-contention +[footprint]: ../fundamentals-and-concepts/persisting-data.mdx#footprints-and-parallel-contention Run it a few more times to watch the count change. From ebb4d1ba323f660706250b55280671f681f0a638 Mon Sep 17 00:00:00 2001 From: Bri <92327786+briwylde08@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:05:31 -0600 Subject: [PATCH 166/248] Move invoking contracts with Stellar transactions (#488) --- .../invoking-contracts-with-transactions.mdx | 244 ------------------ docs/getting-started/run-rpc.mdx | 2 +- 2 files changed, 1 insertion(+), 245 deletions(-) delete mode 100644 docs/getting-started/invoking-contracts-with-transactions.mdx diff --git a/docs/getting-started/invoking-contracts-with-transactions.mdx b/docs/getting-started/invoking-contracts-with-transactions.mdx deleted file mode 100644 index 43cb99d12..000000000 --- a/docs/getting-started/invoking-contracts-with-transactions.mdx +++ /dev/null @@ -1,244 +0,0 @@ ---- -sidebar_position: 8 -title: 6. Invoke and Deploy Contracts with Stellar Transactions -description: A description of the InvokeHostFunctionOp operation. ---- - -Stellar supports invoking and deploying contracts with a new Operation named `InvokeHostFunctionOp`. The [`soroban-cli`] abstracts these details away from the user, but SDKs do not yet and if you're building a dapp you'll probably find yourself building the XDR transaction to submit to the network. - -The `InvokeHostFunctionOp` can be used to perform the following Soroban operations: - -- Invoke contract functions. -- Upload Wasm of the new contracts. -- Deploy new contracts using the uploaded Wasm or built-in implementations (this currently includes only the [token contract](../advanced-tutorials/stellar-asset-contract.mdx)). - -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli - -## InvokeHostFunctionOp - -The XDR of `HostFunction` and `InvokeHostFunctionOp` below can be found -[here][XDR]. - -[XDR]: https://github.com/stellar/stellar-xdr/blob/c2e702c70951ff59a1eff257f08cf38d47210e5f/Stellar-transaction.x#L550 - -```c++ -union HostFunctionArgs switch (HostFunctionType type) -{ -case HOST_FUNCTION_TYPE_INVOKE_CONTRACT: - SCVec invokeContract; -case HOST_FUNCTION_TYPE_CREATE_CONTRACT: - CreateContractArgs createContract; -case HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM: - UploadContractWasmArgs uploadContractWasm; -}; - -struct HostFunction { - // Arguments of the function to call defined by the function - // type. - HostFunctionArgs args; - // Per-address authorizations for this host fn - // Currently only supported for INVOKE_CONTRACT function - ContractAuth auth<>; -}; - -struct InvokeHostFunctionOp -{ - // The host functions to invoke. The functions will be executed - // in the same fashion as operations: either all functions will - // be successfully applied or all fail if at least one of them - // fails. - HostFunction functions; -}; -``` - -### Function - -The `functions` in `InvokeHostFunctionOp` will be executed by the Soroban host environment. The function arguments are passed as function-dependent XDR. The options are: - -1. `HOST_FUNCTION_TYPE_INVOKE_CONTRACT` - - This will call the `call_n` host function, invoking a contract function. - - `invokeArgs` is expected to contain the contract id, contract function name, and the parameters to the contract function being invoked. -2. `HOST_FUNCTION_TYPE_UPLOAD_CONTRACT_WASM` - - This will upload the contract Wasm using the provided `code` blob: - ```c++ - struct UploadContractWasmArgs - { - opaque code; - }; - ``` -3. `HOST_FUNCTION_TYPE_CREATE_CONTRACT` - - This will create a contract instance in the network using the specified `source` and build a 32-byte contract identifer based on `contractID` value. - ```c++ - struct CreateContractArgs - { - ContractID contractID; - SCContractCode source; - }; - ``` - - `source` can be either a reference to the hash of the installed WASM (to be more precise, a SHA-256 hash of the `InstallContractCodeArgs` from the operation above) or just specify that a built-in contract has to be used: - ```c++ - union SCContractCode switch (SCContractCodeType type) - { - case SCCONTRACT_CODE_WASM_REF: - Hash wasm_id; - case SCCONTRACT_CODE_TOKEN: - void; - }; - ``` - -- `contractID` is defined as following: - ```c++ - union ContractID switch (ContractIDType type) - { - case CONTRACT_ID_FROM_SOURCE_ACCOUNT: - uint256 salt; - case CONTRACT_ID_FROM_ED25519_PUBLIC_KEY: - struct - { - uint256 key; - Signature signature; - uint256 salt; - } fromEd25519PublicKey; - case CONTRACT_ID_FROM_ASSET: - Asset asset; - }; - ``` -- The parameters of this value define which the hash preimage that is then hashed with SHA-256 to get the ID of the created contract. -- `CONTRACT_ID_FROM_SOURCE_ACCOUNT` specifies that the contract ID will be created using the Stellar source account and the provided salt. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_SOURCE_ACCOUNT`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L643-L649). -- `CONTRACT_ID_FROM_ASSET` specifies that the contract will be created using the Stellar asset. This is only supported when `source == SCCONTRACT_CODE_TOKEN`. Note, that the asset doesn't need to exist when this is applied, however the issuer of the asset will be the initial token administrator. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ASSET`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L637-L642). -- `CONTRACT_ID_FROM_ED25519_PUBLIC_KEY` specified that the contract will be created using a public ED25519 key. Since this operation is not tied to any on-chain entity, this also has to contain an ED25519 signature of SHA256 hash of [`ENVELOPE_TYPE_CREATE_CONTRACT_ARGS`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L650-L656) XDR preimage. The contract ID preimage used is [`ENVELOPE_TYPE_CONTRACT_ID_FROM_ED25519`](https://github.com/stellar/stellar-xdr/blob/026c9cd074bdb28ddde8ee52f2a4502d9e518a09/Stellar-transaction.x#L623-L629). - -### Authorization Data - -This is currently only supported for `HOST_FUNCTION_TYPE_INVOKE_CONTRACT`. - -Soroban [authorization framework](../fundamentals-and-concepts/authorization.mdx) provides a -standardized way for passing authorization data to the contract invocations via -`ContractAuth` structures. - -```c++ -struct AddressWithNonce -{ - SCAddress address; - uint64 nonce; -}; - -struct ContractAuth -{ - AddressWithNonce* addressWithNonce; // not present for invoker - AuthorizedInvocation rootInvocation; - SCVec signatureArgs; -}; -``` - -`ContractAuth` contains a tree of invocations authorized by an `Address` and -the corresponding signature (in `Address`-dependent format). - -In order to build a `ContractAuth` the following is required: - -- `Address` that authorizes the invocations and the corresponding `nonce`. - - When `addressWithNonce` is missing, then it means that the transaction - source account (or operation source when present) authorizes these - invocations. `signatureArgs` have to be skipped as well in this case. - - `nonce` has to correspond to the `contractID` of the `rootInvocation`. It - is stored in the ledger entry with `CONTRACT_DATA` key with `contractID` from - `rootInvocation` and `SCVal` `key` with the following value: - `ScVal::LedgerKeyNonce(ScNonceKey{ nonce_address })` (when not present, nonce - is equal to `0`). -- `rootInvocation` structure corresponding to the authorized invocation tree -- `signatureArgs` - signature (or multiple signatures) that sign the 32-byte -payload that is a SHA-256 hash of `ENVELOPE_TYPE_CONTRACT_AUTH` preimage -([XDR][envelope-xdr]). The signature structure is defined by the `Address` (see -below for the Stellar account signatures). This should be empty if -`addressWithNonce` is not present (as transaction/operation signature is used -instead). - -`AuthorizedInvocation` defines a node in the authorized invocation tree: - -```c++ -struct AuthorizedInvocation -{ - Hash contractID; - SCSymbol functionName; - SCVec args; - AuthorizedInvocation subInvocations<>; -}; -``` - -`AuthorizedInvocation` needs to include a contract, contract function, arguments -of `require_auth`/`require_auth_for_args` call and all the authorized -sub-contract invocations originating from the current node. Building -`AuthorizedInvocation` trees may be simplified by using the recording auth mode -in Soroban preflight (see the [docs][preflight-doc] for more details). - -[envelope-xdr]: https://github.com/stellar/stellar-xdr/blob/df18148747e807618acf4639db41c4fd6f0be9fc/Stellar-transaction.x#L681 -[preflight-doc]: ../fundamentals-and-concepts/interacting-with-contracts.mdx#authorization - -#### Stellar Account Signatures - -`signatureArgs` format is user-defined for the [custom accounts], but it is -protocol-defined for the Stellar accounts. - -The signatures for the Stellar account are a vector of the following Soroban -[structures] in the Soroban SDK format: - -```rust -#[contracttype] -pub struct AccountEd25519Signature { - pub public_key: BytesN<32>, - pub signature: BytesN<64>, -} -``` - -[structures]: https://github.com/stellar/rs-soroban-env/blob/main/soroban-env-host/src/native_contract/account_contract.rs#L33 -[custom accounts]: ../fundamentals-and-concepts/authorization.mdx#account-abstraction - -## Transaction resources - -Every Soroban transaction has to have a `SorobanTransactionData` transaction -[extension] populated. This is needed to compute the -[Soroban resource fee](../fundamentals-and-concepts/fees-and-metering.mdx). - -[extension]: https://github.com/stellar/stellar-xdr/blob/c2e702c70951ff59a1eff257f08cf38d47210e5f/Stellar-transaction.x#L874 - -The Soroban transaction data is defined as follows: - -```c++ -struct SorobanResources -{ - // The ledger footprint of the transaction. - LedgerFootprint footprint; - // The maximum number of instructions this transaction can use - uint32 instructions; - - // The maximum number of bytes this transaction can read from ledger - uint32 readBytes; - // The maximum number of bytes this transaction can write to ledger - uint32 writeBytes; - - // Maximum size of dynamic metadata produced by this contract ( - // currently only includes the events). - uint32 extendedMetaDataSizeBytes; -}; - -struct SorobanTransactionData -{ - SorobanResources resources; - // Portion of transaction `fee` allocated to refundable fees. - int64 refundableFee; - ExtensionPoint ext; -}; -``` - -This data comprises two parts: Soroban resources and the refundableFee. The -`refundableFee` is the portion of the transaction fee eligible for refund. It -should currently be no less than the metadata fee of the transaction. - -The `SorobanResources` structure includes the ledger footprint and the resource -values, which together determine the resource consumption limit and the -resource fee. The footprint must contain the `LedgerKey`s that will be read -and/or written. - -The simplest method to determine the values in `SorobanResources` is to use the -transaction simulation with -[preflight service](../fundamentals-and-concepts/interacting-with-contracts.mdx#preflight). \ No newline at end of file diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx index 0353eafd6..c08b03da6 100644 --- a/docs/getting-started/run-rpc.mdx +++ b/docs/getting-started/run-rpc.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 9 -title: 7. Soroban RPC +title: 6. Soroban RPC description: Get an RPC Service --- From b0f67d4c42bf6dacb615e857989db5d02ce0f243 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 7 Jul 2023 13:43:02 -0400 Subject: [PATCH 167/248] Update hello-world.mdx (#490) --- docs/getting-started/hello-world.mdx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 088efd12c..a0ee15611 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -220,10 +220,8 @@ mod test; ```rust -#![cfg(test)] - -use super::{Contract, ContractClient}; -use soroban_sdk::{vec, Env}; +use soroban_sdk::{vec, Env, Symbol}; +use crate::{Contract, ContractClient}; #[test] fn test() { @@ -385,4 +383,4 @@ Building optimized contracts is only necessary when deploying to a network with [Write a Contract]: #write-a-contract [Deploy to a Local Network]: deploy-to-a-local-network [Build]: #build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli \ No newline at end of file +[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli From 8e2f741f660a732e915f3d7e40766aa64e401437 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Thu, 13 Jul 2023 14:05:27 -0700 Subject: [PATCH 168/248] Release Preview 10 (#480) * Change command recommended for building .wasm files for deployment (#476) * Fix logging example (#481) * Update docs with auth XDR changes. (#483) * Update docs with auth XDR changes. * WASM->Wasm rename. Wasm is the official abbreviation of WebAssembly. * Typo fixes (#484) * Add fuzzing docs. (#486) * State expiration operations and token updates (#485) * Add docs for state expiration operations * Updates * update token * Update custom account * More token updates * Update atomic swap * More detailed state expiration docs (#492) * More fixes (#489) * More fixes * Add approve warning * Update releases page * Fix link * Update example links from 0.8.4 to 0.9.2 * fix link * Fixed instance bump bug in docs (#493) --------- Co-authored-by: Dmytro Kozhevin Co-authored-by: Brian Anderson Co-authored-by: Siddharth Suresh Co-authored-by: Garand Tyson Co-authored-by: Julian Martinez --- docs/getting-started/hello-world.mdx | 8 +- docs/getting-started/state-expiration.mdx | 124 ++++++++++++++++++++++ docs/getting-started/storing-data.mdx | 117 ++++++++++++++++---- 3 files changed, 226 insertions(+), 23 deletions(-) create mode 100644 docs/getting-started/state-expiration.mdx diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index a0ee15611..dce7a1892 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -288,10 +288,10 @@ Try changing the values in the test to see how it works. ## Build -To build a Soroban contract to deploy or run, use the `cargo build` command. +To build a Soroban contract to deploy or run, use the `soroban contract build` command. ```sh -cargo build --target wasm32-unknown-unknown --release +soroban contract build ``` :::tip @@ -360,8 +360,8 @@ The [hello world example] demonstrates how to write a simple contract, with a si [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.8.4 -[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.8.4/hello_world +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2 +[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.9.2/hello_world ## Optimizing Builds diff --git a/docs/getting-started/state-expiration.mdx b/docs/getting-started/state-expiration.mdx new file mode 100644 index 000000000..01d8aa2a5 --- /dev/null +++ b/docs/getting-started/state-expiration.mdx @@ -0,0 +1,124 @@ +--- +sidebar_position: 10 +title: 8. State Expiration +description: State Expiration Semantics +--- + +# Terms and Semantics + +## Expiration Ledger + +Each `ContractData` and `ContractCode` entry has an `expirationLedger` field stored in its `LedgerEntry`. +The entry is considered expired when `current_ledger > expirationLedger`. + +## Lifetime + +An entry's lifetime is defined as how many ledgers remain until the entry expires. +For example, if the current ledger is 5 and an entry's expiration ledger is 15, then +the entry's lifetime is 10 ledgers. + +## Minimum Lifetime + +For each entry type, there is a minimum lifetime that the entry must have when being created +or updated. This lifetime minimum is enforced automatically at the protocol level. This minimum +is a network parameter and defaults to 16 ledgers for `Temporary` entries and 4,096 ledgers for +`Persistent` and `Instance` entries. + +## Maximum Lifetime + +On any given ledger, an entry's lifetime can be extended up to the maximum lifetime. This is a +network parameter and defaults to 1 year worth of ledgers. This maximum lifetime is not enforced +based on when an entry was created, but based on the current ledger. For example, if an entry is +created on January 1st, 2024, its lifetime could initially be bumped up to January 1st, 2025. +After this initial lifetime bump, if the entry received another lifetime bump later on January 10th, 2024, +the lifetime could be extended up to January 10th, 2025. + +# Operations + +## BumpFootprintExpirationOp + +### Semantics + +XDR: +``` +/* + Threshold: med + Result: BumpFootprintExpirationResult +*/ +struct BumpFootprintExpirationOp +{ + ExtensionPoint ext; + uint32 ledgersToExpire; +}; +``` + +`BumpFootprintExpirationOp` is a Soroban operation that will bump the expiration +ledger of the entries specified in the *read-only set of the footprint*. The +read-write set must be empty. The bump will make sure that the entries will not +expire before ledgersToExpire ledgers from now. + +Let's look at this example below. +``` +Ex. Last closed ledger (LCL) = 5, Current Ledger = 6, ledgersToExpire = 8 + +entry1.expirationLedger = 10 +entry2.expirationLedger = 14 +entry3.expirationLedger = 10000 + +entry1.expirationLedger will be updated to 14 so it will live for 8 more ledgers +after the current one closes and the entry can be accessed in ledgers [6, 14]. Note: This is going to be updated to count +Current Ledger, so it'll become [6, 13]. + +entry2 and entry3 will not be updated because they already have an +expirationLedger that is large enough. +``` + +### Transaction resources + +`BumpFootprintExpirationOp` is a Soroban operation, and therefore must be the +only operation in a transaction. The transaction also needs to populate +`SorobanTransactionData` transaction extension explained +[here](../fundamentals-and-concepts/invoking-contracts-with-transactions.mdx#transaction-resources). To fill +out `SorobanResources`, use preflight mentioned in the provided link, or make +sure `readBytes` includes the key and entry size of every entry in the +`readOnly` set and make sure `extendedMetaDataSizeBytes` is at least double of +`readBytes`. + + +## RestoreFootprintOp + +XDR: +``` +/* + Threshold: med + Result: RestoreFootprintOp +*/ +struct RestoreFootprintOp +{ + ExtensionPoint ext; +}; +``` + +`RestoreFootprintOp` is a Soroban operation that will restore expired entries +specified in the *read-write set of the footprint* and make them accessible +again. The read-only set of the footprint must be empty. An expired entry is one +where its expirationLedger is less than the current ledger number. + +The restored entry will have its expiration ledger bumped to the [minimums] the +network allows for newly created entries, which is 4096 + current ledger for +persistent entries, and 16 + current ledger for temporary entries (Note that +both will be updated soon to use 4096 + current ledger - 1 and 16 + current +ledger - 1). The minimums linked are what the settings will be on release, but +they can be updated in the future through a validator vote. + +[minimums]: https://github.com/stellar/stellar-core/blob/2109a168a895349f87b502ae3d182380b378fa47/src/ledger/NetworkConfig.h#L77-L78 +### Transaction resources + +`RestoreFootprintOp` is a Soroban operation, and therefore must be the only +operation in a transaction. The transaction also needs to populate +`SorobanTransactionData` transaction extension explained +[here](../fundamentals-and-concepts/invoking-contracts-with-transactions.mdx#transaction-resources). To fill +out `SorobanResources`, use preflight mentioned in the provided link, or make +sure `writeBytes` includes the key and entry size of every entry in the +`readWrite` set and make sure `extendedMetaDataSizeBytes` is at least double of +`writeBytes`. diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 96d25e593..5a1bc6ae2 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -7,18 +7,18 @@ description: Write a simple Soroban contract that stores and retrieves data. The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.8.4 +[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2 -[increment example]: https://github.com/stellar/soroban-examples/tree/v0.8.4/increment +[increment example]: https://github.com/stellar/soroban-examples/tree/v0.9.2/increment ## Run the Example -First go through the [Setup] process to get your development environment configured, then clone the `v0.8.4` tag of `soroban-examples` repository: +First go through the [Setup] process to get your development environment configured, then clone the `v0.9.2` tag of `soroban-examples` repository: [Setup]: setup.mdx ``` -git clone -b v0.8.4 https://github.com/stellar/soroban-examples +git clone -b v0.9.2 https://github.com/stellar/soroban-examples ``` Or, skip the development environment setup and open this example in [Gitpod][oigp]. @@ -49,21 +49,31 @@ pub struct IncrementContract; #[contractimpl] impl IncrementContract { + /// Increment increments an internal counter, and returns the value. pub fn increment(env: Env) -> u32 { - let mut count: u32 = env - .storage() - .get(COUNTER) - .unwrap_or(Ok(0)) // If no value set, assume 0. - .unwrap(); // Panic if the value of COUNTER is not u32. + // Get the current count. + let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0); // If no value set, assume 0. log!(&env, "count: {}", count); + + // Increment the count. count += 1; - env.storage().set(COUNTER, count); + + // Save the count. + env.storage().instance().set(&COUNTER, &count); + + // The contract instance will be bumped to have a lifetime of at least 100 ledgers. + // If the lifetime is already more than 100 ledgers, this is a no-op. Otherwise, + // the lifetime is extended to 100 ledgers. This lifetime bump includes the contract + // instance itself and all entries in storage().instance(), i.e, COUNTER. + env.storage().instance().bump(100); + + // Return the count to the caller. count } } ``` -Ref: https://github.com/stellar/soroban-examples/tree/v0.8.4/increment +Ref: https://github.com/stellar/soroban-examples/tree/v0.9.2/increment ## How it Works @@ -85,18 +95,27 @@ Short `Symbol`s up to 9 characters long can be pre-computed at compile time usin const COUNTER: Symbol = Symbol::short("COUNTER"); ``` +### Types of Contract data + +Contract data is made up of three different types: `Persistent`, `Temporary`, and `Instance`. All contract data has a "lifetime" that must be periodically bumped. If an entry's +lifetime is not periodically bumped, the entry will eventually reach the end of its lifetime and "expire". Each type of storage functions similarly, but have different fees and expiration behavior. Whenever a +`Temporary` entry expires, it is deleted from the ledger and is permanently inaccessible. Whenever a `Persistent` or `Instance` entry expires, it is inaccessible, but can be +"restored" and used again via the [`RestoreFootprintOp`]. As a general rule, `Temporary` storage should only be used for data that can be easily recreated or is only valid for a period +of time, where `Persistent` or `Instance` storage should be used for data that can not be recreated and should kept permanently, such as a user's token balance. For more information +about the different storage types, see [Contract Data Type Descriptions](#Contract-Data-Type-Descriptions). + ### Contract Data Access -The `Env` `data()` function is used to retrieve access and update a counter. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data. +The `Env.storage()` function is used to retrieve access and update a counter. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data. The `get()` function gets the current value associated with the counter key. ```rust let mut count: u32 = env .storage() - .get(COUNTER) - .unwrap_or(Ok(0)) // If no value set, assume 0. - .unwrap(); // Panic if the value of COUNTER is not u32. + .instance() + .get(&COUNTER) + .unwrap_or(0); // If no value set, assume 0. ``` If no value is currently stored, the value given to `unwrap_or(...)` is returned instead. @@ -106,9 +125,40 @@ Values stored as contract data and retrieved are transmitted from the environmen The `set()` function stores the new count value against the key, replacing the existing value. ```rust -env.storage().set(COUNTER, count); +env.storage().instance().set(&COUNTER, count); ``` +To access a given type of storage, use `Env.storage().persistent()`, `Env.storage().temporary()`, and `Env.storage().instance()`. +Each storage type is in a separate key space. To demonstrate this, see the code snippet below: + +```rust +const EXAMPLE_KEY: Symbol = Symbol::short("KEY"); +env.storage().persistent().set(&EXAMPLE_KEY, 1); +env.storage().temporary().set(&EXAMPLE_KEY, 2); + +env.storage().persistent().get(&EXAMPLE_KEY); // Returns Ok(1) +env.storage().temporary().get(&EXAMPLE_KEY); // Returns Ok(2) +``` + + +### Managing Contract Data Lifetimes + +The `Env.storage().storage_type().bump()` function is used to extend a contract data entry's lifetime inside a smart contract function. The `bump()` function is a conditional lifetime bump which +extends an entry's lifetime up to a given length of time, measured in ledgers. + +```rust +env.storage().instance().bump(100); +``` + +This call to `bump()` ensures that the current lifetime of the contract instance entry is at least 100 ledgers. If this is called and the contract instance entry has a current lifetime of 50 ledgers, +the lifetime will be extended up to 100 ledgers. If this is called and the contract instance entry has a current lifetime of 150 ledgers, the lifetime will not be extended and the `bump()` call is a no-op. + +All `Instance` storage is stored in a single contract instance `LedgerEntry` and shares a single lifetime. This means that one call to `Env.storage().instance().bump()` will extend the lifetime of all `Instance` +entries, as well as the contract instance itself. For `Temporary` and `Persistent` storage, each entry has its own lifetime and must be bumped individually. The interface is slightly different and takes the key +of the entry being bumped as well as the new lifetime. + +In addition to contract defined lifetime extensions using the `bump()` function, a contract data entry's lifetime can be extended via the [`BumpFootprintExpirationOp`] operation. + ## Tests Open the `increment/src/test.rs` file to follow along. @@ -152,10 +202,10 @@ assert_eq!(client.increment(), 1); ## Build the Contract -To build the contract, use the `cargo build` command. +To build the contract, use the `soroban contract build` command. ```sh -cargo build --target wasm32-unknown-unknown --release +soroban contract build ``` A `.wasm` file should be outputted in the `target` directory: @@ -166,7 +216,7 @@ target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm ## Run the Contract -If you have [`soroban-cli`] installed, you can invoke contract functions in the WASM using it. +If you have [`soroban-cli`] installed, you can invoke contract functions in the Wasm using it. ```sh soroban contract invoke \ @@ -197,6 +247,32 @@ soroban contract invoke \ Footprint: {"readOnly":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"static":"ledgerKeyContractCode"}}}],"readWrite":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"symbol":[67,79,85,78,84,69,82]}}}]} ``` +### Contract Data Type Descriptions + +The general usage and interface is identical for all storage types. They differ only in fees and expiration behavior as follows: + +- `Temporary` + - Cheapest fees. + - Permanently deleted on expiration, cannot be restored. + - Suitable for time bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. + - Unlimited amount of storage. +- `Instance` + - Most expensive fees (same price as `Persistent` storage). + - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. + - Shares the same lifetime as the contract instance. If the contract instance has not expired, instance data is guaranteed to be accessible and not expired. + - Limited amount of storage available. + - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). +- `Persistent` + - Most expensive fees (same price as `Instance` storage). + - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. + - Does not share the same lifetime as the contract instance. If the contract instance is not expired, `Persistent` data may be expired and need to be restored before invoking the contract. + - Unlimited amount of storage. + - Suitable for user data that cannot be `Temporary` (i.e. balances). + +For more detailed guidelines on how to use contract data, see [`Contract Data Best Practices`]. + +### Contract Data Best Practices + :::info Soroban is a pre-release and at this time outputs footprints in an unstable JSON format. @@ -214,3 +290,6 @@ soroban contract read --id 1 --key COUNTER ``` [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli +[`BumpFootprintExpirationOp`]: ../getting-started/state-expiration#BumpFootprintExpirationOp +[`RestoreFootprintOp`]: ../getting-started/state-expiration#RestoreFootprintOp +[`Contract Data Best Practices`]: ../fundamentals-and-concepts/persisting-data.mdx#contract-data-best-practices From 3ca50c074a109e8f984e3a540d931c4be525ad12 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Fri, 14 Jul 2023 10:09:34 -0700 Subject: [PATCH 169/248] Update setup.mdx (#495) --- docs/getting-started/setup.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 4ed9c7abf..d073b620d 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -57,7 +57,7 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. ```sh -cargo install --locked --version 0.8.0 soroban-cli +cargo install --locked --version 0.9.1 soroban-cli ``` :::info From c08d6777e145f9bd46f65d84d6fefa07e77bf727 Mon Sep 17 00:00:00 2001 From: Siddharth Suresh Date: Fri, 14 Jul 2023 15:04:02 -0500 Subject: [PATCH 170/248] fix versions (#497) --- docs/getting-started/hello-world.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index dce7a1892..c7d04ece6 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -49,10 +49,10 @@ The `soroban-sdk` is in early development. Report issues [here](https://github.c ```toml [dependencies] -soroban-sdk = "0.8.4" +soroban-sdk = "0.9.2" [dev_dependencies] -soroban-sdk = { version = "0.8.4", features = ["testutils"] } +soroban-sdk = { version = "0.9.2", features = ["testutils"] } [features] testutils = ["soroban-sdk/testutils"] @@ -117,10 +117,10 @@ crate-type = ["cdylib"] testutils = ["soroban-sdk/testutils"] [dependencies] -soroban-sdk = "0.8.4" +soroban-sdk = "0.9.2" [dev_dependencies] -soroban-sdk = { version = "0.8.4", features = ["testutils"] } +soroban-sdk = { version = "0.9.2", features = ["testutils"] } [profile.release] opt-level = "z" From bd89a43fd790199d79dd42aea5c4355992a16a49 Mon Sep 17 00:00:00 2001 From: Julian Martinez <73849597+Julian-dev28@users.noreply.github.com> Date: Fri, 14 Jul 2023 14:34:01 -0700 Subject: [PATCH 171/248] add #[contract] and symbol_short (#498) * #[contract]; symbol_short description * Update hello-world.mdx * add missing symbol_short and #[contract] references --- .../deploy-to-a-local-network.mdx | 2 +- docs/getting-started/deploy-to-futurenet.mdx | 2 +- docs/getting-started/hello-world.mdx | 27 ++++++++++--------- docs/getting-started/storing-data.mdx | 13 +++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx index 099dd7671..c55bdbe96 100644 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ b/docs/getting-started/deploy-to-a-local-network.mdx @@ -25,7 +25,7 @@ To run a local standalone network with the Stellar Quickstart Docker image, run docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:57e8ab498bfa14c65595fbb01cb94b1cdee9637ef2e6634e59d54f6958c05bdb \ + stellar/quickstart:soroban-dev@sha256:ed57f7a7683e3568ae401f5c6e93341a9f77d8ad41191bf752944d7898981e0c \ --standalone \ --enable-soroban-rpc ``` diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index aef2a328b..5d7072bad 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -47,7 +47,7 @@ To run your own soroban-rpc locally, use the following command, and rpc-url `htt docker run --rm -it \ -p 8000:8000 \ --name stellar \ - stellar/quickstart:soroban-dev@sha256:57e8ab498bfa14c65595fbb01cb94b1cdee9637ef2e6634e59d54f6958c05bdb \ + stellar/quickstart:soroban-dev@sha256:ed57f7a7683e3568ae401f5c6e93341a9f77d8ad41191bf752944d7898981e0c \ --futurenet \ --enable-soroban-rpc ``` diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index c7d04ece6..4828130fa 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -152,7 +152,7 @@ Once you've created a project, writing a contract involves writing Rust code in All contracts should begin with `#![no_std]` to ensure that the Rust standard library is not included in the build. The Rust standard library is large and not well suited to being deployed into small programs like those deployed to blockchains. ```rust -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contract, contractimpl, symbol_short, vec, Env, Symbol, Vec}; ``` The contract will need to import the types and macros that it needs from the `soroban-sdk` crate. Take a look at [Create a Project](#create-new-project) to see how to setup a project. @@ -162,8 +162,8 @@ Many of the types available in typical Rust programs, such as `std::vec::Vec`, a Contract inputs must not be references. ```rust +#[contract] pub struct Contract; - #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { @@ -172,20 +172,21 @@ impl Contract { } ``` -Contract functions live inside an `impl` for a struct. The `impl` block is annotated with `#[contractimpl]`. Contract functions must be given names that are no more than 32 characters long. Functions that are intended to be called externally should be marked with `pub` visibility. The first argument can be an `Env` argument to get a copy of the Soroban environment, which is necessary for most things. +The `#[contract]` attribute designates the Contract struct as the type to which contract functions are associated. This implies that the struct will have contract functions implemented for it. Contract functions are defined within an `impl` block for the struct, which is annotated with `#[contractimpl]`. It is important to note that contract functions should have names with a maximum length of 32 characters. Additionally, if a function is intended to be invoked from outside the contract, it should be marked with the `pub` visibility modifier. It is common for the first argument of a contract function to be of type `Env`, allowing access to a copy of the Soroban environment, which is typically necessary for various operations within the contract. Putting those pieces together a simple contract will look like this. ```rust title="src/lib.rs" #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contract, contractimpl, symbol_short, vec, Env, Symbol, Vec}; +#[contract] pub struct Contract; #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, Symbol::short("Hello"), to] + vec![&env, symbol_short!("Hello"), to] } } ``` @@ -201,17 +202,17 @@ Given a simple contract like the contract demonstrated in the Write a Contract s ```rust #![no_std] -use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec}; +use soroban_sdk::{contract, contractimpl, symbol_short, vec, Env, Symbol, Vec}; +#[contract] pub struct Contract; #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { - vec![&env, Symbol::short("Hello"), to] + vec![&env, symbol_short!("Hello"), to] } } - #[cfg(test)] mod test; ``` @@ -220,8 +221,8 @@ mod test; ```rust -use soroban_sdk::{vec, Env, Symbol}; use crate::{Contract, ContractClient}; +use soroban_sdk::{vec, Env, Symbol, symbol_short}; #[test] fn test() { @@ -229,10 +230,10 @@ fn test() { let contract_id = env.register_contract(None, Contract); let client = ContractClient::new(&env, &contract_id); - let words = client.hello(&Symbol::short("Dev")); + let words = client.hello(&symbol_short!("Dev")); assert_eq!( words, - vec![&env, Symbol::short("Hello"), Symbol::short("Dev"),] + vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),] ); } ``` @@ -256,7 +257,7 @@ All public functions within an `impl` block that is annotated with the `#[contra ```rust let client = ContractClient::new(&env, &contract_id); -let words = client.hello(&Symbol::short("Dev")); +let words = client.hello(&symbol_short!("Dev")); ``` The values returned by functions can be asserted on: @@ -264,7 +265,7 @@ The values returned by functions can be asserted on: ```rust assert_eq!( words, - vec![&env, Symbol::short("Hello"), Symbol::short("Dev"),] + vec![&env, symbol_short!("Hello"), symbol_short!("Dev"),] ); ``` diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 5a1bc6ae2..86cd88e2d 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -43,8 +43,12 @@ test test::test ... ok ## Code ```rust title="increment/src/lib.rs" -const COUNTER: Symbol = Symbol::short("COUNTER"); +#![no_std] +use soroban_sdk::{contract, contractimpl, symbol_short, vec, Env, Symbol, Vec, log}; +const COUNTER: Symbol = symbol_short!("COUNTER"); + +#[contract] pub struct IncrementContract; #[contractimpl] @@ -88,11 +92,10 @@ a later time to lookup the value. character space (only `a-zA-z0-9_` characters are allowed). Identifiers like contract function names are represented by `Symbol`s. -Short `Symbol`s up to 9 characters long can be pre-computed at compile time using -`Symbol::short`. +The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime. ```rust -const COUNTER: Symbol = Symbol::short("COUNTER"); +const COUNTER: Symbol = symbol_short!("COUNTER"); ``` ### Types of Contract data @@ -132,7 +135,7 @@ To access a given type of storage, use `Env.storage().persistent()`, `Env.storag Each storage type is in a separate key space. To demonstrate this, see the code snippet below: ```rust -const EXAMPLE_KEY: Symbol = Symbol::short("KEY"); +const EXAMPLE_KEY: Symbol = symbol_short!("KEY"); env.storage().persistent().set(&EXAMPLE_KEY, 1); env.storage().temporary().set(&EXAMPLE_KEY, 2); From ef10d15b4fd93cc32df35ddaf8ed35ac9e3844d7 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Thu, 20 Jul 2023 16:45:13 -0400 Subject: [PATCH 172/248] fix: move State Expiration to Concepts (#505) This is not part of the core onboarding tutorial. It probably belongs in Fundamentals and Concepts instead. For background, these docs are attempting to use [Divio's documentation system](https://documentation.divio.com/), with the "Getting Started" section as _The_ Tutorial. The "Fundamentals and Concepts" section is what Divio describes as "Explanation" docs. --- docs/getting-started/state-expiration.mdx | 124 ---------------------- 1 file changed, 124 deletions(-) delete mode 100644 docs/getting-started/state-expiration.mdx diff --git a/docs/getting-started/state-expiration.mdx b/docs/getting-started/state-expiration.mdx deleted file mode 100644 index 01d8aa2a5..000000000 --- a/docs/getting-started/state-expiration.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -sidebar_position: 10 -title: 8. State Expiration -description: State Expiration Semantics ---- - -# Terms and Semantics - -## Expiration Ledger - -Each `ContractData` and `ContractCode` entry has an `expirationLedger` field stored in its `LedgerEntry`. -The entry is considered expired when `current_ledger > expirationLedger`. - -## Lifetime - -An entry's lifetime is defined as how many ledgers remain until the entry expires. -For example, if the current ledger is 5 and an entry's expiration ledger is 15, then -the entry's lifetime is 10 ledgers. - -## Minimum Lifetime - -For each entry type, there is a minimum lifetime that the entry must have when being created -or updated. This lifetime minimum is enforced automatically at the protocol level. This minimum -is a network parameter and defaults to 16 ledgers for `Temporary` entries and 4,096 ledgers for -`Persistent` and `Instance` entries. - -## Maximum Lifetime - -On any given ledger, an entry's lifetime can be extended up to the maximum lifetime. This is a -network parameter and defaults to 1 year worth of ledgers. This maximum lifetime is not enforced -based on when an entry was created, but based on the current ledger. For example, if an entry is -created on January 1st, 2024, its lifetime could initially be bumped up to January 1st, 2025. -After this initial lifetime bump, if the entry received another lifetime bump later on January 10th, 2024, -the lifetime could be extended up to January 10th, 2025. - -# Operations - -## BumpFootprintExpirationOp - -### Semantics - -XDR: -``` -/* - Threshold: med - Result: BumpFootprintExpirationResult -*/ -struct BumpFootprintExpirationOp -{ - ExtensionPoint ext; - uint32 ledgersToExpire; -}; -``` - -`BumpFootprintExpirationOp` is a Soroban operation that will bump the expiration -ledger of the entries specified in the *read-only set of the footprint*. The -read-write set must be empty. The bump will make sure that the entries will not -expire before ledgersToExpire ledgers from now. - -Let's look at this example below. -``` -Ex. Last closed ledger (LCL) = 5, Current Ledger = 6, ledgersToExpire = 8 - -entry1.expirationLedger = 10 -entry2.expirationLedger = 14 -entry3.expirationLedger = 10000 - -entry1.expirationLedger will be updated to 14 so it will live for 8 more ledgers -after the current one closes and the entry can be accessed in ledgers [6, 14]. Note: This is going to be updated to count -Current Ledger, so it'll become [6, 13]. - -entry2 and entry3 will not be updated because they already have an -expirationLedger that is large enough. -``` - -### Transaction resources - -`BumpFootprintExpirationOp` is a Soroban operation, and therefore must be the -only operation in a transaction. The transaction also needs to populate -`SorobanTransactionData` transaction extension explained -[here](../fundamentals-and-concepts/invoking-contracts-with-transactions.mdx#transaction-resources). To fill -out `SorobanResources`, use preflight mentioned in the provided link, or make -sure `readBytes` includes the key and entry size of every entry in the -`readOnly` set and make sure `extendedMetaDataSizeBytes` is at least double of -`readBytes`. - - -## RestoreFootprintOp - -XDR: -``` -/* - Threshold: med - Result: RestoreFootprintOp -*/ -struct RestoreFootprintOp -{ - ExtensionPoint ext; -}; -``` - -`RestoreFootprintOp` is a Soroban operation that will restore expired entries -specified in the *read-write set of the footprint* and make them accessible -again. The read-only set of the footprint must be empty. An expired entry is one -where its expirationLedger is less than the current ledger number. - -The restored entry will have its expiration ledger bumped to the [minimums] the -network allows for newly created entries, which is 4096 + current ledger for -persistent entries, and 16 + current ledger for temporary entries (Note that -both will be updated soon to use 4096 + current ledger - 1 and 16 + current -ledger - 1). The minimums linked are what the settings will be on release, but -they can be updated in the future through a validator vote. - -[minimums]: https://github.com/stellar/stellar-core/blob/2109a168a895349f87b502ae3d182380b378fa47/src/ledger/NetworkConfig.h#L77-L78 -### Transaction resources - -`RestoreFootprintOp` is a Soroban operation, and therefore must be the only -operation in a transaction. The transaction also needs to populate -`SorobanTransactionData` transaction extension explained -[here](../fundamentals-and-concepts/invoking-contracts-with-transactions.mdx#transaction-resources). To fill -out `SorobanResources`, use preflight mentioned in the provided link, or make -sure `writeBytes` includes the key and entry size of every entry in the -`readWrite` set and make sure `extendedMetaDataSizeBytes` is at least double of -`writeBytes`. From ae6461d925c89ab22034c027d2f96893bcb6ec1a Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Thu, 20 Jul 2023 16:50:37 -0400 Subject: [PATCH 173/248] fix: move RPC doc out of Getting Started (#504) This seems like part of the RPC reference material, not an essential thing that someone needs to know as part of the "official onboarding tutorial," which is what Getting Started is supposed to be. --- docs/getting-started/run-rpc.mdx | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 docs/getting-started/run-rpc.mdx diff --git a/docs/getting-started/run-rpc.mdx b/docs/getting-started/run-rpc.mdx deleted file mode 100644 index c08b03da6..000000000 --- a/docs/getting-started/run-rpc.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_position: 9 -title: 6. Soroban RPC -description: Get an RPC Service ---- - -The RPC service allows you to communicate directly with Soroban via a [JSON RPC interface](https://soroban.stellar.org/api/). - -For example, you can build an application and have it [send a transaction](https://soroban.stellar.org/api/methods/sendTransaction), [get ledger](https://soroban.stellar.org/api/methods/getLedgerEntry) and [event data](https://soroban.stellar.org/api/methods/getEvents) or [simulate transactions](https://soroban.stellar.org/api/methods/simulateTransaction). - -Alternatively, you can use one of Soroban's [client SDKs](https://soroban.stellar.org/docs/category/sdks) such as the [js-soroban-client](https://soroban.stellar.org/docs/reference/sdks/js), which will need to communicate with an RPC instance to access the network. - -## Run Your Own Instance -[Download](https://hub.docker.com/r/stellar/quickstart) and run a local instance via [Docker Quickstart](https://github.com/stellar/quickstart) and run a [standalone] network or communicate with a live development [Futurenet] (and soon to come, Testnet and Mainnet). - -For local development, an RPC service can run on a standard laptop with 16GB of RAM and has minimal storage and CPU requirements. - -[standalone]: deploy-to-a-local-network.mdx -[Futurenet]: ../reference/futurenet.mdx - -## RPC Providers -Connect to available [hosted instances] for the community to use. - -[hosted instances]: ../reference/rpc-providers.mdx From 87681b11c9b59ba6da98199258d547d353db59de Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 21 Jul 2023 11:10:51 -0400 Subject: [PATCH 174/248] Format (#508) * package updates * cleaned up formatting --- docs/getting-started/deploy-to-futurenet.mdx | 3 +- docs/getting-started/hello-world.mdx | 2 +- docs/getting-started/storing-data.mdx | 35 ++++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 5d7072bad..5addf95b8 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -40,9 +40,10 @@ soroban contract deploy \ :::caution -The above command uses a futurenet soroban-rpc instance maintained by the Stellar Development Foundation. When interacting with the network in production you should run your own soroban-rpc or use a third party infrastructure provider. +The above command uses a futurenet soroban-rpc instance maintained by the Stellar Development Foundation. When interacting with the network in production you should run your own soroban-rpc or use a third party infrastructure provider. To run your own soroban-rpc locally, use the following command, and rpc-url `http://localhost:8000/soroban/rpc`: + ``` docker run --rm -it \ -p 8000:8000 \ diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 4828130fa..16b218230 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -360,7 +360,7 @@ This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/w The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] - + [oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2 [hello world example]: https://github.com/stellar/soroban-examples/tree/v0.9.2/hello_world diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 86cd88e2d..eec713102 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -88,11 +88,11 @@ Open the `increment/src/lib.rs` file to follow along. Contract data is associated with a key. The key is the value that can be used at a later time to lookup the value. -`Symbol` is a short (up to 32 characters long) string type with limited -character space (only `a-zA-z0-9_` characters are allowed). Identifiers like +`Symbol` is a short (up to 32 characters long) string type with limited +character space (only `a-zA-z0-9_` characters are allowed). Identifiers like contract function names are represented by `Symbol`s. -The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime. +The `symbol_short!()` macro is a convenient way to pre-compute short symbols up to 9 characters in length at compile time using `Symbol::short`. It generates a compile-time constant that adheres to the valid character set of letters (a-zA-Z), numbers (0-9), and underscores (\_). If a symbol exceeds the 9-character limit, `Symbol::new` should be utilized for creating symbols at runtime. ```rust const COUNTER: Symbol = symbol_short!("COUNTER"); @@ -143,7 +143,6 @@ env.storage().persistent().get(&EXAMPLE_KEY); // Returns Ok(1) env.storage().temporary().get(&EXAMPLE_KEY); // Returns Ok(2) ``` - ### Managing Contract Data Lifetimes The `Env.storage().storage_type().bump()` function is used to extend a contract data entry's lifetime inside a smart contract function. The `bump()` function is a conditional lifetime bump which @@ -255,22 +254,22 @@ Footprint: {"readOnly":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0 The general usage and interface is identical for all storage types. They differ only in fees and expiration behavior as follows: - `Temporary` - - Cheapest fees. - - Permanently deleted on expiration, cannot be restored. - - Suitable for time bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - - Unlimited amount of storage. + - Cheapest fees. + - Permanently deleted on expiration, cannot be restored. + - Suitable for time bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. + - Unlimited amount of storage. - `Instance` - - Most expensive fees (same price as `Persistent` storage). - - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. - - Shares the same lifetime as the contract instance. If the contract instance has not expired, instance data is guaranteed to be accessible and not expired. - - Limited amount of storage available. - - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). + - Most expensive fees (same price as `Persistent` storage). + - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. + - Shares the same lifetime as the contract instance. If the contract instance has not expired, instance data is guaranteed to be accessible and not expired. + - Limited amount of storage available. + - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). - `Persistent` - - Most expensive fees (same price as `Instance` storage). - - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. - - Does not share the same lifetime as the contract instance. If the contract instance is not expired, `Persistent` data may be expired and need to be restored before invoking the contract. - - Unlimited amount of storage. - - Suitable for user data that cannot be `Temporary` (i.e. balances). + - Most expensive fees (same price as `Instance` storage). + - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. + - Does not share the same lifetime as the contract instance. If the contract instance is not expired, `Persistent` data may be expired and need to be restored before invoking the contract. + - Unlimited amount of storage. + - Suitable for user data that cannot be `Temporary` (i.e. balances). For more detailed guidelines on how to use contract data, see [`Contract Data Best Practices`]. From d41f50e590790245c2a8ae9a3183559535b18459 Mon Sep 17 00:00:00 2001 From: Tyler van der Hoeven Date: Fri, 21 Jul 2023 11:20:44 -0400 Subject: [PATCH 175/248] add initial gh action (#507) * add initial gh action * fix links --------- Co-authored-by: Bri <92327786+briwylde08@users.noreply.github.com> --- docs/getting-started/storing-data.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index eec713102..014b7d545 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -292,6 +292,6 @@ soroban contract read --id 1 --key COUNTER ``` [`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[`BumpFootprintExpirationOp`]: ../getting-started/state-expiration#BumpFootprintExpirationOp -[`RestoreFootprintOp`]: ../getting-started/state-expiration#RestoreFootprintOp +[`BumpFootprintExpirationOp`]: ../fundamentals-and-concepts/state-expiration#BumpFootprintExpirationOp +[`RestoreFootprintOp`]: ../fundamentals-and-concepts/state-expiration#RestoreFootprintOp [`Contract Data Best Practices`]: ../fundamentals-and-concepts/persisting-data.mdx#contract-data-best-practices From 38a974b4b94fe28758fbb43781398eb355d66ead Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:52:33 -0400 Subject: [PATCH 176/248] Clean up Getting Started tutorial; add "Deploy to Futurenet" (#516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: move Freighter and Running RPC to Reference We want to keep the stuff in Getting Started hyper-focused on a quick end-to-end tour of Soroban. Now that there's a public RPC endpoint, it is much more straightforward to have people deploy contract right to it, rather than running their own nodes. Running your own node is a more advanced concept that dabblers need not muck with. So this moves both the "Deploy to a Local Network" and "Deploy to Futurenet" pages to the RPC page, in the Reference section. This required some reorganization & rework of the concepts to make it fit the new context. I also updated some instructions, such as teaching people to use `soroban config network` and `soroban config identity`, which were not included in the old "Deploy to…" pages. This commit also moves the "Connect Freighter Wallet" to Reference, since it's a bit in-the-weeds, which is a good feature for a Reference document but not for an end-to-end Tutorial. Coming Soon™: a new "Deploy Contracts" step in the Getting Started section, which uses the public RPC Futurenet endpoint. This will be followed by a "Create a Dapp" step, which will use the new JS Lib generation built into the CLI, and go over relevant Freighter details. * fix: clean up Hello World walk-through - explicitly instruct people to call it `hello-soroban` - move some single-use footnote-style links inline, to make them easier to see/understand/update later - remove spacing around tips for easier visual parsing - remove "Hello World Example" section, since this IS the Hello World example - remove unused & unneeded footnote-style link definitions - clean up example code so it doesn't give warnings on copy/paste * feat(getting-started): clean up Storing Data I'm working toward having people create a frontend Dapp with multiple contracts in a `contracts` folder, so I added a whole part at the beginning walking people through setting up a Cargo Workspace. This page also had more information than necessary about State Expiration; I moved this to the State Expiration doc, which had been practically blank. I reorganized this information somewhat; most notably, the "Best Practices" section had been practically empty. I moved some miscellaneous information to it; it should maybe be renamed "more information about state expiration" rather than "best practices", since it DOESN'T currently contain best practices, and I am not qualified to say what Best Practices might actually be. (Note that in the old version, the "Best Practices" section was blank! It was a misplaced heading, with nothing relevant below.) * fix: add missing "be" Co-authored-by: Willem Wyndham * feat: add 3. Deploy to Futurenet This contains the relevant details people will probably need to know when first getting started with Soroban. * fix: run prettier * feat: commit, summarize, save IDs to files Instructing people to commit to git will help them think about their work more clearly, and will also help them avoid mistakes and get better help when they need it. I also added summaries to each of these tutorial pages, to review what was learned and set up the next lesson. Finally, I decided to have them save contract IDs to files in their `.soroban` folder, rather than in more-ephemeral environment variables. This will make it easier to have them use `soroban contract bindings` in the "Build a Dapp" step, since they'll be able to reference these files in their package.json scripts. * fix: run lint --------- Co-authored-by: Willem Wyndham --- .../connect-freighter-wallet.mdx | 65 --- .../deploy-to-a-local-network.mdx | 100 ----- docs/getting-started/deploy-to-futurenet.mdx | 175 +++++--- docs/getting-started/hello-world.mdx | 109 ++--- docs/getting-started/storing-data.mdx | 374 ++++++++++-------- 5 files changed, 384 insertions(+), 439 deletions(-) delete mode 100644 docs/getting-started/connect-freighter-wallet.mdx delete mode 100644 docs/getting-started/deploy-to-a-local-network.mdx diff --git a/docs/getting-started/connect-freighter-wallet.mdx b/docs/getting-started/connect-freighter-wallet.mdx deleted file mode 100644 index bdb03c358..000000000 --- a/docs/getting-started/connect-freighter-wallet.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -sidebar_position: 6 -title: 4. Connect Freighter Wallet -description: Freighter is a browser extension that can sign Soroban transactions. ---- - -[Freighter](https://www.freighter.app/) is a browser extension wallet provided by the Stellar Development Foundation. It provides users a way to interact with Soroban tokens directly from the web browser. - -## Setup - -1. Install the Freighter browser extension. - -2. Create a keypair or import an existing account using a mnemonic phrase to complete setup. - -3. Next, switch to `Experimental Mode` to enable the Soroban SDK. In the extension, click the gear in the lower right corner and then navigate to `Preferences`. Toggle on `Experimental Mode`. - -4. After switching to `Experimental Mode`, you should automatically be switched to the Futurenet network. Fund your account on Futurenet using Friendbot. For convenience, you can do so in the Stellar [Laboratory](https://laboratory.stellar.org/#account-creator?network=futurenet). - -## Enable Soroban Tokens - -With a funded Futurenet account and `Experimental Mode` enabled, you can now add Soroban tokens to your Freighter wallet. - -1. On the Freighter account screen, click this `Manage Assets` button at the bottom of the screen. - -2. You will now see a button to `Add Soroban token` at the bottom of the screen. Click this `Add Soroban token` button. - -3. On the next screen, enter the Token ID of the token you want to add to Freighter and click `Add New Token`. - -4. You will now see your token's balance on Freighter's account page. Clicking on the balance will show a history of payments sent using this token. - -## Send Token Payments - -Once you have added a Soroban token to your Freighter wallet, you can now send a payment of that token directly from Freighter. - -1. On the Freighter account screen, click the `Send Payment` icon in the upper right of the screen. - -2. Enter a recipient public key. Click `Continue`. - -3. Select your token from the asset dropdown at the bottom of the screen and enter a token amount. Click `Continue`. - -4. Enter a memo (optional). Click `Review Send`. - -5. Review the details of your payment. Click `Send`. - -## Sign Soroban XDRs - -With a funded Futurenet account and `Experimental Mode` enabled, you can now sign Soroban XDRs using dApps that are integrated with Freighter. An example of an integrated dApp is Stellar's [Laboratory](https://laboratory.stellar.org/#txsigner?network=futurenet). - -1. On the Lab's transaction signer, enter a Soroban XDR into the form field. - -2. Click `Sign with Freighter`. - -3. Freighter will open with the details of the XDR. Click `Approve` to sign or `Reject` to dismiss without a signature. - -4. If approved, Freighter will transmit a signed XDR back to the Lab. - -## As a dApp Provider, Prompt Freighter to Sign Transactions (Advanced) - -If you're building a JS dApp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): - -1. Follow the setup instructions above. - -2. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dApp to sign Soroban XDRs using the account in Freighter. - -3. Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dApp. diff --git a/docs/getting-started/deploy-to-a-local-network.mdx b/docs/getting-started/deploy-to-a-local-network.mdx deleted file mode 100644 index c55bdbe96..000000000 --- a/docs/getting-started/deploy-to-a-local-network.mdx +++ /dev/null @@ -1,100 +0,0 @@ ---- -sidebar_position: 5 -title: 3. Deploy to a Local Network -description: Use Docker and the Stellar Quickstart image to run a local network. ---- - -If you have Docker installed, you can run a local standalone network with the [Stellar Quickstart] Docker image. - -The Quickstart image is a single container that runs everything you need to test against a fully featured network. It contains: - -- Stellar Core – Node software that runs the network, coordinates consensus, and finalizes ledgers. -- Soroban RPC server – JSON RPC server for interacting with Soroban contracts. -- Horizon server – HTTP API for access ledger state and historical transactions. -- Friendbot server – HTTP API for creating and funding new accounts on test networks. - -:::info - -It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. - -::: - -To run a local standalone network with the Stellar Quickstart Docker image, run the following command. - -```sh -docker run --rm -it \ - -p 8000:8000 \ - --name stellar \ - stellar/quickstart:soroban-dev@sha256:ed57f7a7683e3568ae401f5c6e93341a9f77d8ad41191bf752944d7898981e0c \ - --standalone \ - --enable-soroban-rpc -``` - -Once the image is started you can check its status by querying the Horizon API: - -```sh -curl http://localhost:8000 -``` - -Generate a key for use on the local sandbox environment by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. - -:::tip - -It's a good practice to never use the same keys for testing and development that you use do for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. - -::: - -Create an account on the local sandbox environment by making a request to the local Friendbot. Specify as the `addr` the `G...` key of your account. - -```sh -curl "http://localhost:8000/friendbot?addr=G..." -``` - -Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. - -```sh -soroban contract deploy \ - --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ - --source S... \ - --rpc-url http://localhost:8000/soroban/rpc \ - --network-passphrase 'Standalone Network ; February 2017' -``` - -:::tip - -It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. - -::: - -A contract ID will be outputted. - -``` -cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 -``` - -Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. - -```sh -soroban contract invoke \ - --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ - --source S... \ - --rpc-url http://localhost:8000/soroban/rpc \ - --network-passphrase 'Standalone Network ; February 2017' \ - -- \ - hello \ - --to friend -``` - -The following output should appear. - -```json -["Hello", "friend"] -``` - -[Write a Contract]: hello-world#write-a-contract -[Run on a Local Network]: run-on-local-network -[Build]: hello-world#build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test -[Run on Sandbox]: hello-world#run-on-sandbox -[Stellar Quickstart]: https://github.com/stellar/quickstart diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index 5addf95b8..bed9fedfb 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -1,95 +1,156 @@ --- -sidebar_position: 7 -title: 5. Deploy to Futurenet -description: Use Docker and the Stellar Quickstart image to deploy to the live test network. +sidebar_position: 4 +title: 3. Deploy to Futurenet +description: Deploy your contract to Soroban's Futurenet network and interact with it. --- -If you have Docker installed, you can run a local node with the [Stellar Quickstart] Docker image that joins the [Futurenet] network, and then use that local node to deploy. +You've built two simple contracts and run them locally in Sandbox. Now you can deploy them to a network. -[Futurenet]: ../reference/futurenet +Soroban has a test network called Futurenet that you can use to deploy and test your contracts. Soon Soroban will also have a test network called Testnet, which will have stronger guarantees around data persistence, but you'll still be able to use Futurenet for testing the latest Soroban features. -:::info +## Configure Futurenet in your CLI -It's also possible to run a contract in the local sandbox environment without a network using just the [`soroban-cli`]. See [Run on Sandbox] for more details. +The first step toward deploying to Futurenet is to configure your CLI to use it. You can do this by running the following command: -::: + soroban config network add --global futurenet \ + --rpc-url https://rpc-futurenet.stellar.org:443 \ + --network-passphrase "Test SDF Future Network ; October 2022" + +Note the `--global`. This creates a file in your home folder's `/.config/soroban/network/futurenet.toml` with the settings you specified. This +means that you can use the `--network futurenet` flag in any Soroban CLI command to use this network. + +If you want project-specific network configurations, you can omit the `--global` flag, and the networks will be added to your working directory's `.soroban/network` folder instead. + +## Configure an Identity + +So far when using Sandbox, you haven't needed to consider _who_ is sending the transactions. But when you deploy to a network, you need to specify an identity that will be used to sign the transactions. + +Let's configure an identity called `alice`. You can use any name you want, but it might be nice to have some named identities that you can use for testing, such as [`alice`, `bob`, and `carol`](https://en.wikipedia.org/wiki/Alice_and_Bob). + + soroban config identity generate --global alice + +You can see the public key of `alice` with: + + soroban config identity address alice -Generate a key by going to the [Stellar Laboratory]. Make note of both the `G...` and `S...` keys. The `G...` key is the public key and will also be the account ID. The `S...` key is the secret key and is that you use to control the account. +Like the Network configs, the `--global` means that the identity gets stored in `~/.config/soroban/identity/alice.toml`. You can omit the `--global` flag to store the identity in your project's `.soroban/identity` folder instead. -:::tip +All this did so far is generate a public/private keypair on your local machine. No network requests were made, and `alice` has no funds on Futurenet. This means that you can't make any transactions with `alice` yet. -It's a good practice to never use the same keys for testing and development that you use for the public Stellar network. Generate new keys for testing and development and avoid ever using them for other purposes. +To get `alice` some Futurenet tokens, you'll need to use [Friendbot](https://developers.stellar.org/docs/fundamentals-and-concepts/testnet-and-pubnet#friendbot). All Stellar and Soroban test networks have a Friendbot that you can use to get some test tokens. The public Friendbot instance for Futurenet lives at `friendbot-futurenet.stellar.org`. Use it: + curl "https://friendbot-futurenet.stellar.org/?addr=$(soroban config identity address alice)" + +:::tip Command Expansion `$(…)` +This uses [command expansion](https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html), which only works with bash-compatible shells. If you are using Windows or some other shell, you will need to copy the output of `soroban config…` and paste it into the `curl` command, or figure out how command expansion works in your shell. ::: -Create an account on the [Futurenet] network by making a request to the Friendbot. Specify as the `addr` the `G...` key of your account. +## Deploy -```sh -curl "https://friendbot-futurenet.stellar.org/?addr=G..." -``` +Now you can deploy your Hello World contract: -Once you have an account on the network, we'll use the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build] as our contract to deploy. Run the following commands to deploy the contract to the network. Use the `S...` key as the secret key. + soroban contract deploy \ + --wasm target/wasm32-unknown-unknown/release/hello_soroban.wasm \ + --source alice \ + --network futurenet -```sh -soroban contract deploy \ - --wasm target/wasm32-unknown-unknown/release/[project-name].wasm \ - --source S... \ - --rpc-url https://rpc-futurenet.stellar.org:443 \ - --network-passphrase 'Test SDF Future Network ; October 2022' +This returns the ID of the contract, starting with a `C`. Let's put it somewhere semi-permanent so we can use it later. Copy that value and: + +```bash +echo "C…" > .soroban/hello-id ``` -:::caution +You may need to create the `.soroban` folder first with `mkdir .soroban`. -The above command uses a futurenet soroban-rpc instance maintained by the Stellar Development Foundation. When interacting with the network in production you should run your own soroban-rpc or use a third party infrastructure provider. +## Interact -To run your own soroban-rpc locally, use the following command, and rpc-url `http://localhost:8000/soroban/rpc`: +This should look a lot like interacting with the contract in the Sandbox, as you did in [1. Hello World](./hello-world.mdx). Only now the contract lives on the Futurenet network, and the CLI is making [RPC](../reference/rpc.mdx) calls in the background. Let's try it: +```bash +soroban contract invoke \ + --id $(cat .soroban/hello-id) \ + --source alice \ + --network futurenet \ + -- \ + --help ``` -docker run --rm -it \ - -p 8000:8000 \ - --name stellar \ - stellar/quickstart:soroban-dev@sha256:ed57f7a7683e3568ae401f5c6e93341a9f77d8ad41191bf752944d7898981e0c \ - --futurenet \ - --enable-soroban-rpc + +This again makes use of command expansion `$(…)`; see the note about that above. + +This looks a lot like interacting with the contract back in [1. Hello World](./hello-world.mdx), but rather than using a `--wasm` flag to point to a local wasm file, you now specify the `--network` and the `--source`. That's it! You can try calling `hello` as before: + +```bash +soroban contract invoke \ + --id $(cat .soroban/hello-id) \ + --source alice \ + --network futurenet \ + -- \ + hello \ + --to RPC ``` -::: +## Two-step deployment -:::tip +It's worth knowing that `deploy` is actually a two-step process. -It's good practice to avoid entering secret keys on the command line. You can also specify the secret key by setting the environment variable `SOROBAN_SECRET_KEY`. The [`soroban-cli`] is still in development and in the future there will be other secure ways to provide a secret key, such as via hardware keys. +1. Upload the contract bytes to the network. Soroban currently refers to this as _installing_ the contract—from the perspective of the blockchain itself, this is a reasonable metaphor. This uploads the bytes of the contract to the network, indexing it by its hash. This contract code can now be referenced by multiple contracts, which means they would have the exact same _behavior_ but separate storage state. -::: +2. Instantiate the contract. This actually creates what you probably think of as a Smart Contract. It makes a new contract ID, and associates it with the contract bytes that were uploaded in the previous step. -A contract ID will be outputted. +You can run these two steps separately. Let's try it with the Incrementor contract: +```bash +soroban contract install \ + --network futurenet \ + --source alice \ + --wasm target/wasm32-unknown-unknown/release/incrementor.wasm ``` -cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 + +This returns the hash of the Wasm bytes. Now you can use `--wasm-hash` with `deploy` rather than `--wasm`. Let's also automatically pipe the returned contract ID into a file in the `.soroban` directory, so that when you search your command history and reuse the deploy command in the future, you don't forget that step (you might want to go back and do something similar with the Hello World deploy, too): + +```bash +soroban contract deploy \ + --wasm-hash [paste the output from the last command] \ + --source alice \ + --network futurenet \ + > .soroban/incrementor-id ``` -Using the contract ID that was outputted, use the [`soroban-cli`] to invoke the `hello` function with a single argument `friend`. +You can check that it saved the contract ID correctly: -```sh -soroban contract invoke \ - --id cd4dae2c409c433b1e1d83994a20214d3e5f60bdd3a817978d8aa7c797864313 \ - --source S... \ - --rpc-url https://rpc-futurenet.stellar.org:443 \ - --network-passphrase 'Test SDF Future Network ; October 2022' \ - -- \ - hello \ - --to friend +```bash +cat .soroban/incrementor-id ``` -The following output should appear. +Now you can interact with it over RPC like you did with the Hello World contract: -```json -["Hello", "friend"] +```bash +soroban contract invoke \ + --id $(cat .soroban/incrementor-id) \ + --source alice \ + --network futurenet \ + -- \ + increment ``` -[Write a Contract]: hello-world#write-a-contract -[Run on a Local Network]: run-on-local-network -[Build]: hello-world#build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[Stellar Laboratory]: https://laboratory.stellar.org/#account-creator?network=test -[Run on Sandbox]: hello-world#run-on-sandbox -[Stellar Quickstart]: https://github.com/stellar/quickstart +## Run your own network/node + +Sometimes you'll need to run your own node: + +- Production apps! It's a bad idea to rely on the public, Stellar-maintained Soroban RPC endpoint. Instead, you should run your own node, and point your app at that. +- When you need a network that differs from the version deployed to Futurenet. + +The Soroban team maintains Docker containers that makes this as straightforward as possible. See the [RPC](../reference/rpc.mdx) reference for details. + +## Summary + +In this lesson, we learned how to: + +- configure networks and identities using Soroban CLI +- fund accounts on test networks using Friendbot +- deploy contracts to a test network +- interact with deployed contracts + +You shouldn't have any changes to commit to git, because we didn't change any code in this lesson! + +Up next, we'll use the deployed contracts to build a simple web app. diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 16b218230..83b4a438f 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 2 title: 1. Hello World description: Create your first Soroban contract. --- @@ -7,23 +7,21 @@ description: Create your first Soroban contract. import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -Once you've [Setup] your development environment, you're ready to create your first Soroban contract. - -[Setup]: setup.mdx +Once you've [Setup](./setup.mdx) your development environment, you're ready to create your first Soroban contract. ## Create New Project Create a new Rust library using the `cargo new` command. ```sh -cargo new --lib [project-name] +cargo new --lib hello-soroban ``` Open the `Cargo.toml`, it should look something like this: ```toml title="Cargo.toml" [package] -name = "project-name" +name = "hello-soroban" version = "0.1.0" edition = "2021" ``` @@ -164,6 +162,7 @@ Contract inputs must not be references. ```rust #[contract] pub struct Contract; + #[contractimpl] impl Contract { pub fn hello(env: Env, to: Symbol) -> Vec { @@ -185,6 +184,8 @@ pub struct Contract; #[contractimpl] impl Contract { + /// Say Hello to someone or something. + /// Returns a length-2 vector/array containing 'Hello' and then the value passed as `to`. pub fn hello(env: Env, to: Symbol) -> Vec { vec![&env, symbol_short!("Hello"), to] } @@ -222,10 +223,10 @@ mod test; ```rust use crate::{Contract, ContractClient}; -use soroban_sdk::{vec, Env, Symbol, symbol_short}; +use soroban_sdk::{symbol_short, vec, Env}; #[test] -fn test() { +fn hello() { let env = Env::default(); let contract_id = env.register_contract(None, Contract); let client = ContractClient::new(&env, &contract_id); @@ -295,39 +296,32 @@ To build a Soroban contract to deploy or run, use the `soroban contract build` c soroban contract build ``` -:::tip - -Use the `release` profile outlined in [Configure the Release Profile], otherwise the contract will exceed Soroban's size limits. +This is a small wrapper around `cargo build` that sets the target to `wasm32-unknown-unknown` and the profile to `release`. You can think of it as a shortcut for the following command: -::: +```sh +cargo build --target wasm32-unknown-unknown --release +``` A `.wasm` file will be outputted in the `target` directory. The `.wasm` file is the built contract. ``` -target/wasm32-unknown-unknown/release/[project-name].wasm +target/wasm32-unknown-unknown/release/hello_soroban.wasm ``` -The `.wasm` file contains the logic of the contract, as well as the contract's specification that can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. - -:::tip - -To further optimize builds to be as small as possible, see [Optimizing Builds]. +The `.wasm` file contains the logic of the contract, as well as the contract's [specification / interface types](../fundamentals-and-concepts/fully-typed-contracts.mdx), which can be imported into other contracts who wish to call it. This is the only artifact needed to deploy the contract, share the interface with others, or integration test against the contract. +:::tip Optimize Builds +To further optimize builds to be as small as possible, see [Optimizing Builds](#optimizing-builds). ::: -[Configure the Release Profile]: #configure-the-release-profile -[Optimizing Builds]: #optimizing-builds - ## Run on Sandbox -If you have the [`soroban-cli`] installed, you can run contracts in a local sandbox environment. +If you have [`soroban-cli`] installed, you can run contracts in a local sandbox environment. The Soroban sandbox environment is the same Soroban environment that runs on Stellar networks, but it runs without nodes, and without the other features you find on a Stellar network. :::info - -It's also possible to run a contract on a fully featured local network. See [Deploy to a Local Network] for more details. - +It's also possible to run a contract on a fully featured local network. See [the RPC Reference page](../reference/rpc.mdx) for more details. ::: Using the code we wrote in [Write a Contract] and the resulting `.wasm` file we built in [Build], run the following command to invoke the `hello` function. Here we're setting the `to` argument to `friend`: @@ -348,40 +342,67 @@ The following output should appear. ``` :::info The `--` double-dash is required! +This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean) used by other commands like [cargo run](https://doc.rust-lang.org/cargo/commands/cargo-run.html). Everything after the `--`, sometimes called [slop](https://github.com/clap-rs/clap/issues/971), is passed to a child process. In this case, `soroban contract invoke` builds an _implicit CLI_ on-the-fly for the `hello` method in your contract. It can do this because Soroban SDK embeds your contract's schema / interface types right in the `.wasm` file that gets deployed on-chain. You can also try: -This is a general [CLI pattern](https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean) used by other commands like [cargo run](https://doc.rust-lang.org/cargo/commands/cargo-run.html). Everything after the `--`, sometimes called [slop](https://github.com/clap-rs/clap/issues/971), is passed to a child process. In this case, `soroban contract invoke` builds an _implicit CLI_ on-the-fly for the `hello` method in your contract. It can do this because Soroban SDK embeds your contract's schema / interface types right in the `.wasm` file that gets deployed on-chain. Try this, too: + soroban contract invoke ... -- --help + +and soroban contract invoke ... -- hello --help ::: -## Hello World Example - -The [hello world example] demonstrates how to write a simple contract, with a single function that takes one input and returns it as an output. - -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] +## Optimizing Builds -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2 -[hello world example]: https://github.com/stellar/soroban-examples/tree/v0.9.2/hello_world +Use `soroban contract optimize` to further minimize the size of the `.wasm`. First, re-install soroban-cli with the `opt` feature: -## Optimizing Builds + cargo install --locked --version 0.9.1 soroban-cli --features opt -Use `soroban contract optimize` to further minimize the size of the `.wasm`. +Then build an optimized `.wasm` file: -```sh -soroban contract optimize \ - --wasm target/wasm32-unknown-unknown/release/first_project.wasm -``` + soroban contract optimize \ + --wasm target/wasm32-unknown-unknown/release/hello_soroban.wasm -This will optimize and output a new `first_project.optimized.wasm` file in the same location as the input `.wasm`. +This will optimize and output a new `hello_soroban.optimized.wasm` file in the same location as the input `.wasm`. :::tip - Building optimized contracts is only necessary when deploying to a network with fees or when analyzing and profiling a contract to get it as small as possible. If you're just starting out writing a contract, these steps are not necessary. See [Build] for details on how to build for development. - ::: [Write a Contract]: #write-a-contract -[Deploy to a Local Network]: deploy-to-a-local-network [Build]: #build -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli + +## Commit to version control + +Now that everything's working, this is a great time to commit your code to version control. Even if you don't share your project with others, this will make it easier for you to see and understand your own changes throughout the rest of the tutorial. + +Go ahead and initialize `hello-soroban` as a git repository: + +```bash +git init +``` + +You'll need a `.gitignore` to tell git to ignore the `target` directory: + +```bash +echo target >> .gitignore +``` + +You should also ignore the `.soroban` directory: + +```bash +echo .soroban >> .gitignore +``` + +Now you can make your initial commit: + +```bash +git add . +git commit -m "Initial commit: hello-soroban contract" +``` + +## Summary + +In this section, we wrote a simple contract that can be deployed to a Soroban network. We also learned how to run the contract locally using the Soroban sandbox environment. + +Next we'll add a new contract to this project, reorganizing the project as a multi-contract project using Cargo Workspaces. The new contract will show off a little bit of Soroban's storage capabilities. diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 014b7d545..8c88ddb6f 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -1,87 +1,184 @@ --- -sidebar_position: 4 +sidebar_position: 3 title: 2. Storing Data description: Write a simple Soroban contract that stores and retrieves data. --- -The [increment example] demonstrates how to write a simple contract that stores data, with a single function that increments an internal counter and returns the value. +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; -[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)][oigp] -[oigp]: https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2 +Now that we've built a basic Hello World example to see the rough structure of Soroban contracts, we'll write a simple contract that stores and retrieves data. This will help you see the basics of Soroban's storage system. We'll also organize the two contracts as one combined project using a Cargo Workspace, which is a common pattern for Soroban projects. -[increment example]: https://github.com/stellar/soroban-examples/tree/v0.9.2/increment +This is going to follow along with the [increment example](https://github.com/stellar/soroban-examples/tree/v0.9.2/increment), which has a single function that increments an internal counter and returns the value. If you want to see a working example, [try it in +GitPod](https://gitpod.io/#https://github.com/stellar/soroban-examples/tree/v0.9.2). -## Run the Example +This tutorial assumes that you've already completed the previous steps in Getting Started: [Setup](./setup.mdx) and [Hello World](./hello-world.mdx). -First go through the [Setup] process to get your development environment configured, then clone the `v0.9.2` tag of `soroban-examples` repository: +## Setting up a multi-contract project -[Setup]: setup.mdx +Many Soroban projects need more than one contract. Cargo makes this easy with workspaces, though it doesn't yet give a way to initialize a new project as a workspace (see [#8365](https://github.com/rust-lang/cargo/issues/8365)). Let's set it up manually. +Rather than just a `hello-soroban` folder, we want a new `soroban-tutorial` folder with a `contracts` folder inside, into which we'll move the existing `hello-soroban` project. As a diff, we want this: + +```diff +-hello-soroban ++soroban-tutorial/contracts/hello-soroban ``` -git clone -b v0.9.2 https://github.com/stellar/soroban-examples + +So change into the parent directory of `hello-soroban` and: + +```bash +mkdir -p soroban-tutorial/contracts +mv hello-soroban soroban-tutorial/contracts +cd soroban-tutorial ``` -Or, skip the development environment setup and open this example in [Gitpod][oigp]. +You're going to want some Rust and Cargo stuff in different spots. From the new project root, run: + +```bash +rm contracts/hello-soroban/Cargo.lock +mv contracts/hello-soroban/target . +cp contracts/hello-soroban/Cargo.toml . +``` + +Note that we copied the Cargo.toml file. That's because we're going to need some of it in the root and some of it in the subdirectory. + +In the root `Cargo.toml`: -To run the tests for the example, navigate to the `increment` directory, and use `cargo test`. +- remove the `[package]`, `[lib]`, `[features]`, and `[dev_dependencies]` sections +- keep the `[release.*]` stuff +- replace the line `[dependencies]` with `[workspace.dependencies]` +- add a `[workspace]` section +In the project-specific `Cargo.toml`, keep roughly the opposite sections, and use the dependency versions as specified in the workspace root. It all ends up looking like this: + + + + +```toml +[workspace] +resolver = "2" +members = [ + "contracts/*", +] + +[workspace.dependencies] +soroban-sdk = "0.9.2" + +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true ``` -cd increment -cargo test -- --nocapture + + + + +```toml +[package] +name = "hello-soroban" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +soroban-sdk = { workspace = true } + +[dev_dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } + +[features] +testutils = ["soroban-sdk/testutils"] ``` -You should see the output: + + + +Now make sure everything works: + + soroban contract build + +Everything should build. + + cargo test + +All tests should pass. +## Code + +Rather than initializing this contract with `cargo new`, let's copy the `hello-soroban` project: + +```bash +cp -r contracts/hello-soroban contracts/incrementor ``` -running 1 test -count: U32(0) -count: U32(1) -count: U32(2) -test test::test ... ok + +You'll need to update the `Cargo.toml` file to reflect the correct name: + +```diff title="contracts/incrementor/Cargo.toml" + [package] +-name = "hello-soroban" ++name = "incrementor" + version = "0.1.0" + edition = "2021" ``` -## Code +And now in `contracts/incrementor/src/lib.rs`, we'll replace the contents with the following: -```rust title="increment/src/lib.rs" +```rust title="contracts/incrementor/src/lib.rs" #![no_std] -use soroban_sdk::{contract, contractimpl, symbol_short, vec, Env, Symbol, Vec, log}; +use soroban_sdk::{contract, contractimpl, log, symbol_short, Env, Symbol}; const COUNTER: Symbol = symbol_short!("COUNTER"); #[contract] -pub struct IncrementContract; +pub struct IncrementorContract; #[contractimpl] -impl IncrementContract { - /// Increment increments an internal counter, and returns the value. +impl IncrementorContract { + /// Increment an internal counter; return the new value. pub fn increment(env: Env) -> u32 { - // Get the current count. - let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0); // If no value set, assume 0. - log!(&env, "count: {}", count); + let mut count: u32 = env.storage().instance().get(&COUNTER).unwrap_or(0); - // Increment the count. count += 1; - // Save the count. + log!(&env, "count: {}", count); + env.storage().instance().set(&COUNTER, &count); - // The contract instance will be bumped to have a lifetime of at least 100 ledgers. - // If the lifetime is already more than 100 ledgers, this is a no-op. Otherwise, - // the lifetime is extended to 100 ledgers. This lifetime bump includes the contract - // instance itself and all entries in storage().instance(), i.e, COUNTER. env.storage().instance().bump(100); - // Return the count to the caller. count } } + +#[cfg(test)] +mod test; ``` -Ref: https://github.com/stellar/soroban-examples/tree/v0.9.2/increment +Make sure it builds: + + soroban contract build + +Check that it built: + + ls target/wasm32-unknown-unknown/release/*.wasm + +You should see both `hello_soroban.wasm` and `incrementor.wasm`. ## How it Works -Open the `increment/src/lib.rs` file to follow along. +Follow along in your `contracts/incrementor/src/lib.rs` file. ### Contract Data Keys @@ -98,18 +195,9 @@ The `symbol_short!()` macro is a convenient way to pre-compute short symbols up const COUNTER: Symbol = symbol_short!("COUNTER"); ``` -### Types of Contract data - -Contract data is made up of three different types: `Persistent`, `Temporary`, and `Instance`. All contract data has a "lifetime" that must be periodically bumped. If an entry's -lifetime is not periodically bumped, the entry will eventually reach the end of its lifetime and "expire". Each type of storage functions similarly, but have different fees and expiration behavior. Whenever a -`Temporary` entry expires, it is deleted from the ledger and is permanently inaccessible. Whenever a `Persistent` or `Instance` entry expires, it is inaccessible, but can be -"restored" and used again via the [`RestoreFootprintOp`]. As a general rule, `Temporary` storage should only be used for data that can be easily recreated or is only valid for a period -of time, where `Persistent` or `Instance` storage should be used for data that can not be recreated and should kept permanently, such as a user's token balance. For more information -about the different storage types, see [Contract Data Type Descriptions](#Contract-Data-Type-Descriptions). - ### Contract Data Access -The `Env.storage()` function is used to retrieve access and update a counter. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data. +The `Env.storage()` function is used to access and update contract data. The executing contract is the only contract that can query or modify contract data that it has stored. The data stored is viewable on ledger anywhere the ledger is viewable, but contracts executing within the Soroban environment are restricted to their own data. The `get()` function gets the current value associated with the counter key. @@ -123,54 +211,68 @@ let mut count: u32 = env If no value is currently stored, the value given to `unwrap_or(...)` is returned instead. -Values stored as contract data and retrieved are transmitted from the environment and expanded into the type specified. In this case a `u32`. If the value can be expanded the type returned will be an `Ok(u32)`, otherwise the type returned will be an `Err(_)`. The final `unwrap()` in the above code snippet is assuming the value will always be a `u32`. If a developer caused it to be some other type a panic would occur at the unwrap. +Values stored as contract data and retrieved are transmitted from [the environment](../fundamentals-and-concepts/environment-concepts.mdx) and expanded into the type specified. In this case a `u32`. If the value can be expanded, the type returned will be a `u32`. Otherwise, if a developer caused it to be some other type, a panic would occur at the unwrap. The `set()` function stores the new count value against the key, replacing the existing value. -```rust -env.storage().instance().set(&COUNTER, count); -``` +### Managing Contract Data Lifetimes with `bump()` -To access a given type of storage, use `Env.storage().persistent()`, `Env.storage().temporary()`, and `Env.storage().instance()`. -Each storage type is in a separate key space. To demonstrate this, see the code snippet below: +All contract data has a "lifetime" that must be periodically bumped. If an +entry's lifetime is not periodically bumped, the entry will eventually reach the end of its lifetime and "expire". You can learn more about this in the [State Expiration](../fundamentals-and-concepts/state-expiration.mdx) document. -```rust -const EXAMPLE_KEY: Symbol = symbol_short!("KEY"); -env.storage().persistent().set(&EXAMPLE_KEY, 1); -env.storage().temporary().set(&EXAMPLE_KEY, 2); +For now, it's worth knowing that there are three kinds of storage: +`Persistent`, `Temporary`, and `Instance`. This contract only uses `Instance` storage: `env.storage().instance()`. Every time the counter is incremented, this storage gets bumped by 100 [ledgers](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/ledgers), or about 500 seconds. -env.storage().persistent().get(&EXAMPLE_KEY); // Returns Ok(1) -env.storage().temporary().get(&EXAMPLE_KEY); // Returns Ok(2) -``` +## Run on Sandbox -### Managing Contract Data Lifetimes +Let's invoke this contract the same way we invoked the Hello World contract. We'll use `--id 2`, since we already used `--id 1` for the Hello World contract. For Sandbox, these values are stored in a `.soroban/ledger.json` file in the current directory; you can always remove this file to reset the ledger. -The `Env.storage().storage_type().bump()` function is used to extend a contract data entry's lifetime inside a smart contract function. The `bump()` function is a conditional lifetime bump which -extends an entry's lifetime up to a given length of time, measured in ledgers. + soroban contract invoke \ + --wasm target/wasm32-unknown-unknown/release/incrementor.wasm \ + --id 2 \ + -- \ + increment -```rust -env.storage().instance().bump(100); -``` +You should see the following output: + + 1 + +Rerun the invoke with the `--footprint` option to view the [footprint](../fundamentals-and-concepts/persisting-data.mdx#footprints-and-parallel-contention) of the invocation, which is the ledger entries that the contract will read or write to. -This call to `bump()` ensures that the current lifetime of the contract instance entry is at least 100 ledgers. If this is called and the contract instance entry has a current lifetime of 50 ledgers, -the lifetime will be extended up to 100 ledgers. If this is called and the contract instance entry has a current lifetime of 150 ledgers, the lifetime will not be extended and the `bump()` call is a no-op. + soroban contract invoke \ + --wasm target/wasm32-unknown-unknown/release/incrementor.wasm \ + --id 2 \ + --footprint \ + -- \ + increment -All `Instance` storage is stored in a single contract instance `LedgerEntry` and shares a single lifetime. This means that one call to `Env.storage().instance().bump()` will extend the lifetime of all `Instance` -entries, as well as the contract instance itself. For `Temporary` and `Persistent` storage, each entry has its own lifetime and must be bumped individually. The interface is slightly different and takes the key -of the entry being bumped as well as the new lifetime. +You should see: -In addition to contract defined lifetime extensions using the `bump()` function, a contract data entry's lifetime can be extended via the [`BumpFootprintExpirationOp`] operation. + Footprint: {"readOnly":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"static":"ledgerKeyContractCode"}}}],"readWrite":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"symbol":[67,79,85,78,84,69,82]}}}]} + +:::info Footprint formats are unstable +Soroban is a pre-release and at this time outputs footprints in an unstable JSON format. +::: + +Run it without the `--footprint` a few more times to watch the count change. + +Use `contract read` to inspect what the full storage looks like after a few runs. + + soroban contract read --id 1 --key COUNTER ## Tests -Open the `increment/src/test.rs` file to follow along. +Open the `contracts/increment/src/test.rs` file and replace the contents with: + +```rust title="contracts/incrementor/src/test.rs" +use crate::{IncrementorContract, IncrementorContractClient}; +use soroban_sdk::Env; -```rust title="increment/src/test.rs" #[test] -fn test() { +fn increment() { let env = Env::default(); - let contract_id = env.register_contract(None, IncrementContract); - let client = IncrementContractClient::new(&env, &contract_id); + let contract_id = env.register_contract(None, IncrementorContract); + let client = IncrementorContractClient::new(&env, &contract_id); assert_eq!(client.increment(), 1); assert_eq!(client.increment(), 2); @@ -178,120 +280,46 @@ fn test() { } ``` -In any test the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in. +This uses the same concepts described in the Hello World example. -```rust -let env = Env::default(); -``` +Make sure it passes: -The contract is registered with the environment using the contract type. + cargo test -```rust -let contract_id = env.register_contract(None, IncrementContract); -``` - -All public functions within an `impl` block that is annotated with the `#[contractimpl]` attribute have a corresponding function generated in a generated client type. The client type will be named the same as the contract type with `Client` appended. For example, in our contract the contract type is `IncrementContract`, and the client is named `IncrementContractClient`. - -```rust -let client = IncrementContractClient::new(&env, &contract_id); -``` +You'll see that this runs tests for the whole workspace; both the Hello World contract and the new Incrementor. -The values returned by functions can be asserted on: +If you want to see the output of the `log!` call, run the tests with `--nocapture`: -```rust -assert_eq!(client.increment(), 1); ``` - -## Build the Contract - -To build the contract, use the `soroban contract build` command. - -```sh -soroban contract build +cargo test -- --nocapture ``` -A `.wasm` file should be outputted in the `target` directory: +You should see the output: ``` -target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm +running 1 test +count: U32(0) +count: U32(1) +count: U32(2) +test test::incrementor ... ok ``` -## Run the Contract - -If you have [`soroban-cli`] installed, you can invoke contract functions in the Wasm using it. - -```sh -soroban contract invoke \ - --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ - --id 1 \ - -- \ - increment -``` +## Take it further -The following output should occur using the code above. +Can you figure out how to add `get_current_value` function to the contract? What about `decrement` or `reset` functions? -``` -1 -``` +## Commit your changes -Rerun the invoke with the `--footprint` option to view the [footprint] of the invocation, which is the ledger entries that the contract will have read or written to. +Looking at your git diff will be interesting now. It's probably kind of noisy if you just run `git status` or `git diff` right away, but once you `git add .`, git will understand the _renames_ (aka "moves") of all the old `hello-soroban` files better. -```sh -soroban contract invoke \ - --wasm target/wasm32-unknown-unknown/release/soroban_increment_contract.wasm \ - --id 1 \ - --footprint \ - -- \ - increment -``` +Go ahead and commit it. +```bash +git commit -m "add incrementor contract" ``` -Footprint: {"readOnly":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"static":"ledgerKeyContractCode"}}}],"readWrite":[{"contractData":{"contractId":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],"key":{"symbol":[67,79,85,78,84,69,82]}}}]} -``` - -### Contract Data Type Descriptions -The general usage and interface is identical for all storage types. They differ only in fees and expiration behavior as follows: +## Summary -- `Temporary` - - Cheapest fees. - - Permanently deleted on expiration, cannot be restored. - - Suitable for time bounded data (i.e. price oracles, signatures, etc.) and easily recreateable data. - - Unlimited amount of storage. -- `Instance` - - Most expensive fees (same price as `Persistent` storage). - - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. - - Shares the same lifetime as the contract instance. If the contract instance has not expired, instance data is guaranteed to be accessible and not expired. - - Limited amount of storage available. - - Suitable for "shared" contract state that cannot be `Temporary` (i.e. admin accounts, contract metadata, etc.). -- `Persistent` - - Most expensive fees (same price as `Instance` storage). - - Recoverable after expiration, can be restored using the [`RestoreFootprintOp`] operation. - - Does not share the same lifetime as the contract instance. If the contract instance is not expired, `Persistent` data may be expired and need to be restored before invoking the contract. - - Unlimited amount of storage. - - Suitable for user data that cannot be `Temporary` (i.e. balances). - -For more detailed guidelines on how to use contract data, see [`Contract Data Best Practices`]. - -### Contract Data Best Practices - -:::info - -Soroban is a pre-release and at this time outputs footprints in an unstable JSON format. - -::: - -[footprint]: ../fundamentals-and-concepts/persisting-data.mdx#footprints-and-parallel-contention - -Run it a few more times to watch the count change. - -Use the `soroban` to inspect what the counter is after a few runs. - -```sh -soroban contract read --id 1 --key COUNTER -``` +In this section, we added a new contract to this project, reorganizing the project as a multi-contract project using Cargo Workspaces. The new contract made use of Soroban's storage capabilities to store and retrieve data. We also learned about the different kinds of storage and how to manage their lifetimes. -[`soroban-cli`]: ../getting-started/setup#install-the-soroban-cli -[`BumpFootprintExpirationOp`]: ../fundamentals-and-concepts/state-expiration#BumpFootprintExpirationOp -[`RestoreFootprintOp`]: ../fundamentals-and-concepts/state-expiration#RestoreFootprintOp -[`Contract Data Best Practices`]: ../fundamentals-and-concepts/persisting-data.mdx#contract-data-best-practices +Next we'll learn to deploy contracts to Soroban's Futurenet network and interact with them over RPC using the CLI. From 52ef0284fff5e1e17797bcf3c5604254f1c25921 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Thu, 27 Jul 2023 18:52:33 -0400 Subject: [PATCH 177/248] Clean up Getting Started tutorial; add "Deploy to Futurenet" (#516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: move Freighter and Running RPC to Reference We want to keep the stuff in Getting Started hyper-focused on a quick end-to-end tour of Soroban. Now that there's a public RPC endpoint, it is much more straightforward to have people deploy contract right to it, rather than running their own nodes. Running your own node is a more advanced concept that dabblers need not muck with. So this moves both the "Deploy to a Local Network" and "Deploy to Futurenet" pages to the RPC page, in the Reference section. This required some reorganization & rework of the concepts to make it fit the new context. I also updated some instructions, such as teaching people to use `soroban config network` and `soroban config identity`, which were not included in the old "Deploy to…" pages. This commit also moves the "Connect Freighter Wallet" to Reference, since it's a bit in-the-weeds, which is a good feature for a Reference document but not for an end-to-end Tutorial. Coming Soon™: a new "Deploy Contracts" step in the Getting Started section, which uses the public RPC Futurenet endpoint. This will be followed by a "Create a Dapp" step, which will use the new JS Lib generation built into the CLI, and go over relevant Freighter details. * fix: clean up Hello World walk-through - explicitly instruct people to call it `hello-soroban` - move some single-use footnote-style links inline, to make them easier to see/understand/update later - remove spacing around tips for easier visual parsing - remove "Hello World Example" section, since this IS the Hello World example - remove unused & unneeded footnote-style link definitions - clean up example code so it doesn't give warnings on copy/paste * feat(getting-started): clean up Storing Data I'm working toward having people create a frontend Dapp with multiple contracts in a `contracts` folder, so I added a whole part at the beginning walking people through setting up a Cargo Workspace. This page also had more information than necessary about State Expiration; I moved this to the State Expiration doc, which had been practically blank. I reorganized this information somewhat; most notably, the "Best Practices" section had been practically empty. I moved some miscellaneous information to it; it should maybe be renamed "more information about state expiration" rather than "best practices", since it DOESN'T currently contain best practices, and I am not qualified to say what Best Practices might actually be. (Note that in the old version, the "Best Practices" section was blank! It was a misplaced heading, with nothing relevant below.) * fix: add missing "be" Co-authored-by: Willem Wyndham * feat: add 3. Deploy to Futurenet This contains the relevant details people will probably need to know when first getting started with Soroban. * fix: run prettier * feat: commit, summarize, save IDs to files Instructing people to commit to git will help them think about their work more clearly, and will also help them avoid mistakes and get better help when they need it. I also added summaries to each of these tutorial pages, to review what was learned and set up the next lesson. Finally, I decided to have them save contract IDs to files in their `.soroban` folder, rather than in more-ephemeral environment variables. This will make it easier to have them use `soroban contract bindings` in the "Build a Dapp" step, since they'll be able to reference these files in their package.json scripts. * fix: run lint --------- Co-authored-by: Willem Wyndham --- docs/reference/freighter.mdx | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 docs/reference/freighter.mdx diff --git a/docs/reference/freighter.mdx b/docs/reference/freighter.mdx new file mode 100644 index 000000000..f03616842 --- /dev/null +++ b/docs/reference/freighter.mdx @@ -0,0 +1,65 @@ +--- +sidebar_position: 7 +title: Freighter Wallet +description: Freighter is a browser extension that can sign Soroban transactions. +--- + +[Freighter](https://www.freighter.app/) is a browser extension wallet provided by the Stellar Development Foundation. It provides users a way to interact with Soroban tokens directly from the web browser. + +## Setup + +1. Install the Freighter browser extension. + +2. Create a keypair or import an existing account using a mnemonic phrase to complete setup. + +3. Next, switch to `Experimental Mode` to enable the Soroban SDK. In the extension, click the gear in the lower right corner and then navigate to `Preferences`. Toggle on `Experimental Mode`. + +4. After switching to `Experimental Mode`, you should automatically be switched to the Futurenet network. Fund your account on Futurenet using Friendbot. For convenience, you can do so in the Stellar [Laboratory](https://laboratory.stellar.org/#account-creator?network=futurenet). + +## Enable Soroban Tokens + +With a funded Futurenet account and `Experimental Mode` enabled, you can now add Soroban tokens to your Freighter wallet. + +1. On the Freighter account screen, click this `Manage Assets` button at the bottom of the screen. + +2. You will now see a button to `Add Soroban token` at the bottom of the screen. Click this `Add Soroban token` button. + +3. On the next screen, enter the Token ID of the token you want to add to Freighter and click `Add New Token`. + +4. You will now see your token's balance on Freighter's account page. Clicking on the balance will show a history of payments sent using this token. + +## Send Token Payments + +Once you have added a Soroban token to your Freighter wallet, you can now send a payment of that token directly from Freighter. + +1. On the Freighter account screen, click the `Send Payment` icon in the upper right of the screen. + +2. Enter a recipient public key. Click `Continue`. + +3. Select your token from the asset dropdown at the bottom of the screen and enter a token amount. Click `Continue`. + +4. Enter a memo (optional). Click `Review Send`. + +5. Review the details of your payment. Click `Send`. + +## Sign Soroban XDRs + +With a funded Futurenet account and `Experimental Mode` enabled, you can now sign Soroban XDRs using dApps that are integrated with Freighter. An example of an integrated dApp is Stellar's [Laboratory](https://laboratory.stellar.org/#txsigner?network=futurenet). + +1. On the Lab's transaction signer, enter a Soroban XDR into the form field. + +2. Click `Sign with Freighter`. + +3. Freighter will open with the details of the XDR. Click `Approve` to sign or `Reject` to dismiss without a signature. + +4. If approved, Freighter will transmit a signed XDR back to the Lab. + +## As a dApp Provider, Prompt Freighter to Sign Transactions (Advanced) + +If you're building a JS dApp, easily sign Soroban transactions using the [Freighter browser extension](https://www.freighter.app/) and its corresponding client library [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api): + +1. Follow the setup instructions above. + +2. Now, you can use the `signTransaction` [method](https://docs.freighter.app/docs/guide/usingFreighterNode) from `@stellar/freighter-api` in your dApp to sign Soroban XDRs using the account in Freighter. + +3. Upon calling `signTransaction`, Freighter will open and prompt the user to sign the transaction. Approving the transaction will return the signed XDR to the requesting dApp. From 100744f65dce0b713e7aa312aa7002e6e6dc9357 Mon Sep 17 00:00:00 2001 From: Elliot Voris Date: Sun, 30 Jul 2023 22:50:16 -0500 Subject: [PATCH 178/248] Updating `soroban-cli` version and adding bash completion note (#527) * Updating `soroban-cli` version and adding bash completion note * Adding example commands to enable autocompletion --- docs/getting-started/setup.mdx | 51 ++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index d073b620d..7a32c7097 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -22,21 +22,21 @@ command. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` -If you use Windows, or need an alternative method of installing Rust, check out: +If you use Windows, or need an alternative method of installing Rust, check out: https://www.rust-lang.org/tools/install ## Install the target Install the `wasm32-unknown-unknown` target. -```sh +```bash rustup target add wasm32-unknown-unknown ``` ## Configure an Editor Many editors have support for Rust. Visit the following link to find out how to -configure your editor: +configure your editor: https://www.rust-lang.org/tools A popular editor is Visual Studio Code: @@ -56,8 +56,8 @@ contract will execute on network, however in a local sandbox. Install the Soroban CLI using `cargo install`. -```sh -cargo install --locked --version 0.9.1 soroban-cli +```bash +cargo install --locked --version 0.9.4 soroban-cli ``` :::info @@ -71,18 +71,18 @@ Report issues and share feedback about the Soroban CLI Run the `soroban` command and you should see output like below. -```sh +```bash soroban ``` -``` -❯ soroban +```bash +$ soroban Build, deploy, & interact with contracts; set identities to sign with; configure networks; generate keys; and more. Intro: https://soroban.stellar.org CLI Reference: https://github.com/stellar/soroban-tools/tree/main/docs/soroban-cli-full-docs.md -Usage: soroban +Usage: soroban [OPTIONS] Commands: contract Tools for smart contract developers @@ -93,9 +93,38 @@ Commands: completion Print shell completion code for the specified shell Options: - -h, --help Print help (see more with '--help') - -V, --version Print version + --global Use global config + -f, --filter-logs Filter logs output. To turn on "soroban_cli::log::footprint=debug" or off "=off". Can also use env var `RUST_LOG` + -q, --quiet Do not write logs to stderr including `INFO` + -v, --verbose Log DEBUG events + --very-verbose Log DEBUG and TRACE events + --list List installed plugins. E.g. `soroban-hello` + -h, --help Print help (see more with '--help') + -V, --version Print version + +TESTING_OPTIONS: + --config-dir +``` + +:::info + +**Protip:** You can use `soroban completion` to generate shell completion for `bash`, `elvish`, `fish`, `powershell`, and `zsh`. You should absolutely try it out. It will feel like a super power!! + +To enable autocomplete in the current bash shell, run: + +```bash +source <(soroban completion --shell bash) ``` +To enable autocomplete permanently in future bash shells, run: + +```bash +echo "source <(soroban completion --shell bash)" >> ~/.bashrc +``` + +Users of non-bash shells may need to adapt the above commands to suit their needs. + +::: + [Rust]: https://www.rust-lang.org/ [Soroban CLI]: setup#install-the-soroban-cli From 2ea51b4b2f59727ccba224b7bebafdfe296c3182 Mon Sep 17 00:00:00 2001 From: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:29:19 -0600 Subject: [PATCH 179/248] update SEO titles and descriptions (#534) * update SEO titles in Getting Started * Update setup.mdx * SEO titles and descriptions in Getting Started * formatting * update titles and descriptions for basic tutorials * update SEO in advanced tutorials * updated header for SEO * fix * updating... again! --- docs/getting-started/deploy-to-futurenet.mdx | 19 ++++++++++++++++++- docs/getting-started/hello-world.mdx | 19 ++++++++++++++++++- docs/getting-started/setup.mdx | 19 ++++++++++++++++++- docs/getting-started/storing-data.mdx | 19 ++++++++++++++++++- 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/docs/getting-started/deploy-to-futurenet.mdx b/docs/getting-started/deploy-to-futurenet.mdx index bed9fedfb..f5414b011 100644 --- a/docs/getting-started/deploy-to-futurenet.mdx +++ b/docs/getting-started/deploy-to-futurenet.mdx @@ -1,9 +1,26 @@ --- sidebar_position: 4 title: 3. Deploy to Futurenet -description: Deploy your contract to Soroban's Futurenet network and interact with it. +description: Deploy smart contracts to a live test network. --- + + Deploy smart contracts to a live test network. + + + + + + You've built two simple contracts and run them locally in Sandbox. Now you can deploy them to a network. Soroban has a test network called Futurenet that you can use to deploy and test your contracts. Soon Soroban will also have a test network called Testnet, which will have stronger guarantees around data persistence, but you'll still be able to use Futurenet for testing the latest Soroban features. diff --git a/docs/getting-started/hello-world.mdx b/docs/getting-started/hello-world.mdx index 83b4a438f..d4e21dfd4 100644 --- a/docs/getting-started/hello-world.mdx +++ b/docs/getting-started/hello-world.mdx @@ -1,9 +1,26 @@ --- sidebar_position: 2 title: 1. Hello World -description: Create your first Soroban contract. +description: Create your first smart contract in Rust. --- + + Create your first smart contract in Rust. + + + + + + import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; diff --git a/docs/getting-started/setup.mdx b/docs/getting-started/setup.mdx index 7a32c7097..3df7e0c9a 100644 --- a/docs/getting-started/setup.mdx +++ b/docs/getting-started/setup.mdx @@ -1,9 +1,26 @@ --- sidebar_position: 1 title: Setup -description: Install and configure Rust and the Soroban CLI. +description: Install and configure Rust to deploy smart contracts. --- + + Install and configure Rust to deploy smart contracts. + + + + + + Soroban contracts are small programs written in the [Rust] programming language. To build and develop contracts you need only a couple prerequisites: diff --git a/docs/getting-started/storing-data.mdx b/docs/getting-started/storing-data.mdx index 8c88ddb6f..682984a3d 100644 --- a/docs/getting-started/storing-data.mdx +++ b/docs/getting-started/storing-data.mdx @@ -1,9 +1,26 @@ --- sidebar_position: 3 title: 2. Storing Data -description: Write a simple Soroban contract that stores and retrieves data. +description: Write a smart contract that stores and retrieves data. --- + + Write a smart contract that stores and retrieves data. + + + + + + import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; From 892a87a5a731fa65be323a79b175a9980e4f49e8 Mon Sep 17 00:00:00 2001 From: Chad Ostrowski <221614+chadoh@users.noreply.github.com> Date: Tue, 5 Sep 2023 18:32:20 -0400 Subject: [PATCH 180/248] feat: add "4. Build an App" step to "Getting Started" (#528) Uses smartdeploy CLI branch for now, for futurenet compatibility Co-authored-by: Julian Martinez Co-authored-by: tomerweller Co-authored-by: Bri Wylde <92327786+briwylde08@users.noreply.github.com> Co-authored-by: Tyler van der Hoeven --- docs/getting-started/create-an-app.mdx | 531 +++++++++++++++++++++++++ 1 file changed, 531 insertions(+) create mode 100644 docs/getting-started/create-an-app.mdx diff --git a/docs/getting-started/create-an-app.mdx b/docs/getting-started/create-an-app.mdx new file mode 100644 index 000000000..4e3a935d1 --- /dev/null +++ b/docs/getting-started/create-an-app.mdx @@ -0,0 +1,531 @@ +--- +sidebar_position: 5 +title: 4. Create an App +description: Make a frontend web app that interacts with your smart contracts. +--- + +With two smart contracts deployed to a public network, you can now create a web app that interacts with them via RPC calls. Let's get started. + +## Initialize a frontend toolchain + +You can build a Soroban app with any frontend toolchain or integrate it into any existing full-stack app. For this tutorial, we're going to use [Astro](https://astro.build/). Astro works with React, Vue, Svelte, any other UI library, or no UI library at all. In this tutorial, we're not using a UI library. The Soroban-specific parts of this tutorial will be similar no matter what frontend toolchain you use. + +If you're new to frontend, don't worry. We won't go too deep. But it will be useful for you to see and experience the frontend development process used by Soroban apps. We'll cover the relevant bits of JavaScript and Astro, but teaching all of frontend development and Astro is beyond the scope of this tutorial. + +Let's get started. + +You're going to need [Node.js](https://nodejs.org/en/download/package-manager/) v18.14.1 or greater. If you haven't yet, install it now. + +Then we want to initialize the current directory, `soroban-tutorial`, as an Astro project, but Astro doesn't like that. It wants to create a new directory. So let's go ahead and do that, then move all the contents of the new directory into their parent directory: + +```bash +npm create astro@4.0.1 soroban-tutorial -- --template basics --install --no-git --typescript strictest +``` + +This will take a little while, as the `--install` option automatically installs the dependencies. Once it's done, let's move the contents of the new nested folder into the project root. Other project organization strategies are possible, but we find that it causes no problems to have the Node-specific web app stuff live right alongside the Rust-specific smart contract stuff and that keeping it all in the root just makes things simpler. + +```bash +mv soroban-tutorial/* . +mv soroban-tutorial/.vscode . +cat soroban-tutorial/.gitignore >> .gitignore +rm soroban-tutorial/.gitignore +rmdir soroban-tutorial +``` + +This is a good time to commit your changes so that later on, you can clearly see the differences between what came from Astro's `basics` template and the Soroban-specific stuff we're going to add. + +```bash +git add . +git commit -m "Initialize Astro project" +``` + +## Generate an NPM package for the Hello World contract + +Before we even open the new frontend files, let's generate an NPM package for the Hello World contract. This is our suggested way to interact with contracts from frontends. These generated libraries work with any JavaScript project (not a specific UI like React), and make it easy to work with some of the trickiest bits of Soroban, like encoding [XDR](https://soroban.stellar.org/docs/fundamentals-and-concepts/fully-typed-contracts). + +This is going to use the CLI command `soroban contract bindings typescript`. Unfortunately, the version of `bindings typescript` packaged with CLI v0.9.4 has some bugs, and the fix can't be released yet because the `main` branch of the CLI is broken with futurenet. To work around this, we're going to install a pinned version of the CLI from a fixed-and-still-futurenet-compatible fork. Create a directory called `.cargo` (with the dot; it's a hidden folder): + + mkdir .cargo + +Then add one file to it, `config.toml`. Paste these contents into it: + +```toml +[alias] # command aliases +install_soroban = "install --git https://github.com/AhaLabs/soroban-tools --branch smartdeploy --root ./target soroban-cli --debug" +``` + +Now install the pinned version by using the alias you just set up: + + cargo install_soroban + +This will take a couple minutes; it builds a local version from the `smartdeploy` branch into `target/bin/soroban`. Once it's done, check that it worked: + +```bash +ls target/bin/soroban +``` + +And check the version info of this `smartdeploy` install: + +```bash +./target/bin/soroban --version +``` + +If you want, you can add `./target/bin/` [to your PATH](https://unix.stackexchange.com/questions/26047/how-to-correctly-add-a-path-to-path), so that anytime you're in a project with a locally-installed version of `soroban` in its `target/bin` directory, you'll automatically use it (rather than your global version) when you just type `soroban`. For this project, let's also add a `soroban` script in the root of the project that automatically installs the pinned version if it's not there, then uses it. This will make it easier for your collaborators to work with you. Create a file called just `soroban` and paste the following contents: + +```bash +#!/bin/bash +if [ ! -f ./target/bin/soroban ]; then + cargo install_soroban +fi +./target/bin/soroban "$@" # `$@` expands to all arguments passed to this script +``` + +Make sure it's executable: + +```bash +chmod +x soroban +``` + +Ok, now you can finally generate that NPM package: + +```bash +./soroban contract bindings typescript \ + --network futurenet \ + --contract-id $(cat .soroban/hello-id) \ + --output-dir hello-soroban-client +``` + +We attempt to keep the code in these generated libraries readable, so go ahead and look around. Open up the new `hello-soroban-client` directory in your editor. If you've built or contributed to Node projects, it will all look familiar. You'll see a `package.json` file, a `src` directory, a `tsconfig.json`, and even a README. The README is a great place to start. Go ahead and give it a read. + +As it says, when using local libraries, we've had the [most success](https://github.com/stellar/soroban-example-dapp/pull/117#discussion_r1232873560) when generating them directly into the `node_modules` folder, and leaving them out of the `dependencies` section. Yes, this is surprising, but it works the best. Go ahead and move this new library there: + +```bash +mv hello-soroban-client node_modules +``` + +And then let's update the `package.json` in your `soroban-tutorial` project with a `postinstall` script to make sure the generated library stays up-to-date: + +```diff + "scripts": { + ... +- "astro": "astro" ++ "astro": "astro", ++ "postinstall": "./soroban contract bindings typescript --network futurenet --contract-id $(cat .soroban/hello-id) --output-dir node_modules/hello-soroban-client" + } +``` + +### Call the contract from the frontend + +Now let's open up `src/pages/index.astro` and add some code to call the contract. We'll start by importing the generated library: + +```diff + --- + import Layout from '../layouts/Layout.astro'; + import Card from '../components/Card.astro'; ++import { Contract, networks } from 'hello-soroban-client'; ++ ++const greeter = new Contract({ ++ ...networks.futurenet, ++ rpcUrl: 'https://rpc-futurenet.stellar.org', // from https://soroban.stellar.org/docs/reference/rpc#public-rpc-providers ++}); ++ ++const greeting = await greeter.hello({ to: 'Soroban' }); + --- +``` + +Then find the `

` tag and replace its contents with the greeting: + +```diff +-

Welcome to Astro

++

{greeting.join(' ')}

+``` + +Now start the dev server: + +```bash +npm run dev +``` + +And open [http://localhost:3000](http://localhost:3000) in your browser. You should see the greeting from the contract! + +You can try updating the `{ to: 'Soroban' }` argument. When you save the file, the page will automatically update. + +### What's happening here? + +If you inspect the page (right-click, inspect) and refresh, you'll see a couple interesting things: + +- The "Network" tab shows that there are no Fetch/XHR requests made. But RPC calls happen via Fetch/XHR! So how is the frontend calling the contract? +- There's no JavaScript on the page. But we just wrote some JavaScript! How is it working? + +This is part of Astro's philosophy: the frontend should ship with as few assets as possible. Preferably zero JavaScript. When you put JavaScript in the [frontmatter](https://docs.astro.build/en/core-concepts/astro-components/), Astro will run it at build time, and then replace anything in the `{...}` curly brackets with the output. + +When using the development server with `npm run dev`, it runs the frontmatter code on the server, and injects the resulting values into the page on the client. + +You can try building to see this more dramatically: + +```bash +npm run build +``` + +Then check the `dist` folder. You'll see that it built an HTML and CSS file, but no JavaScript. And if you look at the HTML file, you'll see a static "Hello Soroban" in the `

`. + +During the build, Astro made a single call to your contract, then injected the static result into the page. This is great for contract methods that don't change, but probably won't work for most contract methods. Let's integrate with the `incrementor` contract to see how to handle interactive methods in Astro. + +## Call the incrementor contract from the frontend + +While `hello` is a simple view-only/read method, `increment` changes on-chain state. This means that someone needs to sign the transaction. So we'll need to add transaction-signing capabilities to the frontend. + +The way signing works in a browser is with a _wallet_. Wallets can be web apps, browser extensions, standalone apps, or even separate hardware devices. + +Right now, the wallet that best supports Soroban is +[Freighter](../reference/freighter.mdx). It's a Chrome extension. Go ahead and [install it now](https://freighter.app). + +Once it's installed, open it up, go to Settings (the gear icon) → Preferences and toggle the switch to Enable Experimental Mode. Then go back to its home screen and select "Future Net" from the top-right dropdown. Finally, if it shows the message that your Stellar address is not funded, go ahead and click the "Fund with Friendbot" button. + +Now you're all set up to use Freighter as a user, and you can add it to your app. + +### Add Freighter + +We're going to add a "Connect" button to the page that opens Freighter and prompts the user to give your web page permission to use Freighter. Once they grant this permission, the "Connect" button will be replaced with a message saying, "Signed in as [their public key]". + +First, add [@stellar/freighter-api](https://www.npmjs.com/package/@stellar/freighter-api) as a dependency: + +```bash +npm install @stellar/freighter-api +``` + +Then we need to work around a bug in NPM—adding a new dependency with `npm install [new dependency]` doesn't run the `postinstall` hook, the way that `npm install` does. But it does run the cleanup logic that removes "incorrect" folders like `node_modules/hello-soroban-client`. So you either need to run `npm i` (a shortcut for `npm install`), or `postinstall` directly: + +```bash +npm run postinstall +``` + +Now let's add a new component to the `src/components` directory called `ConnectFreighter.astro` with the following contents: + +```html +
+
+ +
+
+ + + + +``` + +Some of this may look surprising. ` - - -``` - -Some of this may look surprising. ` + + +``` + +Some of this may look surprising. ` + + +``` + +Some of this may look surprising. ` - - -``` - -Some of this may look surprising. `