From 80ea5501da7ba781233bf19f806d648baf0f59a7 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Wed, 18 Dec 2024 16:52:35 -0600 Subject: [PATCH 01/11] update rust readmes --- motoko/canister_logs/README.md | 54 +++++----- rust/basic_bitcoin/README.md | 15 +-- rust/basic_dao/README.md | 42 ++++---- rust/basic_ethereum/README.md | 12 +-- rust/canister-info/README.md | 6 -- rust/canister-snapshots/README.md | 42 +++----- rust/canister_logs/README.md | 155 +++++++++++++--------------- rust/composite_query/README.md | 17 +-- rust/counter/README.md | 23 ++--- rust/defi/README.md | 35 +++---- rust/dip721-nft-container/README.md | 33 +++--- rust/face-recognition/README.md | 47 ++++----- rust/guards/README.md | 30 +++--- rust/hello/README.md | 49 +++------ rust/icp_transfer/README.md | 79 +++++--------- rust/image-classification/README.md | 47 +++------ rust/nft-wallet/README.md | 22 ++-- rust/parallel_calls/README.md | 29 ++---- rust/performance_counters/README.md | 37 +++---- rust/periodic_tasks/README.md | 8 -- 20 files changed, 301 insertions(+), 481 deletions(-) diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index ad69e31b5..545dd99b9 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -1,66 +1,64 @@ ---- -keywords: [beginner, motoko, canister logs, logging] ---- - # Canister logs -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/canister_logs) - ## Prerequisites -This example requires an installation of: -- [x] DFX version 0.19.0 or newer -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -You will need to have 3 terminal windows: -- Terminal A: Running a DFX instance and separating its output from anything else -- Terminal B: Deploying a canister and seeing its output -- Terminal C: Reading logs interactively +## Step 1: Setup project environment + +Navigate into the folder containing the project's files and start a local instance of the replica with the command: -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +```shell +dfx start --clean +``` + +You will need to have 3 terminal windows: +- Terminal A: Running a `dfx` instance and separating its output from anything else. +- Terminal B: Deploying a canister and seeing its output. +- Terminal C: Reading logs interactively. ```shell # Terminal A -- for running DFX and separating its output from anything else. -$ cd examples/motoko/canister_logs -$ dfx start --clean +cd examples/motoko/canister_logs # Terminal B -- for deploying the canister and calling its methods. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs # Terminal C -- for polling logs. -$ cd examples/motoko/canister_logs +cd examples/motoko/canister_logs ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```shell # Terminal B -$ dfx deploy +dfx deploy ``` -### Step 3: Check canister logs: +## Step 3: Check canister logs Expect to see logs from timer traps. ```shell # Terminal B -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap [3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -### Step 4: Call `print` method and check the logs: +## Step 4: Call `print` method and check the logs ```shell # Terminal B -$ dfx canister call CanisterLogs print hi +dfx canister call CanisterLogs print hi () # Expect to see new log entry. -$ dfx canister logs CanisterLogs +dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -70,7 +68,7 @@ $ dfx canister logs CanisterLogs ... ``` -### Step 5: Start constantly polling logs: +## Step 5: Start constantly polling logs In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: @@ -86,7 +84,7 @@ $ ./poll_logs.sh ... ``` -### Step 6: Call `print`, `trap` and other canister methods: +## Step 6: Call `print`, `trap` and other canister methods ```shell # Terminal B diff --git a/rust/basic_bitcoin/README.md b/rust/basic_bitcoin/README.md index f43a1f5e7..6341aa5ea 100644 --- a/rust/basic_bitcoin/README.md +++ b/rust/basic_bitcoin/README.md @@ -1,12 +1,5 @@ ---- -keywords: [advanced, rust, bitcoin, btc, integration, bitcoin integration] ---- - # Basic Bitcoin -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_bitcoin) - -## Overview This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/bitcoin/overview) **that can send and receive Bitcoin** on the Internet Computer. ## Architecture @@ -21,18 +14,16 @@ of the Internet Computer. For a deeper understanding of the ICP < > BTC integration, see the [Bitcoin integration documentation](https://wiki.internetcomputer.org/wiki/Bitcoin_Integration). -## Prerequisites +### Prerequisites * [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0-beta.0` is required. * [x] On macOS, `llvm` with the `wasm32-unknown-unknown` target (which is not included in the XCode installation by default) is required. To install, run `brew install llvm`. ## Step 1: Building and deploying sample code -### Clone the smart contract - This tutorial has the same smart contract written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) using ECDSA, Schnorr, and Bitcoin API. @@ -130,7 +121,7 @@ from three types of addresses: Note that P2TR *key path* spending with a tweaked key is currently not available on the IC because the threshold Schnorr signing interface does not allow applying BIP341 tweaks to the private key. In contrast, the -tweaked public key is used to spend in the script path, which is availble on the +tweaked public key is used to spend in the script path, which is available on the IC. For a technical comparison of different ways of how single-signer P2TR addresses can be constructed and used, you may want to take a look at [this post](https://bitcoin.stackexchange.com/a/111100) by Pieter Wuille. diff --git a/rust/basic_dao/README.md b/rust/basic_dao/README.md index c508230b9..21a8e403b 100644 --- a/rust/basic_dao/README.md +++ b/rust/basic_dao/README.md @@ -1,15 +1,7 @@ ---- -keywords: [advanced, rust, dao, decentralized organization, decentralized org] ---- - # Basic DAO -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_dao) - This sample project demonstrates a basic [decentralized autonomous organization](https://en.wikipedia.org/wiki/Decentralized_autonomous_organization) (DAO) that can be deployed to the [Internet Computer](https://github.com/dfinity/ic). The basic DAO sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/basic_dao) and [Rust](https://github.com/dfinity/examples/tree/master/rust/basic_dao). You can see a quick introduction on [YouTube](https://youtu.be/3IcYlieA-EE). -## Overview - A `basic_dao` can be initialized with a set of accounts: mappings from principal IDs to a number of tokens. Account owners can query their account balance by calling `account_balance` and transfer tokens to other accounts by calling `transfer`. Anyone can call `list_accounts` to view all accounts. Account owners can submit proposals by calling `submit_proposal`. A proposal specifies a canister, method, and arguments for this method. Account owners can cast votes (either `Yes` or `No`) on a proposal by calling `vote`. The amount of votes cast is equal to the amount of tokens the account owner has. If enough `Yes` votes are cast, `basic_dao` will execute the proposal by calling the proposal’s given method with the given args against the given canister. If enough `No` votes are cast, the proposal is not executed, and is instead marked as `Rejected`. @@ -18,37 +10,39 @@ Certain system parameters, like the number of `Yes` votes needed to pass a propo View the [canister service definition](https://github.com/dfinity/examples/blob/master/rust/basic_dao/src/basic_dao/src/basic_dao.did) for more details. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] The Rust toolchain (e.g. cargo). - [x] [didc.](https://github.com/dfinity/candid/tree/master/tools/didc) -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Build the `basic_dao` canister: +## Step 1: Build the `basic_dao` canister ```bash make clean; make ``` -### Step 2: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 2: Setup the dev environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: ```bash cd basic_dao dfx start --background ``` -### Step 3: Create test identities with the commands: +## Step 3: Create test identities with the commands ```bash dfx identity new --disable-encryption Alice; dfx identity use Alice; export ALICE=$(dfx identity get-principal); dfx identity new --disable-encryption Bob; dfx identity use Bob; export BOB=$(dfx identity get-principal); ``` -### Step 4: Deploy basic_dao with the initial test accounts: +## Step 4: Deploy basic_dao with the initial test accounts ```bash dfx deploy --argument "(record { @@ -63,7 +57,7 @@ dfx deploy --argument "(record { })" ``` -### Step 5: List accounts and confirm you see the two test accounts: +## Step 5: List accounts and confirm you see the two test accounts ```bash dfx canister call basic_dao list_accounts '()' @@ -86,7 +80,7 @@ Output: ) ``` -### Step 6: Call `account_balance` as Bob: +## Step 6: Call `account_balance` as Bob ```bash dfx canister call basic_dao account_balance '()' @@ -98,7 +92,7 @@ You should see the output: (record { amount_e8s = 100_000_000 : nat64 }) ``` -### Step 7: Transfer tokens to Alice: +## Step 7: Transfer tokens to Alice ```bash dfx canister call basic_dao transfer "(record { to = principal \"$ALICE\"; amount = record { amount_e8s = 90_000_000:nat;};})"; @@ -110,7 +104,7 @@ Output: (variant { Ok }) ``` -### Step 8: List accounts and see that the transfer was made: +## Step 8: List accounts and see that the transfer was made ```bash dfx canister call basic_dao list_accounts '()' @@ -137,7 +131,9 @@ Output: Note that the transfer fee was deducted from Bob's account. ::: -### Step 9: Let's make a proposal to change the transfer fee. You can call `get_system_params` to learn the current transfer fee: +## Step 9: Let's make a proposal to change the transfer fee + +You can call `get_system_params` to learn the current transfer fee: ```bash dfx canister call basic_dao get_system_params '()'; @@ -177,7 +173,7 @@ Output: blob "DIDL\03l\01\f2\c7\94\ae\03\01n\02l\01\b9\ef\93\80\08x\01\00\01 N\00\00\00\00\00\00" ``` -### Step 10: We can then submit the proposal: +## Step 10: We can then submit the proposal ```bash dfx canister call basic_dao submit_proposal '(record { canister_id = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; @@ -191,7 +187,7 @@ Note the output proposal ID: (variant { Ok = 0 : nat64 }) ``` -### Step 11: Confirm the proposal was created: +## Step 11: Confirm the proposal was created ```bash dfx canister call basic_dao get_proposal '(0:nat64)' @@ -199,7 +195,7 @@ dfx canister call basic_dao get_proposal '(0:nat64)' You should see `state = variant { Open };` in the output. -### Step 12: Vote on the proposal: +## Step 12: Vote on the proposal ```bash dfx canister call basic_dao vote '(record { proposal_id = 0:nat64; vote = variant { Yes };})' @@ -253,7 +249,7 @@ Output: ) ``` -### Resources +## Resources - [ic-cdk](https://docs.rs/ic-cdk/latest/ic_cdk/) - [ic-cdk-macros](https://docs.rs/ic-cdk-macros) - [JavaScript API reference](https://erxue-5aaaa-aaaab-qaagq-cai.ic0.app/) diff --git a/rust/basic_ethereum/README.md b/rust/basic_ethereum/README.md index 44e54fae5..0297369ca 100644 --- a/rust/basic_ethereum/README.md +++ b/rust/basic_ethereum/README.md @@ -1,13 +1,5 @@ ---- -keywords: [ advanced, rust, ethereum, eth, integration, ethereum integration ] ---- - # Basic Ethereum -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/basic_ethereum) - -## Overview - This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview) **that can send and receive Ether (ETH)** on the Internet Computer. @@ -22,9 +14,9 @@ features of the Internet Computer. For a deeper understanding of the ICP < > ETH integration, see the [Ethereum integration overview](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview). -## Prerequisites +### Prerequisites -* [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). ## Step 1: Building and deploying sample code diff --git a/rust/canister-info/README.md b/rust/canister-info/README.md index 5342502bd..183429b8c 100644 --- a/rust/canister-info/README.md +++ b/rust/canister-info/README.md @@ -1,11 +1,5 @@ ---- -keywords: [beginner, rust, canister info] ---- - # Canister info -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister-info) - The purpose of this dapp is to give developers a small (backend) dapp that uses the IC's `canister_info` management call to retrieve information about canisters including canister history. You can find a detailed description of its methods in the form of doc comments in the source code. diff --git a/rust/canister-snapshots/README.md b/rust/canister-snapshots/README.md index 17dcb5dfc..2b222378b 100644 --- a/rust/canister-snapshots/README.md +++ b/rust/canister-snapshots/README.md @@ -1,12 +1,4 @@ ---- -keywords: [advanced, rust, backup, restore, snapshots] ---- - -# Canister Snapshots Example - -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister-snapshots) - -## Overview +# Canister snapshots This example demonstrates the process of taking and loading canister snapshots. It features a canister named `chat`, which functions as a miniature database. @@ -14,24 +6,23 @@ The `remove_spam` canister method intentionally includes a bug to simulate data The example outlines the steps to install the canister, create a snapshot, and subsequently restore the data after the simulated data loss. -## Prerequisites +### Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). Note: the Canister Snapshots feature requires `dfx` version `0.23.0-beta.3` or later. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). Note: the Canister Snapshots feature requires `dfx` version `0.23.0-beta.3` or later. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- ### Step 1: Begin by opening a terminal window and navigating into the project's directory +Begin by opening a terminal window. -```sh -cd examples/rust/canister-snapshots -``` +## Step 1: Setup the project environment -- ### Step 2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: -```sh -dfx stop -dfx start --clean + +```bash +cd examples/rust/canister-snapshots +dfx start ``` This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. @@ -39,19 +30,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean Running dfx start for version 0.23.0-beta.3 [...] Replica API running on 127.0.0.1:4943 ``` -- ### Step 3: Open another terminal window in the same directory +## Step 2: Open another terminal window in the same directory ```sh cd examples/rust/canister-snapshots ``` -- ### Step 4: Compile and deploy `chat` canister +## Step 3: Compile and deploy `chat` canister ```sh dfx deploy @@ -69,7 +59,7 @@ URLs: chat: http://127.0.0.1:4943/?canisterId=... ``` -- ### Step 5: Populate the database with data +## Step 4: Populate the database with data ```sh dfx canister call chat append 'Hi there!' @@ -85,7 +75,7 @@ Example output: (vec { "Hi there!" }) ``` -- ### Step 6: Take canister snapshot +## Step 5: Take canister snapshot Canister `chat` is currently running, and snapshots should not be taken of active canisters. Therefore, the canister should be stopped before taking a snapshot and then restarted. @@ -107,7 +97,7 @@ Created a new snapshot of canister chat. Snapshot ID: 00000000000000008000000000 Starting code for canister chat, with canister_id bkyz2-fmaaa-aaaaa-qaaaq-cai ``` -- ### Step 7: Simulate data loss +## Step 6: Simulate data loss The `remove_spam` canister method intentionally includes a bug to simulate data loss. @@ -127,7 +117,7 @@ Example output: There is no more data in the database. -- ### Step 8: Restore the canister state from the snapshot +## Step 7: Restore the canister state from the snapshot Canister `chat` is currently running, and snapshots should not be applied to active canisters. Therefore, the canister must be stopped before applying the snapshot and then restarted. diff --git a/rust/canister_logs/README.md b/rust/canister_logs/README.md index be2927f4c..38f0a52ae 100644 --- a/rust/canister_logs/README.md +++ b/rust/canister_logs/README.md @@ -1,123 +1,111 @@ ---- -keywords: [beginner, rust, canister logs, logging] ---- - # Canister logs -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/canister_logs) +### Prerequisites -## Prerequisites -This example requires an installation of: +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] DFX version 0.19.0 or newer -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` +## Step 1: Setup project environment -You will need to have 3 terminal windows: -- Terminal A: Running a DFX instance and separating its output from anything else -- Terminal B: Deploying a canister and seeing its output -- Terminal C: Reading logs interactively +Navigate into the folder containing the project's files and start a local instance of the replica with the commandss: + +```shell +dfx start --clean +``` -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +You will need to have 3 terminal windows: +- Terminal A: Running a `dfx` instance and separating its output from anything else. +- Terminal B: Deploying a canister and seeing its output. +- Terminal C: Reading logs interactively. ```shell # Terminal A -- for running DFX and separating its output from anything else. -$ cd examples/rust/canister_logs -$ dfx start --clean +cd examples/rust/canister_logs # Terminal B -- for deploying the canister and calling its methods. -$ cd examples/rust/canister_logs +cd examples/rust/canister_logs # Terminal C -- for polling logs. -$ cd examples/rust/canister_logs +cd examples/rust/canister_logs ``` -### Step 2: Deploy the canister: +## Step 2: Deploy the canister ```shell # Terminal B -$ dfx deploy +dfx deploy ``` -### Step 3: Check canister logs: +## Step 3: Check canister logs Expect to see logs from timer traps. ```shell # Terminal B -$ dfx canister logs canister_logs -[0. 2024-05-22T12:35:32.050252022Z]: right before timer trap -[1. 2024-05-22T12:35:32.050252022Z]: [TRAP]: timer trap -[2. 2024-05-22T12:35:37.680315152Z]: right before timer trap -[3. 2024-05-22T12:35:37.680315152Z]: [TRAP]: timer trap - +dfx canister logs CanisterLogs +[0. 2024-05-23T08:32:26.203980235Z]: right before timer trap +[1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap +[2. 2024-05-23T08:32:31.836721763Z]: right before timer trap +[3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -### Step 4: Call `print` method and check the logs: +## Step 4: Call `print` method and check the logs ```shell # Terminal B -$ dfx canister call canister_logs print hi +dfx canister call CanisterLogs print hi () # Expect to see new log entry. -$ dfx canister logs canister_logs +dfx canister logs CanisterLogs +... +[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap +[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap +[10. 2024-05-23T08:32:48.713755238Z]: hi +[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap +[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap ... -[18. 2024-05-22T12:36:20.881326098Z]: right before timer trap -[19. 2024-05-22T12:36:20.881326098Z]: [TRAP]: timer trap -[20. 2024-05-22T12:36:26.305162772Z]: hi -[21. 2024-05-22T12:36:27.185879186Z]: right before timer trap -[22. 2024-05-22T12:36:27.185879186Z]: [TRAP]: timer trap ``` -### Step 5: Start constantly polling logs: +## Step 5: Start constantly polling logs -In order not to call `dfx canister logs canister_logs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: +In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: ```shell # Terminal C $ ./poll_logs.sh ... -[18. 2024-05-22T12:36:20.881326098Z]: right before timer trap -[19. 2024-05-22T12:36:20.881326098Z]: [TRAP]: timer trap -[20. 2024-05-22T12:36:26.305162772Z]: hi -[21. 2024-05-22T12:36:27.185879186Z]: right before timer trap -[22. 2024-05-22T12:36:27.185879186Z]: [TRAP]: timer trap +[8. 2024-05-23T08:32:46.598972616Z]: right before timer trap +[9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap +[10. 2024-05-23T08:32:48.713755238Z]: hi +[11. 2024-05-23T08:32:51.623988313Z]: right before timer trap +[12. 2024-05-23T08:32:51.623988313Z]: [TRAP]: timer trap ... ``` -### Step 6: Call `print`, `trap` and other canister methods: +## Step 6: Call `print`, `trap` and other canister methods ```shell # Terminal B -$ dfx canister call canister_logs print hi! +dfx canister call CanisterLogs print hi! () -$ dfx canister call canister_logs print hello! +dfx canister call CanisterLogs print hello! () -$ dfx canister call canister_logs print yey! +dfx canister call CanisterLogs print yey! () -$ dfx canister call canister_logs trap oops! +dfx canister call CanisterLogs trap oops! Error: Failed update call. Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: oops!, error code None -$ dfx canister call canister_logs panic aaa! +dfx canister call CanisterLogs memory_oob Error: Failed update call. Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'aaa!', src/lib.rs:17:5, error code None - -$ dfx canister call canister_logs memory_oob -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped: stable memory out of bounds, error code None - -$ dfx canister call canister_logs failed_unwrap -Error: Failed update call. -Caused by: Failed update call. - The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:31:47, error code None + The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: StableMemory range out of bounds, error code None ``` @@ -126,30 +114,25 @@ Observe recorded logs that might look similar to this: ```shell # Terminal C ... -[45. 2024-05-22T12:37:33.0576873Z]: right before timer trap -[46. 2024-05-22T12:37:33.0576873Z]: [TRAP]: timer trap -[47. 2024-05-22T12:37:33.773343176Z]: hi! -[48. 2024-05-22T12:37:37.558075267Z]: hello! -[49. 2024-05-22T12:37:38.349121524Z]: right before timer trap -[50. 2024-05-22T12:37:38.349121524Z]: [TRAP]: timer trap -[51. 2024-05-22T12:37:41.466030479Z]: yey! -[52. 2024-05-22T12:37:43.7472275Z]: right before timer trap -[53. 2024-05-22T12:37:43.7472275Z]: [TRAP]: timer trap -[54. 2024-05-22T12:37:45.302285184Z]: right before trap -[55. 2024-05-22T12:37:45.302285184Z]: [TRAP]: oops! -[56. 2024-05-22T12:37:48.900425146Z]: right before timer trap -[57. 2024-05-22T12:37:48.900425146Z]: [TRAP]: timer trap -[58. 2024-05-22T12:37:49.736443986Z]: right before panic -[59. 2024-05-22T12:37:49.736443986Z]: Panicked at 'aaa!', src/lib.rs:37:5 -[60. 2024-05-22T12:37:49.736443986Z]: [TRAP]: Panicked at 'aaa!', src/lib.rs:37:5 -[61. 2024-05-22T12:37:54.122929037Z]: right before timer trap -[62. 2024-05-22T12:37:54.122929037Z]: [TRAP]: timer trap -[63. 2024-05-22T12:37:54.94948481Z]: right before memory out of bounds -[64. 2024-05-22T12:37:54.94948481Z]: [TRAP]: stable memory out of bounds -[65. 2024-05-22T12:37:59.693695919Z]: right before failed unwrap -[66. 2024-05-22T12:37:59.693695919Z]: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:51:47 -[67. 2024-05-22T12:37:59.693695919Z]: [TRAP]: Panicked at 'called `Result::unwrap()` on an `Err` value: FromUtf8Error { bytes: [192, 255, 238], error: Utf8Error { valid_up_to: 0, error_len: Some(1) } }', src/lib.rs:51:47 -[68. 2024-05-22T12:38:00.621855713Z]: right before timer trap -[69. 2024-05-22T12:38:00.621855713Z]: [TRAP]: timer trap +[19. 2024-05-23T08:33:11.319493785Z]: right before timer trap +[20. 2024-05-23T08:33:11.319493785Z]: [TRAP]: timer trap +[21. 2024-05-23T08:33:14.229855179Z]: hi! +[22. 2024-05-23T08:33:16.413512126Z]: right before timer trap +[23. 2024-05-23T08:33:16.413512126Z]: [TRAP]: timer trap +[24. 2024-05-23T08:33:18.622686552Z]: hello! +[25. 2024-05-23T08:33:21.519088681Z]: right before timer trap +[26. 2024-05-23T08:33:21.519088681Z]: [TRAP]: timer trap +[27. 2024-05-23T08:33:22.96101893Z]: yey! +[28. 2024-05-23T08:33:26.601860526Z]: right before timer trap +[29. 2024-05-23T08:33:26.601860526Z]: [TRAP]: timer trap +[30. 2024-05-23T08:33:28.039227914Z]: right before trap +[31. 2024-05-23T08:33:28.039227914Z]: [TRAP]: oops! +[32. 2024-05-23T08:33:31.634215234Z]: right before timer trap +[33. 2024-05-23T08:33:31.634215234Z]: [TRAP]: timer trap +[34. 2024-05-23T08:33:35.96761902Z]: right before memory out of bounds +[35. 2024-05-23T08:33:35.96761902Z]: [TRAP]: StableMemory range out of bounds +[36. 2024-05-23T08:33:36.712223153Z]: right before timer trap +[37. 2024-05-23T08:33:36.712223153Z]: [TRAP]: timer trap ... -``` + +``` \ No newline at end of file diff --git a/rust/composite_query/README.md b/rust/composite_query/README.md index 530a30111..82c6b267b 100644 --- a/rust/composite_query/README.md +++ b/rust/composite_query/README.md @@ -1,17 +1,18 @@ ---- -keywords: [intermediate, rust, composite query, queries] ---- - # Composite queries -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/composite_query) +### Prerequisites +This example requires an installation of: + +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +Begin by opening a terminal window. -## Building the example +## Step 1: Setup the project environment We first need to build the data partition backend canister. ```bash -git clone https://github.com/dfinity/examples cd examples/rust/composite_query dfx start --background dfx canister create data_partition @@ -26,7 +27,7 @@ dfx build kv_frontend dfx canister install kv_frontend ``` -## Using the canister +## Step 2: Using the canister Now we add some key value pairs via the frontend canister. diff --git a/rust/counter/README.md b/rust/counter/README.md index 0206f18ec..2f2ab37b6 100644 --- a/rust/counter/README.md +++ b/rust/counter/README.md @@ -1,12 +1,8 @@ ---- -keywords: [beginner, rust, counter] ---- - # Counter -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/counter) +This example demonstrates a counter application. -## Prerequisites +### Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). @@ -14,38 +10,41 @@ This example requires an installation of: Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Step 1: Setup the project environment + +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: + ```bash cd examples/rust/counter dfx start --background ``` -### Step 2: Test the canister: +## Step 2: Test the canister ```bash cargo test ``` -### Step 3: Deploy the canister: +## Step 3: Deploy the canister ```bash dfx deploy ``` -### Step 4: Set the value of the counter: +## Step 4: Set the value of the counter ```bash dfx canister call counter set '(7)' ``` -### Step 5: Increment the value of the counter: +## Step 5: Increment the value of the counter ```bash dfx canister call counter inc ``` -### Step 6: Get the value of the counter: +## Step 6: Get the value of the counter ```bash dfx canister call counter get diff --git a/rust/defi/README.md b/rust/defi/README.md index 8d2b6a6a4..40ab42db7 100644 --- a/rust/defi/README.md +++ b/rust/defi/README.md @@ -4,7 +4,7 @@ To enable DeFi applications on the IC, canisters need to interact with token canisters and the ledger canister. This sample dapp illustrates how to facilitate these interactions. You can see a quick introduction on [YouTube](https://youtu.be/fLbaOmH24Gs). -The sample exchange is implemented in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/defi) and [Rust](https://github.com/dfinity/examples/tree/master/rust/defi) and can be seen [running on the IC](https://gzz56-daaaa-aaaal-qai2a-cai.ic0.app/). +The sample exchange is implemented in [Rust](https://github.com/dfinity/examples/tree/master/rust/defi) and can be seen [running on the IC](https://gzz56-daaaa-aaaal-qai2a-cai.ic0.app/). ## Architecture @@ -79,19 +79,16 @@ After depositing funds to the exchange, the user can place orders. An order cons Compared to depositing funds, withdrawing funds is simpler. Since the exchange has custody of the funds, the exchange will send funds back to the user on `withdraw` requests. The internal exchange balances are adjusted accordingly. ## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Download [cmake](https://cmake.org/). -- [x] Download [npm](https://nodejs.org/en/download/). -- [x] If you want to deploy the Rust version, make sure you add Wasm as a target: +- [x] Add Wasm as a target: `rustup target add wasm32-unknown-unknown` - ## Step 1: Download the project's GitHub repo and install the dependencies: -``` +```bash git clone --recurse-submodules --shallow-submodules https://github.com/dfinity/examples.git -# for the rust implementation examples/rust/defi -cd examples/motoko/defi +cd examples/rust/defi make install ``` @@ -105,35 +102,31 @@ http://127.0.0.1:4943?canisterId=by6od-j4aaa-aaaaa-qaadq-cai or you can regenerate the URL "http://127.0.0.1:4943?canisterId=$(dfx canister id frontend)". Open this URL in a web browser. -## Step 2: To interact with the exchange, you can create a local Internet Identity by clicking the login button. +## Step 2: Create a local Internet Identity by clicking the login button This sample project uses a local test version of Internet Identity. Do not use your mainnet Internet Identity, and this testnet Internet Identity will not work on the mainnet. -## Step 3: When prompted, select **Create Internet Identity**. - +## Step 3: When prompted, select **Create Internet Identity** -## Step 4: Then select **Create Passkey**. +## Step 4: Then select **Create Passkey** -## Step 5: Complete the CAPTCHA. +## Step 5: Complete the CAPTCHA -## Step 6: Save the II number and click **I saved it, continue**. +## Step 6: Save the II number and click **I saved it, continue** -## Step 7: You will be redirected to the exchange's frontend webpage. +You will be redirected to the exchange's frontend webpage +## Step 7: Get tokens -## Step 8: You can give yourself some tokens and ICP by running an initialization script with your II principal that you can copy from the frontend. - - -## Step 9: Then run the following command: +You can give yourself some tokens and ICP by running an initialization script with your II principal that you can copy from the frontend `make init-local II_PRINCIPAL=` -## Step 10: Refresh the web browser to verify that your tokens were deposited. - +## Step 8: Refresh the web browser to verify that your tokens were deposited. To trade tokens with yourself, you can open a second incognito browser window. diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index ed4157991..016d35ffa 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -1,18 +1,12 @@ ---- -keywords: [advanced, rust, nft, dip721] ---- - # DIP721 NFT -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container) - This example demonstrates implementing an NFT canister. NFTs (non-fungible tokens) are unique tokens with arbitrary metadata, usually an image of some kind, to form the digital equivalent of trading cards. There are a few different NFT standards for the Internet Computer (e.g [EXT](https://github.com/Toniq-Labs/extendable-token), [IC-NFT](https://github.com/rocklabs-io/ic-nft)), but this tutorial will use [DIP-721](https://github.com/Psychedelic/DIP721). You can see a quick introduction on [YouTube](https://youtu.be/1po3udDADp4). The canister is a basic implementation of the standard, with support for the minting, burning, and notification interface extensions. -The sample code is available in the [samples repository](https://github.com/dfinity/examples) in [Rust](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container) and [Motoko](https://github.com/dfinity/examples/tree/master/motoko/dip721-nft-container). +The sample code is available in the [samples repository](https://github.com/dfinity/examples) in [Rust](https://github.com/dfinity/examples/tree/master/rust/dip721-nft-container). Command-line length limitations would prevent you from minting an NFT with a large file, like an image or video, via `dfx`. To that end, there is a [command-line minting tool](https://github.com/dfinity/experimental-minting-tool) provided for minting simple NFTs. @@ -94,24 +88,23 @@ It contains six NFTs, so you can look at items from `/0/0` to `/` wi Remember that query functions are uncertified; the result of functions like `ownerOfDip721` can be modified arbitrarily by a single malicious node. If queried information is depended on, for example, if someone might send ICP to the owner of a particular NFT to buy it from them, those calls should be performed as update calls instead. You can force an update call by passing the `--update` flag to `dfx` or using the `Agent::update` function in `agent-rs`. - ### Step 5: Mint an NFT. +### Step 4: Mint an NFT Due to size limitations on the length of a terminal command, an image- or video-based NFT would be impossible to send via `dfx`. To that end, there is an experimental [minting tool](https://github.com/dfinity/experimental-minting-tool) you can use to mint a single-file NFT. diff --git a/rust/face-recognition/README.md b/rust/face-recognition/README.md index 1305fc352..17bc0b97c 100644 --- a/rust/face-recognition/README.md +++ b/rust/face-recognition/README.md @@ -1,11 +1,11 @@ -# ICP Face Recognition +# ICP face recognition This is an ICP smart contract runs face detection and face recognition of user's photo that can be uploaded either from a camera or a local file. The smart contract consists of two canisters: -- the backend canister embeds the [the Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings. -- the frontend canister contains the Web assets such as HTML, JS, CSS that are served to the browser. +- The backend canister embeds the [the Tract ONNX inference engine](https://github.com/sonos/tract) with two ONNX models. One model is used to detect a face in the photo and return its bounding box. Another model is used for computing face embeddings. +- The frontend canister contains the Web assets such as HTML, JS, CSS that are served to the browser. # Models @@ -17,6 +17,7 @@ A face detection model finds the bounding box of a face in the image. You can download [Ultraface](https://github.com/onnx/models/tree/main/validated/vision/body_analysis/ultraface) - ultra-lightweight face detection model - [[here](https://github.com/onnx/models/blob/bec48b6a70e5e9042c0badbaafefe4454e072d08/validated/vision/body_analysis/ultraface/models/version-RFB-320.onnx)]. Alternatively, you can run + ``` ./download-face-detection-model.sh ``` @@ -26,17 +27,18 @@ Alternatively, you can run A face recognition model computes a vector embedding of an image with a face. You can obtain a pretrained model from [facenet-pytorch](https://github.com/timesler/facenet-pytorch) as follows. +- #### Step 1: Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/. -1. Install `python` and `pip`: https://packaging.python.org/en/latest/tutorials/installing-packages/. +- #### Step 2: Install `facenet-pytorch` and `torch`: -2. Install `facenet-pytorch` and `torch`: ``` pip install facenet-pytorch pip install torch pip install onnx ``` -3. Export ONNX model. Start a python shell and run the following commands or create a python file and run it: +- #### Step 3: Export ONNX model. Start a python shell and run the following commands or create a python file and run it: + ``` import torch import facenet_pytorch @@ -45,29 +47,17 @@ input = torch.randn(1, 3, 160, 160) torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_version=11) ``` -4. This should produce `face-recognition.onnx`. Copy the file to the root of this repository. - -# Dependencies - -Install `dfx`, Rust, etc: https://internetcomputer.org/docs/current/developer-docs/getting-started/hello-world - -Install `wasi2ic`: -- Follow the steps in https://github.com/wasm-forge/wasi2ic -- Make sure that `wasi2ic` binary is in your `$PATH`. - -Install NodeJS dependencies for the frontend: +- #### Step 4: This should produce `face-recognition.onnx`. Copy the file to the root of this repository. -``` -npm install -``` - -Install `wasm-opt`: +### Prerequisites -``` -cargo install wasm-opt -``` +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] Install `wasi2ic`: Follow the steps in https://github.com/wasm-forge/wasi2ic and make sure that `wasi2ic` binary is in your `$PATH`. +- [x] Install `wasm-opt`: `cargo install wasm-opt` -# Build +## Build the application ``` dfx start --background @@ -77,7 +67,7 @@ dfx deploy If the deployment is successful, the it will show the `frontend` URL. Open that URL in browser to interact with the smart contract. -# Chunk uploading of models +## Chunk uploading of models Since the models are large, they cannot be embedded into the Wasm binary of the smart contract. Instead they should be uploaded separately. @@ -91,6 +81,7 @@ cargo install ic-file-uploader ``` Afterwards, execute the `upload-models-to-canister.sh` script, which runs the following commands: + ``` dfx canister call backend clear_face_detection_model_bytes dfx canister call backend clear_face_recognition_model_bytes @@ -99,7 +90,7 @@ ic-file-uploader backend append_face_recognition_model_bytes face-recognition.on dfx canister call backend setup_models ``` -# Credits +## Credits Thanks to [DecideAI](https://decideai.xyz/) for discussions and providing [ic-file-uploader](https://github.com/modclub-app/ic-file-uploader/tree/main). diff --git a/rust/guards/README.md b/rust/guards/README.md index 8fc09fb5a..b1f65d454 100644 --- a/rust/guards/README.md +++ b/rust/guards/README.md @@ -1,14 +1,14 @@ -# Guards and Async Code +# Guards and async code ## Summary -This example canister shows some advanced behaviour between guards and asynchronous code. This example is meant for Rust +This example canister shows some advanced behavior between guards and asynchronous code. This example is meant for Rust canister developers that are already familiar with [asynchronous code](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/advanced-features/async-code/) and the security best-practices related to [inter-canister calls and rollbacks](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#inter-canister-calls-and-rollbacks). -## Guard to Maintain Invariants +## Guard to maintain invariants This example canister stores a bunch of items on the heap, where each item is simply modelled as a `String`. One invariant that the canister aims at maintaining is that each item is **processed at most once**, where processing an @@ -19,7 +19,7 @@ One tricky part in this scenario is that an item can therefore only be marked as has completed, meaning in the callback. As mentioned in the [security best-practices](https://internetcomputer.org/docs/current/developer-docs/security/rust-canister-development-security-best-practices#securely-handle-traps-in-callbacks), it's not always feasible to guarantee that the callback will not trap, which in that case would break the invariant due -to the state being rollbacked. +to the state being rolled back. The standard solution to maintain such an invariant, despite a potential panic in the callback is to use a guard. However, this example canister shows that it's also crucially important that the declaration of the guard happens in @@ -27,41 +27,41 @@ another message than the callback, which is the case for true asynchronous code etc.). It's in particular not enough to `await` a function that's declared to be `async`, since if the future can polled until completion directly, everything will be executed in a single message. -## Automated Integration Tests +## Automated integration tests -To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run +To run the integration tests under `tests/` install [PocketIC server](https://github.com/dfinity/pocketic) and then run: ```shell cargo build --target wasm32-unknown-unknown --release && cargo test ``` -## Manual Testing with `dfx` +## Manual testing with `dfx` ### Setup -Start `dfx` +Start `dfx`: ```shell dfx start --background ``` -and then proceed to deploying the canister +Deploy the canister: ```shell dfx deploy ``` -You should now be able to query the canister, e.g., to check if an item is processed +You should now be able to query the canister, e.g., to check if an item is processed: ```shell dfx canister call guards is_item_processed 'mint' ``` -which should return `(null)` since the canister currently has an empty state. +This should return `(null)` since the canister currently has an empty state. ### Test -As an example, we show how the behaviour tested in `should_process_single_item_and_mark_it_as_processed` can be tested +As an example, we show how the behavior tested in `should_process_single_item_and_mark_it_as_processed` can be tested manually. Set the item `"mint"` to be processed: @@ -84,7 +84,7 @@ Process the item by calling the *panicking* callback: dfx canister call guards process_single_item_with_panicking_callback '("mint", variant { TrueAsyncCall })' ``` -Since the queried endpoint panicks on purpose, expect some error message similar to +Since the queried endpoint panics on purpose, expect some error message similar to: ```text 2024-05-29 11:54:39.817800 UTC: [Canister bkyz2-fmaaa-aaaaa-qaaaq-cai] Panicked at 'panicking callback!', src/lib.rs:47:5 @@ -93,10 +93,10 @@ Caused by: Failed update call. The replica returned a rejection error: reject code CanisterError, reject message Canister bkyz2-fmaaa-aaaaa-qaaaq-cai trapped explicitly: Panicked at 'panicking callback!', src/lib.rs:47:5, error code None ``` -Ensure that the guard was executed to ensure that the item is marked as processed despite the previous panic +Ensure that the guard was executed to ensure that the item is marked as processed despite the previous panic: ```shell dfx canister call guards is_item_processed 'mint' ``` -should return `(opt true)`. +This should return `(opt true)`. diff --git a/rust/hello/README.md b/rust/hello/README.md index 5be675357..b093d864a 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -1,12 +1,5 @@ ---- -keywords: [beginner, rust, hello] ---- - # Hello, world! -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/hello) - -## Overview This sample demonstrates a simple dapp consisting of two canisters: - A simple backend canister, `hello`, implementing the logic of the application. @@ -19,9 +12,9 @@ It is the dapp equivalent of the ubiquitous 'Hello, world!' and can be seen runn This sample is based on the default project created by running `dfx new` as described in the quick start documents. -The sample code is available from the [samples](https://github.com/dfinity/examples) repository in both [Motoko](https://github.com/dfinity/examples/tree/master/motoko/hello) and [Rust](https://github.com/dfinity/examples/tree/master/rust/hello). +The sample code is available from the [samples](https://github.com/dfinity/examples) repository in [Rust](https://github.com/dfinity/examples/tree/master/rust/hello). -Canister `hello`, whether implemented in Motoko or Rust, presents the same Candid interface: +Canister `hello` presents the following Candid interface: ```candid service : { greet: (text) -> (text); @@ -36,53 +29,42 @@ The frontend canister and its assets are identical for both projects. This example demonstrates a dead simple dapp consisting of two canister smart contracts: -- A simple backend canister, hello, implementing the logic of the application in Motoko. +- A simple backend canister, hello, implementing the logic of the application in Rust. - A simple frontend asset canister, hello_assets serving the assets of the dapp's web user interface. This example is based on the default project created by running `dfx new hello`. This example is based on the default project created by running `dfx new --type=rust hello`. -### Prerequisites +### Prerequisites + This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install `node.js` (to build the web frontend). - - ### Step 1: Open a terminal window. -If you haven't already, create a default project with the command: -``` -dfx new --type=rust hello -cd hello -``` +## Step 1: Open a terminal window - ### Step 2: Start a local canister execution environment: +Start an instance of the local replica and create a default project with the command: ``` dfx start --background +dfx new --type=rust hello +cd hello ``` - ### Step 3: Ensure that the required node modules are available in your project directory, if needed, by running the following command: - -``` -npm install -``` - - ### Step 4: Register, build, and deploy the project with the command: +## Step 2: Register, build, and deploy the project ``` dfx deploy -npm start ``` - ### Step 5: Call the hello canister's greet function: +## Step 3: Call the hello canister's `greet` function ``` dfx canister call hello_backend greet everyone ``` - ### Step 6: Observe the following result: +## Step 4: Observe the following result ``` ("Hello, everyone!") @@ -90,16 +72,17 @@ dfx canister call hello_backend greet everyone The previous steps use `dfx` to directly call the function on the hello (backend) canister. To access the web user interface of the dapp, that is served by canister hello_assets, do the following: - ### Step 7: Determine the URL of the hello_frontend asset canister. +## Step 5: Determine the URL of the hello_frontend asset canister ``` echo "http://localhost:8000/?canisterId=$(dfx canister id hello_frontend)" ``` - ### Step 8: Navigate to the URL in your browser. +## Step 6: Navigate to the URL in your browser + The browser should display a simple HTML page with a sample asset image file, an input field, and a button. - ### Step 9: Enter the text "everyone" and click the button to see the greeting returned by the backend hello canister. +## Step 7: Enter the text "everyone" and click the button to see the greeting returned by the backend hello canister. ### Troubleshooting If the web page doesn't display properly or displays the wrong content, you may need to clear your browser cache. diff --git a/rust/icp_transfer/README.md b/rust/icp_transfer/README.md index d3f266c65..f4dbe96bd 100644 --- a/rust/icp_transfer/README.md +++ b/rust/icp_transfer/README.md @@ -1,9 +1,5 @@ # ICP transfer -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/icp_transfer). - -## Overview - ICP transfer is a canister that can transfer ICP from its account to other accounts. It is an example of a canister that uses the ledger canister. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/icp_transfer) and [Rust](https://github.com/dfinity/examples/tree/master/rust/icp_transfer). :::info @@ -17,54 +13,42 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -## Prerequisites - -This example requires an installation of: - -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) - -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. +### Prerequisites -:::info - -If you just want to interact with this example, follow steps 4-8 and 10-13 below. +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. -::: +## Step 1: Setup project environment -### Step 1: Create a new `dfx` project and navigate into the project's directory. +Start a local instance of the replica and create a new project with the commands: -```bash +``` +dfx start --background dfx new --type=rust icp_transfer --no-frontend cd icp_transfer ``` ### Step 2: Determine ledger file locations -:::info +> [!TIP] +> You can read more about how to [setup the ICP ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icp-tokens/ledger-local-setup). -You can read more about how to [setup the ICP ledger locally](https://internetcomputer.org/docs/current/developer-docs/defi/icp-tokens/ledger-local-setup). +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -::: - -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. - -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz`. -The URL for the ledger.did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did`. +The URL for the ledger.did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did`. [OPTIONAL] If you want to make sure you have the latest ICP ledger files, you can run the following script. Please ensure that you have [`jq`](https://jqlang.github.io/jq/) installed as the script relies on it. ```sh -curl -o download_latest_icp_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/00a4ab409e6236d4082cee4a47544a2d87b7190d/rs/rosetta-api/scripts/download_latest_icp_ledger.sh" +curl -o download_latest_icp_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icp_ledger.sh" chmod +x download_latest_icp_ledger.sh ./download_latest_icp_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2: @@ -78,8 +62,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icp_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icp_ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ledger-canister.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icp_ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ledger-canister.wasm.gz", "remote": { "id": { "ic": "ryjl3-tyaaa-aaaaa-aaaba-cai" @@ -98,13 +82,7 @@ Replace its contents with this but adapt the URLs to be the ones you determined } ``` -### Step 4: Start a local replica: - -```bash -dfx start --background --clean -``` - -### Step 5: Create a new identity that will work as a minting account: +## Step 4: Create a new identity that will work as a minting account ```bash dfx identity new minter --storage-mode plaintext @@ -115,14 +93,14 @@ export MINTER_ACCOUNT_ID=$(dfx ledger account-id) > [!IMPORTANT] > Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. -### Step 6: Switch back to your default identity and record its ledger account identifier: +## Step 5: Switch back to your default identity and record its ledger account identifier ```bash dfx identity use default export DEFAULT_ACCOUNT_ID=$(dfx ledger account-id) ``` -### Step 7: Deploy the ledger canister to your network: +## Step 6: Deploy the ledger canister to your network Take a moment to read the details of the call made below. Not only are you deploying the ICP ledger canister, you are also: @@ -165,7 +143,7 @@ URLs: icp_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=ryjl3-tyaaa-aaaaa-aaaba-cai ``` -### Step 8: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 7: Verify that the ledger canister is healthy and working as expected ```bash dfx canister call icp_ledger_canister account_balance '(record { account = '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$DEFAULT_ACCOUNT_ID'")]) + "}")')'})' @@ -177,7 +155,7 @@ The output should be: (record { e8s = 10_000_000_000 : nat64 }) ``` -### Step 9: Prepare the token transfer canister: +## Step 8: Prepare the token transfer canister Replace the contents of the `src/icp_transfer_backend/Cargo.toml` file with the following: @@ -275,26 +253,23 @@ service : { ``` -### Step 10: Deploy the token transfer canister: +## Step 9: Deploy the token transfer canister ```bash dfx deploy icp_transfer_backend ``` -### Step 11: Determine out the address of your canister: +## Step 10: Determine out the address of your canister ```bash TOKENS_TRANSFER_ACCOUNT_ID="$(dfx ledger account-id --of-canister icp_transfer_backend)" TOKENS_TRANSFER_ACCOUNT_ID_BYTES="$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$TOKENS_TRANSFER_ACCOUNT_ID'")]) + "}")')" ``` -### Step 12: Transfer funds to your canister: - -:::info +## Step 11: Transfer funds to your canister -Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. - -::: +> [!TIP] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. Make the following call to transfer funds to the canister: @@ -308,7 +283,7 @@ If successful, the output should be: (variant { Ok = 1 : nat64 }) ``` -### Step 13: Transfer funds from the canister: +## Step 12: Transfer funds from the canister Now that the canister owns ICP on the ledger, you can transfer funds from the canister to another account, in this case back to the default account: diff --git a/rust/image-classification/README.md b/rust/image-classification/README.md index 500a95bc0..49432d7d6 100644 --- a/rust/image-classification/README.md +++ b/rust/image-classification/README.md @@ -1,4 +1,4 @@ -# ICP Image Classification +# ICP image classification This is an ICP smart contract that accepts an image from the user and runs image classification inference. The smart contract consists of two canisters: @@ -10,42 +10,19 @@ The smart contract consists of two canisters: This example uses Wasm SIMD instructions that are available in `dfx` version `0.20.2-beta.0` or newer. -# Dependencies +## Prerequisites -Install `dfx`, Rust, etc: https://internetcomputer.org/docs/current/developer-docs/getting-started/hello-world +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +- [x] Install WASI SDK 21: + - [x] Install `wasi-skd-21.0` from https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21 + - [x] Export `CC_wasm32_wasi` in your shell such that it points to WASI clang and sysroot. Example: `export CC_wasm32_wasi="/path/to/wasi-sdk-21.0/bin/clang --sysroot=/path/to/wasi-sdk-21.0/share/wasi-sysroot` +- [x] Install `wasi2ic`: Follow the steps in https://github.com/wasm-forge/wasi2ic and make sure that `wasi2ic` binary is in your `$PATH`. +- [x] Download MobileNet v2-7 to `src/backend/assets/mobilenetv2-7.onnx`: `./downdload_model.sh` +- [x] Install `wasm-opt`: `cargo install wasm-opt` -Install WASI SDK 21: - -- Install `wasi-skd-21.0` from https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21 -- Export `CC_wasm32_wasi` in your shell such that it points to WASI clang and sysroot. Example: - -``` -export CC_wasm32_wasi="/path/to/wasi-sdk-21.0/bin/clang --sysroot=/path/to/wasi-sdk-21.0/share/wasi-sysroot" -``` - -Install `wasi2ic`: -- Follow the steps in https://github.com/wasm-forge/wasi2ic -- Make sure that `wasi2ic` binary is in your `$PATH`. - -Download MobileNet v2-7 to `src/backend/assets/mobilenetv2-7.onnx`: - -``` -./downdload_model.sh -``` - -Install NodeJS dependencies for the frontend: - -``` -npm install -``` - -Install `wasm-opt`: - -``` -cargo install wasm-opt -``` - -# Build +## Build the application ``` dfx start --background diff --git a/rust/nft-wallet/README.md b/rust/nft-wallet/README.md index 2309eb417..23652a33a 100644 --- a/rust/nft-wallet/README.md +++ b/rust/nft-wallet/README.md @@ -1,24 +1,16 @@ ---- -keywords: [advanced, rust, nft, dip721] ---- - # NFT wallet -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/nft-wallet) - -## Overview - This is an NFT wallet example dapp that utilizes minted NFTs from the Rust dip721-nft-container. Among some of its essential features, the wallet can register NFTs, transfer out NFTs, and check how many NFTs it contains. This dapp includes a frontend UI for interaction. -## Prerequisites -This example requires an installation of: +### Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Begin by opening a terminal window. +## Step 1: Setup project environment -### Step 1: You can deploy the dapp using the `start.sh` script: +You can deploy the dapp using the `start.sh` script: ```bash cd examples/rust/nft-wallet @@ -38,13 +30,13 @@ cd .. ./deploy.sh ``` -### Step 2: If you'd like to deploy on the IC network run the command: +If you'd like to deploy on the mainnet, run the command: ```bash ./deploy.sh --network ic ``` -### Step 3: Make calls against NFT wallet canister: +## Step 2: Make calls against NFT wallet canister For example, to to transfer an NFT use the command: diff --git a/rust/parallel_calls/README.md b/rust/parallel_calls/README.md index 3e0bba4f4..95db32030 100644 --- a/rust/parallel_calls/README.md +++ b/rust/parallel_calls/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, defi] ---- - # Parallel inter-canister calls -[View this sample code on GitHub](https://github.com/dfinity/examples/tree/master/rust/parallel_calls). - -## Overview - This example demonstrates how to implement inter-canister calls that run in parallel in Rust, and highlights some differences between parallel and sequential calls. Running independent calls in parallel can lower the latency, especially when messages are sent across subnets. For example, a canister that swaps two tokens might want to launch both token transfer operations in parallel. ## Architecture @@ -18,38 +10,37 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -## Prerequisites +### Prerequisites -To run this example you should: - -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running the example - Begin by opening a terminal window. -### Step 1: Navigate into the example folder and start a local Internet Computer replica +## Step 1: Setup project environment + +Navigate into the folder containing the project's files and start a local instance of the replica with the commands: ```bash cd examples/rust/parallel_calls dfx start --background ``` -### Step 2: Deploy the canister +## Step 2: Deploy the canisters ```bash dfx deploy ``` -### Step 3: Set up the caller canister +## Step 3: Set up the caller canister We now provide the ID of the callee to the caller, such that the caller can initiate calls. ``` dfx canister call caller setup_callee "(principal \"`dfx canister id callee`\")" ``` -### Step 4: Invoke sequential and parallel calls +## Step 4: Invoke sequential and parallel calls Let's first call the different endpoints of the `caller` canister using `dfx` @@ -102,7 +93,7 @@ All the sequential calls succeed, but most parallel calls fail. The reason is th Lastly, the parallel calls here complete sooner -- because most of them fail! -### Step 5: Multi-subnet setting +## Step 5: Multi-subnet setting Parallel calls are a lot more useful in multi-subnet settings. We can create such a setting locally using Pocket IC. diff --git a/rust/performance_counters/README.md b/rust/performance_counters/README.md index a158c2e6e..218fab4b6 100644 --- a/rust/performance_counters/README.md +++ b/rust/performance_counters/README.md @@ -1,14 +1,6 @@ ---- -keywords: [intermediate, rust, performance, canister performance, counter] ---- - # Performance counter -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/performance_counters) - -## Overview - -The canister can query one of the "performance counters", which is a deterministic monotonically increasing integer approximating the amount of work the canister has done. Developers might use this data to profile and optimize the canister performance. +A canister can query one of the "performance counters", which is a deterministic monotonically increasing integer approximating the amount of work the canister has done. Developers might use this data to profile and optimize the canister performance. ```Candid ic0.performance_counter : (counter_type : i32) -> i64 @@ -39,21 +31,18 @@ In the future, ICP might expose more performance counters. ## Prerequisites -This example requires an installation of: +## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC + SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Step 1: Begin by opening a terminal window and navigating into the project's directory - -```sh -cd examples/rust/performance_counters -``` +## Step 1: Setup project environment -### Step 2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/performance_counters dfx start --clean ``` @@ -62,18 +51,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -### Step 3: Open another terminal window in the same directory +## Step 2: Open another terminal window in the same directory ```sh cd examples/rust/performance_counters ``` -### Step 4: Compile and deploy `performance_counters` canister +## Step 3: Compile and deploy `performance_counters` canister ```sh dfx deploy @@ -90,7 +79,7 @@ URLs: performance_counters: http://127.0.0.1/... ``` -### Step 5: Call `performance_counters` canister `for_update` method +## Step 4: Call `performance_counters` canister `for_update` method ```sh dfx canister call performance_counters for_update @@ -105,7 +94,7 @@ Example output: Note, how the current message execution counter (~6M instructions) is much different from the call context counter (~19M instructions). -### Step 6: Check the Internet Computer replica terminal window for more details +## Step 5: Check the replica terminal window for more details Example replica log output: @@ -123,7 +112,7 @@ By contrast, the call context performance counter (1) is monotonically increasin Also note, that both counters start over for each nested execution (~12K instructions). -### Step 7: Repeat the steps above calling `for_composite_query` method +## Step 6: Repeat the steps above calling `for_composite_query` method ```sh dfx canister call performance_counters for_composite_query diff --git a/rust/periodic_tasks/README.md b/rust/periodic_tasks/README.md index 3e68e1c71..62fe33fc9 100644 --- a/rust/periodic_tasks/README.md +++ b/rust/periodic_tasks/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, periodic, timer, heartbeats] ---- - # Periodic tasks and timers -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/periodic_tasks) - -## Overview - Unlike other blockchains, the Internet Computer can automatically execute canister smart contracts after a specified delay or periodically. There are two ways to schedule an automatic canister execution on the IC: From 323c7689ca1478a48b11cadf50c56d566a12b230 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 15:39:54 -0600 Subject: [PATCH 02/11] Update rust readmes --- rust/basic_bitcoin/README.md | 10 +- rust/basic_dao/README.md | 2 +- rust/basic_ethereum/README.md | 2 +- rust/canister-snapshots/README.md | 2 +- rust/canister_logs/README.md | 2 +- rust/composite_query/README.md | 2 +- rust/counter/README.md | 2 +- rust/dip721-nft-container/README.md | 2 +- rust/face-recognition/README.md | 2 +- rust/hello/README.md | 2 +- rust/icp_transfer/README.md | 2 +- rust/nft-wallet/README.md | 2 +- rust/parallel_calls/README.md | 2 +- rust/performance_counters/README.md | 5 +- rust/periodic_tasks/README.md | 75 ++++----- rust/pub-sub/README.md | 29 ++-- rust/qrcode/README.md | 21 +-- rust/query_stats/README.md | 37 ++--- rust/send_http_get/README.md | 18 +-- rust/send_http_post/README.md | 22 +-- rust/simd/README.md | 59 ++----- rust/threshold-ecdsa/README.md | 158 +++++-------------- rust/threshold-schnorr/README.md | 230 ++++++++-------------------- rust/token_transfer/README.md | 76 ++++----- rust/token_transfer_from/README.md | 78 ++++------ rust/vetkd/README.md | 34 ++-- rust/x509/README.md | 34 ++-- 27 files changed, 293 insertions(+), 617 deletions(-) diff --git a/rust/basic_bitcoin/README.md b/rust/basic_bitcoin/README.md index 6341aa5ea..53eab4760 100644 --- a/rust/basic_bitcoin/README.md +++ b/rust/basic_bitcoin/README.md @@ -1,4 +1,4 @@ -# Basic Bitcoin +# Basic Bitcoin This tutorial will walk you through how to deploy a sample [canister smart contract](https://internetcomputer.org/docs/current/developer-docs/multi-chain/bitcoin/overview) **that can send and receive Bitcoin** on the Internet Computer. @@ -14,7 +14,7 @@ of the Internet Computer. For a deeper understanding of the ICP < > BTC integration, see the [Bitcoin integration documentation](https://wiki.internetcomputer.org/wiki/Bitcoin_Integration). -### Prerequisites +## Prerequisites * [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). @@ -111,7 +111,7 @@ from three types of addresses: key. This precaution is to prevent attacks that can occur when creating taproot multisigner addresses using specific multisignature schemes. However, the Schnorr API of the internet computer does not support Schnorr - multisignatures. + multisignatures. 3. A [P2TR address](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki) where the funds can be spent using the provided public key with the script @@ -209,7 +209,7 @@ reflected in your current balance. ## Step 6: Retrieving block headers -You can also get a range of Bitcoin block headers by using the `get_block_headers` +You can also get a range of Bitcoin block headers by using the `get_block_headers` endpoint on your canister. In the Candid UI, write the desired start height and optionally end height, and click on "Call": @@ -233,7 +233,7 @@ In this tutorial, you were able to: * Connect the canister to the Bitcoin testnet. * Send the canister some testnet BTC. * Check the testnet BTC balance of the canister. -* Use the canister to send testnet BTC to another testnet BTC address. +* Use the canister to send testnet BTC to another testnet BTC address. This example is extensively documented in the following tutorials: diff --git a/rust/basic_dao/README.md b/rust/basic_dao/README.md index 21a8e403b..c374649e9 100644 --- a/rust/basic_dao/README.md +++ b/rust/basic_dao/README.md @@ -10,7 +10,7 @@ Certain system parameters, like the number of `Yes` votes needed to pass a propo View the [canister service definition](https://github.com/dfinity/examples/blob/master/rust/basic_dao/src/basic_dao/src/basic_dao.did) for more details. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] The Rust toolchain (e.g. cargo). diff --git a/rust/basic_ethereum/README.md b/rust/basic_ethereum/README.md index 0297369ca..9ac78f9e6 100644 --- a/rust/basic_ethereum/README.md +++ b/rust/basic_ethereum/README.md @@ -14,7 +14,7 @@ features of the Internet Computer. For a deeper understanding of the ICP < > ETH integration, see the [Ethereum integration overview](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/overview). -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). diff --git a/rust/canister-snapshots/README.md b/rust/canister-snapshots/README.md index 2b222378b..d57b2c83c 100644 --- a/rust/canister-snapshots/README.md +++ b/rust/canister-snapshots/README.md @@ -6,7 +6,7 @@ The `remove_spam` canister method intentionally includes a bug to simulate data The example outlines the steps to install the canister, create a snapshot, and subsequently restore the data after the simulated data loss. -### Prerequisites +## Prerequisites This example requires an installation of: diff --git a/rust/canister_logs/README.md b/rust/canister_logs/README.md index 38f0a52ae..ad5c3ca0b 100644 --- a/rust/canister_logs/README.md +++ b/rust/canister_logs/README.md @@ -1,6 +1,6 @@ # Canister logs -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/composite_query/README.md b/rust/composite_query/README.md index 82c6b267b..1de116005 100644 --- a/rust/composite_query/README.md +++ b/rust/composite_query/README.md @@ -1,6 +1,6 @@ # Composite queries -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/rust/counter/README.md b/rust/counter/README.md index 2f2ab37b6..de2a5216a 100644 --- a/rust/counter/README.md +++ b/rust/counter/README.md @@ -2,7 +2,7 @@ This example demonstrates a counter application. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). diff --git a/rust/dip721-nft-container/README.md b/rust/dip721-nft-container/README.md index 016d35ffa..38c3dad98 100644 --- a/rust/dip721-nft-container/README.md +++ b/rust/dip721-nft-container/README.md @@ -86,7 +86,7 @@ A running instance of the Rust canister for demonstration purposes is available The interface is meant to be programmatic, but the Rust version additionally contains HTTP functionality so you can view a metadata file at `//`. It contains six NFTs, so you can look at items from `/0/0` to `/5/0`. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` diff --git a/rust/face-recognition/README.md b/rust/face-recognition/README.md index 17bc0b97c..bf6ea0903 100644 --- a/rust/face-recognition/README.md +++ b/rust/face-recognition/README.md @@ -49,7 +49,7 @@ torch.onnx.export(resnet, input, "face-recognition.onnx", verbose=False, opset_v - #### Step 4: This should produce `face-recognition.onnx`. Copy the file to the root of this repository. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/hello/README.md b/rust/hello/README.md index b093d864a..c3937ed5b 100644 --- a/rust/hello/README.md +++ b/rust/hello/README.md @@ -36,7 +36,7 @@ This example is based on the default project created by running `dfx new hello`. This example is based on the default project created by running `dfx new --type=rust hello`. -### Prerequisites +## Prerequisites This example requires an installation of: - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). diff --git a/rust/icp_transfer/README.md b/rust/icp_transfer/README.md index f4dbe96bd..429d4fbee 100644 --- a/rust/icp_transfer/README.md +++ b/rust/icp_transfer/README.md @@ -13,7 +13,7 @@ The sample code revolves around one core transfer function which takes as input This sample will use the Rust variant. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/nft-wallet/README.md b/rust/nft-wallet/README.md index 23652a33a..12bf84040 100644 --- a/rust/nft-wallet/README.md +++ b/rust/nft-wallet/README.md @@ -2,7 +2,7 @@ This is an NFT wallet example dapp that utilizes minted NFTs from the Rust dip721-nft-container. Among some of its essential features, the wallet can register NFTs, transfer out NFTs, and check how many NFTs it contains. This dapp includes a frontend UI for interaction. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/parallel_calls/README.md b/rust/parallel_calls/README.md index 95db32030..085d8d322 100644 --- a/rust/parallel_calls/README.md +++ b/rust/parallel_calls/README.md @@ -10,7 +10,7 @@ The sample code revolves around two simple canisters, `caller` and `callee`. `Ca The callee exposes a simple `ping` endpoint that takes no parameters and returns nothing. -### Prerequisites +## Prerequisites - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. diff --git a/rust/performance_counters/README.md b/rust/performance_counters/README.md index 218fab4b6..24de25f87 100644 --- a/rust/performance_counters/README.md +++ b/rust/performance_counters/README.md @@ -31,10 +31,7 @@ In the future, ICP might expose more performance counters. ## Prerequisites -## Prerequisites - -- [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Step 1: Setup project environment diff --git a/rust/periodic_tasks/README.md b/rust/periodic_tasks/README.md index 62fe33fc9..bd7eeb22c 100644 --- a/rust/periodic_tasks/README.md +++ b/rust/periodic_tasks/README.md @@ -14,21 +14,17 @@ The example consists of two canisters named `heartbeat` and `timer`, both implem ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Example 1: +## Example 1: heartbeats and timers -- #### Step 1: Begin by opening a terminal window and navigating into the project's directory. +- ### Step 1: Setup project environment -```sh -cd examples/rust/periodic_tasks -``` - -- #### Step 2: Start a clean local Internet Computer replica and a web server: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/periodic_tasks dfx start --clean ``` @@ -37,18 +33,18 @@ This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pr Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 3: Open another terminal window in the same directory: +- #### Step 2: Open another terminal window in the same directory: ```sh cd examples/rust/periodic_tasks ``` -- #### Step 4: Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 10s: +- #### Step 3: Compile and deploy the `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 10s: ```sh dfx deploy heartbeat --argument 10 @@ -77,25 +73,25 @@ URLs: timer: http://127.0.0.1/... ``` -- #### Step 5: After 10s, observe similar non-zero counters in both canisters: +- #### Step 4: After 10s, observe similar non-zero counters in both canisters: ```sh dfx canister call heartbeat counter dfx canister call timer counter ``` -Note, as the canisters deployed one by one, there might be a minor discrepancy in the counters. +Note: As the canisters deployed one by one, there might be a minor discrepancy in the counters. Example output: ```sh -% dfx canister call heartbeat counter +% dfx canister call heartbeat counter (8 : nat32) -% dfx canister call timer counter +% dfx canister call timer counter (7 : nat32) ``` -- #### Step 6: Compare the amount of cycles used to schedule the periodic task with 10s interval: +- #### Step 5: Compare the amount of cycles used to schedule the periodic task with 10s interval: ```sh dfx canister call heartbeat cycles_used @@ -115,36 +111,40 @@ For periodic tasks with 10 sec intervals, the `heartbeat` canister uses *more* c Not only do timers use fewer cycles, but they are also more composable. As there is no global state or methods to export, different libraries with timers could be easily used in the same project. -Also, timers provide isolation between the scheduling logic and the periodic task. If the periodic task fails, all the changes made by this task will be reverted, but the timers library state will be updated, i.e. the failed task will be removed from the list of timers to execute. +Also, timers provide isolation between the scheduling logic and the periodic task. If the periodic task fails, all the changes made by this task will be reverted, but the timers library state will be updated, i.e., the failed task will be removed from the list of timers to execute. For such isolation of execution and scheduling contexts, the internal timers library uses self-canister calls: - ```rust - # This is a pseudo-code of a self call: - ic_cdk::call(ic_cdk::id(), "periodic_task", ()); - ``` +```rust +# This is a pseudo-code of a self call: +ic_cdk::call(ic_cdk::id(), "periodic_task", ()); +``` + +Despite the [costs](https://internetcomputer.org/docs/current/developer-docs/gas-cost) associated with such self-canister calls, the timers library still uses fewer cycles than the heartbeats. -Despite the [costs](https://internetcomputer.org/docs/current/developer-docs/production/computation-and-storage-costs) associated with such self-canister calls, the timers library still uses fewer cycles than the heartbeats. +## Example 2: Cycles usage for tasks with 1s interval -### Example 2: Cycles usage for tasks with 1s interval +- ### Step 1: Setup project environment -- #### Step 1: Open a new terminal window in the example root directory: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh cd examples/rust/periodic_tasks +dfx start --clean ``` -- #### Step 2: Start a clean local Internet Computer replica and a web server: +This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. + +Example output: ```sh -dfx stop dfx start --clean +[...] +Dashboard: http://localhost:63387/_/dashboard ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -- #### Step 3: Open another terminal window in the same directory: +- #### Step 2: Open another terminal window in the same directory: ```sh cd examples/rust/periodic_tasks @@ -153,12 +153,12 @@ cd examples/rust/periodic_tasks Example output: ```sh -% dfx stop && dfx start --clean +dfx start --clean [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 4:. Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 1s: +- #### Step 3:. Compile and deploy `heartbeat` and `timer` canisters, setting the interval for periodic tasks to 1s: ```sh dfx deploy --argument 1 heartbeat @@ -187,25 +187,25 @@ URLs: timer: http://127.0.0.1/... ``` -- #### Step 5: After a few seconds, observe similar non-zero counters in both canisters: +- #### Step 4: After a few seconds, observe similar non-zero counters in both canisters: ```sh dfx canister call heartbeat counter dfx canister call timer counter ``` -Note, as the canisters deployed one by one, there might be a minor discrepancy in the counters. +Note: As the canisters deployed one by one, there might be a minor discrepancy in the counters. Example output: ```sh -% dfx canister call heartbeat counter +% dfx canister call heartbeat counter (8 : nat32) -% dfx canister call timer counter +% dfx canister call timer counter (9 : nat32) ``` -- #### Step 6: Compare the number of cycles used to schedule the periodic task with 1s interval: +- #### Step 5: Compare the number of cycles used to schedule the periodic task with 1s interval: ```sh dfx canister call heartbeat cycles_used @@ -230,6 +230,7 @@ Also, there is no isolation between the scheduling logic and the periodic task. For such isolation of execution and scheduling contexts, the timers library uses internal self-canister calls as described in `Demo 1`. Due to the [costs](https://internetcomputer.org/docs/current/developer-docs/production/computation-and-storage-costs) associated with such self-canister calls, `timer` canister uses more cycles for very frequent periodic tasks. ## Further learning + 1. Have a look at the locally running dashboard. The URL is at the end of the `dfx start` command: `Dashboard: http://localhost/...` 2. Check out `heartbeat` and `timer` canisters Candid user interface. The URLs are at the end of the `dfx deploy` command: `heartbeat: http://127.0.0.1/...` 3. Find which interval makes even the costs of running periodic tasks in the `timer` and `heartbeat` canisters: `dfx deploy heartbeat --argument 5 && dfx deploy timer --argument 5` diff --git a/rust/pub-sub/README.md b/rust/pub-sub/README.md index df08528c3..fe483135f 100644 --- a/rust/pub-sub/README.md +++ b/rust/pub-sub/README.md @@ -1,12 +1,5 @@ ---- -keywords: [beginner, rust, pubsub, publisher, subscriber] ---- - # PubSub -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/pub-sub) - -## Overview This sample project demonstrates how functions may be passed as arguments of inter-canister calls to be used as callbacks. A common problem in both distributed and decentralized systems is keeping separate services (or canisters) synchronized with one another. While there are many potential solutions to this problem, a popular one is the Publisher/Subscriber pattern or "PubSub". PubSub is an especially valuable pattern on the Internet Computer as its primary drawback, message delivery failures, does not apply. @@ -14,43 +7,39 @@ A common problem in both distributed and decentralized systems is keeping separa ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` Begin by opening a terminal window. -### Step 1: Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the command: +## Step 1: Setup project environment -```bash +Navigate into the folder containing the project's files and start a local instance of the replica with the command: + +```sh cd examples/rust/pub-sub dfx start --background ``` -### Step 2: Deploy the canister: - -```bash -dfx deploy -``` - -### Step 3: Get the publisher ID +## Step 2: Get the publisher ID ```bash dfx canister id publisher ``` -### Step 4: Subscribe to the "Apples" topic: +## Step 3: Subscribe to the "Apples" topic ```bash dfx canister call subscriber setup_subscribe '(principal "", "Apples")' ``` -### Step 5: Publish to the "Apples" topic: +## Step 4: Publish to the "Apples" topic ```bash dfx canister call publisher publish '(record { "topic" = "Apples"; "value" = 2 })' ``` -### Step 6: Receive your subscription: +## Step 5: Receive your subscription ```bash dfx canister call subscriber get_count diff --git a/rust/qrcode/README.md b/rust/qrcode/README.md index 6d1f453dd..2ab8afb6a 100644 --- a/rust/qrcode/README.md +++ b/rust/qrcode/README.md @@ -1,13 +1,5 @@ ---- -keywords: [intermediate, rust, qrcode] ---- - # QR code generator -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/qrcode) - -## Overview - This example shows that an Internet Computer dapp can perform a long-running computation, like image processing, in a single message execution. This is possible due to a unique feature called Deterministic Time Slicing (DTS), which automatically divides long computations into smaller slices executed across multiple blocks. Developers can write long-running code as usual and don't require anything special to take advantage of DTS, as demonstrated in this example. @@ -17,20 +9,19 @@ You try the live version of the dapp running on the mainnet here: [https://khpe2 ## Prerequisites This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). -- [x] Install `node.js` to build the web frontend. Make sure the version is at least `12.20`. -- [x] Make sure your rust version is up-to-date (e.g., run `rustup update`). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Make sure your Rust version is up-to-date (e.g., run `rustup update`). - [x] Add the `wasm32` target to your rust installation (by running `rustup target add wasm32-unknown-unknown`). -- [x] Clone this project to a local directory. - [x] Install `node.js` dependencies by running `npm install`. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Running locally -Start a local replica of the Internet Computer by running: +Navigate into the folder containing the project's files and start a local instance of the replica with the command: -```bash -dfx start --background +```sh +cd examples/rust/qrcode +dfx start --clean --background ``` You can omit the `--background` argument if you want to see log messages of the dapp. diff --git a/rust/query_stats/README.md b/rust/query_stats/README.md index cdec34a6d..7e441ddfc 100644 --- a/rust/query_stats/README.md +++ b/rust/query_stats/README.md @@ -1,13 +1,5 @@ ---- -keywords: [beginner, rust, query statistics] ---- - # Query statistics -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/query_stats) - -## Overview - This example shows to work with the query stats feature. ## Architecture @@ -27,37 +19,41 @@ The `load` function just returns a timestamp. It just exists such that there is a query endpoint to call. The `get_query_stats` is the function that queries the status endpoint and returns the collected query statistics. -### Prerequisites +## Prerequisites + This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Install `node.js` (to build the web frontend). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - ### Step 1: Start a local canister execution environment: +## Step 1: Setup project environment -``` -dfx start --background +Navigate into the folder containing the project's files and start a local instance of the replica with the command: + +```sh +cd examples/rust/query_stats +dfx start --clean ``` - ### Step 2: Register, build, and deploy the project with the command: +## Step 2: Compile and deploy `query_stats` canister -``` +```sh dfx deploy ``` - ### Step 3: Call the canisters load function a few times to generate query traffic: +## Step 3: Call the canister's load function a few times to generate query traffic ``` dfx canister call query_stats load ``` - ### Step 4: Observe the following result: +## Step 4: Observe the following result ``` dfx canister call query_stats get_query_stats ``` - ### Step 5: After a while, the values should become populated +## Step 5: After a while, the values should become populated ``` "Number of calls: 19 - Number of instructions 414_083 - Request payload bytes: 114 - Response payload bytes: 270" @@ -79,7 +75,8 @@ Their raw values are not that useful, you may want to implement some sort of met One way to go from here is to get the query stats in a regular interval using a timer and compare to the last values, calculating rates. -### Resources +## Resources + - [ic-cdk](https://docs.rs/ic-cdk/latest/ic_cdk/). ## Security considerations and security best practices diff --git a/rust/send_http_get/README.md b/rust/send_http_get/README.md index a5cf2731c..b5bbf59c0 100644 --- a/rust/send_http_get/README.md +++ b/rust/send_http_get/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, rust, http, get, http get] ---- - # HTTP: GET -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/send_http_get) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `GET` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-get). @@ -13,18 +7,8 @@ This demo goes in hand with the [developer documentation on HTTPS outcalls](http If you want to start working on your project right away, you might want to try the following commands: ```bash +git clone https://github.com/dfinity/examples cd examples/rust/send_http_get -dfx help -dfx canister --help -``` - -## Running the project locally -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy ``` diff --git a/rust/send_http_post/README.md b/rust/send_http_post/README.md index af6df1f8f..b9ef3e131 100644 --- a/rust/send_http_post/README.md +++ b/rust/send_http_post/README.md @@ -1,11 +1,5 @@ ---- -keywords: [intermediate, rust, http, post, http post] ---- - # HTTP: POST -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/send_http_post) - The purpose of this dapp is to give developers a minimal dapp that uses the IC's HTTPS outcalls feature to make a `POST` request. This demo goes in hand with the [developer documentation on HTTPS outcalls](https://internetcomputer.org/docs/current/developer-docs/integrations/https-outcalls/https-outcalls-post). @@ -13,20 +7,8 @@ This demo goes in hand with the [developer documentation on HTTPS outcalls](http If you want to start working on your project right away, you might want to try the following commands: ```bash +git clone https://github.com/dfinity/examples cd examples/rust/send_http_post -dfx help -dfx canister --help -``` - -## Running the project locally - -If you want to test your project locally, you can use the following commands: - -```bash -# Starts the replica, running in the background dfx start --background - -# Deploys your canisters to the replica and generates your candid interface dfx deploy -``` - +``` \ No newline at end of file diff --git a/rust/simd/README.md b/rust/simd/README.md index 59b13a020..0bc57b5f8 100644 --- a/rust/simd/README.md +++ b/rust/simd/README.md @@ -1,13 +1,5 @@ ---- -keywords: [advanced, rust, simd, ai] ---- - # WebAssembly SIMD Example -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/simd) - -## Overview - Unlike other blockchains, the Internet Computer supports WebAssembly SIMD ([Single Instruction, Multiple Data](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)) instructions. This, combined with state-of-the-art Rust compiler support, @@ -21,42 +13,34 @@ The example consists of a canister named `mat_mat_mul` (matrix-matrix multiplica This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). Note: the WebAssembly SIMD support requires `dfx` version `0.20.2-beta.0` or later. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). Note: the WebAssembly SIMD support requires `dfx` version `0.20.2-beta.0` or later. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ### Example 1: Floating point matrices multiplications -- #### Step 1.1: Begin by opening a terminal window and navigating into the project's directory +- #### Step 1: Setup project environment -```sh -cd examples/rust/simd -``` - -- #### Step 1.2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/simd dfx start --clean ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -Example output: - ```sh -% dfx stop && dfx start --clean +dfx start --clean Running dfx start for version 0.20.2-beta.0 [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 1.3: Open another terminal window in the same directory +- #### Step 2: Open another terminal window in the same directory ```sh cd examples/rust/simd ``` -- #### Step 1.4: Compile and deploy `mat_mat_mul` canister +- #### Step 3: Compile and deploy `mat_mat_mul` canister ```sh dfx deploy @@ -73,7 +57,7 @@ URLs: mat_mat_mul: http://127.0.0.1/?canisterId=... ``` -- #### Step 1.5: Compare the amount of instructions used for different matrix multiplication implementations +- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations Call a loop performing 1K element-wise multiplications of `K x 4` packed slices from matrices `A` and `B` using optimized algorithm, the same algorithm with @@ -100,44 +84,31 @@ In this example, Rust's auto-vectorization shines in optimizing matrix multiplic The auto-vectorized code achieves over 10x speedup compared to the optimized version! Also, it's on par with the hand-crafted WebAssembly SIMD multiplication. -It's important to note that the optimized code's performance is currently limited -due to a known issue with NaN canonicalization in `wasmtime`. -This issue [has been fixed](https://github.com/bytecodealliance/wasmtime/commit/72a3b8b99d7c0343bacb7cd2cff3151b0144179d) -by DFINITY, but not yet released at the time of writing. - ### Example 2: Integer matrices multiplications -- #### Step 2.1: Begin by opening a terminal window and navigating into the project's directory - -```sh -cd examples/rust/simd -``` +- #### Step 1: Setup project environment -- #### Step 2.2: Start a clean local Internet Computer replica and a web server +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx stop +cd examples/rust/simd dfx start --clean ``` -This terminal will stay blocked, printing log messages, until the `Ctrl+C` is pressed or `dfx stop` command is run. - -Example output: - ```sh -% dfx stop && dfx start --clean +dfx start --clean Running dfx start for version 0.20.2-beta.0 [...] Dashboard: http://localhost:63387/_/dashboard ``` -- #### Step 2.3: Open another terminal window in the same directory +- #### Step 2: Open another terminal window in the same directory ```sh cd examples/rust/simd ``` -- #### Step 2.4: Compile and deploy `mat_mat_mul` canister +- #### Step 3: Compile and deploy `mat_mat_mul` canister ```sh dfx deploy @@ -154,7 +125,7 @@ URLs: mat_mat_mul: http://127.0.0.1/?canisterId=... ``` -- #### Step 2.5: Compare the amount of instructions used for different matrix multiplication implementations +- #### Step 4: Compare the amount of instructions used for different matrix multiplication implementations Call a loop performing 1K element-wise multiplications of `K x 4` packed slices from matrices `A` and `B` using optimized algorithm and the same algorithm diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 9b699c21d..031be0e66 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -1,50 +1,42 @@ ---- -keywords: [advanced, rust, threshold ecdsa, ecdsa, signature] ---- +# Threshold ECDSA sample -# Threshold ECDSA +We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) - -## Overview - -We present a minimal example canister smart contract for showcasing the [threshold ECDSA](https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa) API. - -The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. +The example canister is a signing oracle that creates ECDSA signatures with keys derived from an input string. More specifically: - The sample canister receives a request that provides a message. -- The sample canister hashes the message and uses the key derivation string for the derivation path. +- The sample canister hashes the message and uses the key derivation string for the derivation path. - The sample canister uses the above to request a signature from the threshold ECDSA [subnet](https://wiki.internetcomputer.org/wiki/Subnet_blockchain) (the threshold ECDSA is a subnet specializing in generating threshold ECDSA signatures). -This tutorial gives a complete overview of the development, starting with downloading [`dfx`](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the mainnet. - -This walkthrough focuses on the version of the sample canister code written in [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) programming language, but no specific knowledge of Motoko is needed to follow along. There is also a [Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) version available in the same repo and follows the same commands for deploying. +This tutorial gives a complete overview of the development, starting with downloading the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the IC mainnet. +> [!TIP] +> This walkthrough focuses on the version of the sample canister code written in the Rust programming language. There is also a [Motoko](https://internetcomputer.org/docs/current/developer-docs/backend/motoko/index.md) version available in the same repo and follows the same commands for deploying. ## Prerequisites -- [x] Download and [install the IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) if you do not already have it. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +This example requires an installation of: -## Getting started +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v0.11.0 or newer. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Sample code for `threshold-ecdsa` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-ecdsa) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-ecdsa) sub-directories. It requires at least [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) version 0.11.0 for local development. +Begin by opening a terminal window. -### Deploy and test the canister locally +## Step 1: Setup the project environment -This tutorial will use the Rust version of the canister: +Navigate into the folder containing the project's files and start a local instance of the Internet Computer with the commands: ```bash cd examples/rust/threshold-ecdsa dfx start --background -npm install -dfx deploy ``` -#### What this does -- `dfx start --background` starts a local instance of the IC via the IC SDK -- `dfx deploy` deploys the code in the user's directory as a canister on the local version of the IC +## Step 2: Deploy the canisters + +```bash +dfx deploy +``` If successful, you should see something like this: @@ -52,25 +44,25 @@ If successful, you should see something like this: Deployed canisters. URLs: Backend canister via Candid interface: - ecdsa_example_motoko: http://127.0.0.1:4943/?canisterId=t6rzw-2iaaa-aaaaa-aaama-cai&id=st75y-vaaaa-aaaaa-aaalq-cai + ecdsa_example_rust: http://127.0.0.1:4943/?canisterId=t6rzw-2iaaa-aaaaa-aaama-cai&id=st75y-vaaaa-aaaaa-aaalq-cai ``` If you open the URL in a web browser, you will see a web UI that shows the public methods the canister exposes. Since the canister exposes `public_key` and `sign` methods, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet -To deploy this canister the mainnet, one needs to do two things: +To deploy this canister to the mainnet, one needs to do two things: -- Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. +- Acquire cycles (the equivalent of "gas" on other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID -To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. +To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. There are three options: @@ -78,35 +70,12 @@ There are three options: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/ecdsa_example_motoko/main.mo` includes the following lines and can be deployed locally: +> [!WARNING] +> To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -:::caution -The following example is two **code snippets** that are part of a larger code file. These snippets may return an error if run on their own. -::: +### Deploying -```motoko -let { public_key } = await ic.ecdsa_public_key({ - canister_id = null; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; -}); -``` - -```motoko -let { signature } = await ic.sign_with_ecdsa({ - message_hash; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; -}); -``` - -:::caution -To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. -::: - -#### Deploy to the mainnet via IC SDK - -To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: +To [deploy via mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: ```bash npm install @@ -118,14 +87,14 @@ If successful, you should see something like this: Deployed canisters. URLs: Backend canister via Candid interface: - ecdsa_example_motoko: https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai + ecdsa_example_rust: https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai ``` -In the example above, `ecdsa_example_motoko` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. +In the example above, `ecdsa_example_rust` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. @@ -136,49 +105,10 @@ In the example below, the method returns `03c22bef676644dba524d4a24132ea8463221a "Ok": { "public_key_hex": "03c22bef676644dba524d4a24132ea8463221a55540a27fc86d690fda8e688e31a" - } + } } ``` - -### Code walkthrough -Open the file `main.mo`, which will show the following Motoko code that demonstrates how to obtain an ECDSA public key. - -```motoko - //declare "ic" to be the management canister, which is evoked by `actor("aaaaa-aa")`. This is how we will obtain an ECDSA public key - let ic : IC = actor("aaaaa-aa"); - - public shared (msg) func public_key() : async { #Ok : { public_key: Blob }; #Err : Text } { - let caller = Principal.toBlob(msg.caller); - - try { - - //request the management canister to compute an ECDSA public key - let { public_key } = await ic.ecdsa_public_key({ - - //When `null`, it defaults to getting the public key of the canister that makes this call - canister_id = null; - derivation_path = [ caller ]; - //this code uses the mainnet test key - key_id = { curve = #secp256k1; name = "test_key_1" }; - }); - - #Ok({ public_key }) - - } catch (err) { - - #Err(Error.message(err)) - - } - - }; -``` - -In the code above, the canister calls the `ecdsa_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). - - -**The [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) is just a facade; it does not exist as a canister (with isolated state, Wasm code, etc.). It is an ergonomic way for canisters to call the system API of the IC (as if it were a single canister). In the code below, we use the management canister to create an ECDSA public key. `let ic : IC = actor("aaaaa-aa")` declares the IC management canister in the code above.** - ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -190,25 +120,7 @@ For obtaining the canister's root public key, the derivation path in the API can ## Signing -Computing threshold ECDSA signatures is the core functionality of this feature. **Canisters do not hold ECDSA keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private ECDSA keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. - -```motoko - public shared (msg) func sign(message_hash: Blob) : async { #Ok : { signature: Blob }; #Err : Text } { - assert(message_hash.size() == 32); - let caller = Principal.toBlob(msg.caller); - try { - Cycles.add(10_000_000_000); - let { signature } = await ic.sign_with_ecdsa({ - message_hash; - derivation_path = [ caller ]; - key_id = { curve = #secp256k1; name = "dfx_test_key" }; - }); - #Ok({ signature }) - } catch (err) { - #Err(Error.message(err)) - } - }; -``` +Computing threshold ECDSA signatures is the core functionality of this feature. **Canisters do not hold ECDSA keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means that canisters "control" their private ECDSA keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. ## Signature verification @@ -236,4 +148,4 @@ In this walkthrough, we deployed a sample smart contract that: * Signed with private ECDSA keys even though **canisters do not hold ECDSA keys themselves**. * Requested a public key. -* Performed signature verification. +* Performed signature verification. \ No newline at end of file diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 11ef6b1ca..45ed865d6 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -1,17 +1,6 @@ ---- -keywords: [advanced, rust, threshold schnorr, schnorr, signature] ---- - # Threshold Schnorr -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) - -## Overview - -We present a minimal example canister smart contract for showcasing the -[threshold -Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) -API. +We present a minimal example canister smart contract for showcasing the [threshold Schnorr](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-sign_with_schnorr) API. The example canister is a signing oracle that creates Schnorr signatures with keys derived based on the canister ID and the chosen algorithm, either BIP340 or @@ -26,40 +15,48 @@ More specifically: (the threshold Schnorr subnet is a subnet generating threshold Schnorr signatures). -This tutorial gives a complete overview of the development, starting with downloading [`dfx`](https://internetcomputer.org/docs/current/developer-docs/setup/index.md), up to the deployment and trying out the code on the mainnet. - This walkthrough focuses on the version of the sample canister code written in -Rust programming language.. There is also a -[Motoko](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) -version available in the same repo and follows the same commands for deploying. - +[Rust](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr). +There is also a Motoko version available in the same repo and follows the same commands for deploying. ## Prerequisites -- [x] Download and [install the IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) - if you do not already have it. For local testing, `dfx >= 0.22.0-beta.0` is - required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +This example requires an installation of: -## Getting started +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -Sample code for `threshold-schnorr-example` is provided in the [examples repository](https://github.com/dfinity/examples), under either [`/motoko`](https://github.com/dfinity/examples/tree/master/motoko/threshold-schnorr) or [`/rust`](https://github.com/dfinity/examples/tree/master/rust/threshold-schnorr) sub-directories. +Begin by opening a terminal window. -### Deploy the canister locally +## Step 1: Setup the project environment -This tutorial will use the Rust version of the canister: +Navigate into the folder containing the project's files, start a local instance of the Internet Computer and with the commands: ```bash cd examples/rust/threshold-schnorr dfx start --background -make deploy ``` #### What this does - `dfx start --background` starts a local instance of the IC via the IC SDK + +## Step 2: Deploy the canisters + +```bash +make deploy +``` + +To test (includes deploying): +```bash +npm install @noble/curves +make test +``` + +#### What this does - `make deploy` deploys the canister code on the local version of the IC +- `npm install @noble/curves` installs a test javascript dependency +- `make test` deploys and tests the canister code on the local version of the IC -If successful, you should see something like this: +If deployment was successful, you should see something like this: ```bash Deployed canisters. @@ -69,21 +66,21 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the -public methods the canister exposes. Since the canister exposes `public_key`, -`sign`, and `verify` methods, those are rendered in the web UI. +public methods the canister exposes. Since the canister exposes `public_key` and +`sign`, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet To deploy this canister the mainnet, one needs to do two things: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +### Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +### Update source code with the right key ID To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/schnorr_example_rust/src/lib.rs` file of the sample code. Before deploying to mainnet, one should modify the code to use the right name of the `key_id`. @@ -93,19 +90,12 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives -the key ID as follows and can be deployed locally: -```rust -SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm) -``` +IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with +either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of +key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. -IMPORTANT: To deploy to IC mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. -#### Deploy to the mainnet via IC SDK +### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -121,11 +111,15 @@ URLs: schnorr_example_rust: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai ``` -In the example above, `schnorr_example_rust` has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. +The implementation of this canister in Rust is (`schnorr_example_rust`) is +deployed on mainnet. It has the URL +https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai +and serves up the Candid web UI for this particular canister deployed on +mainnet. ## Obtaining public keys -### Using the Candid Web UI +### Using the Candid UI If you deployed your canister locally or to the mainnet, you should have a URL to the Candid web UI where you can access the public methods. We can call the `public-key` method. @@ -142,42 +136,6 @@ Ed25519 public key. } ``` - -### Code walkthrough -Open the file `lib.rs`, which will show the following Rust code that -demonstrates how to obtain a Schnorr public key. - -```rust -#[update] -async fn public_key(algorithm: SchnorrAlgorithm) -> Result { - let request = ManagementCanisterSchnorrPublicKeyRequest { - canister_id: None, - derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), - }; - - let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = - ic_cdk::call(Principal::management_canister(), "schnorr_public_key", (request,)) - .await - .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; - - Ok(PublicKeyReply { - public_key_hex: hex::encode(&res.public_key), - }) -} -``` - -In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). - - -**The [IC management -canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) -is just a facade; it does not exist as a canister (with isolated state, Wasm -code, etc.). It is an ergonomic way for canisters to call the system API of the -IC (as if it were a single canister). In the code below, we use the management -canister to create a Schnorr public key. Canister ID `"aaaaa-aa"` -declares the IC management canister in the canister code.** - ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -185,105 +143,51 @@ For obtaining the canister's root public key, the derivation path in the API can ### Key derivation - For obtaining a canister's public key below its root key in the BIP-32 key derivation hierarchy, a derivation path needs to be specified. As explained in the general documentation, each element in the array of the derivation path is either a 32-bit integer encoded as 4 bytes in big endian or a byte array of arbitrary length. The element is used to derive the key in the corresponding level at the derivation hierarchy. -- In the example code above, we use the bytes extracted from the msg.caller principal in the `derivation_path`, so that different callers of `public_key()` method of our canister will be able to get their own public keys. +- In the example code above, we use the bytes extracted from the `msg.caller` principal in the `derivation_path`, so that different callers of `public_key()` method of our canister will be able to get their own public keys. ## Signing Computing threshold Schnorr signatures is the core functionality of this feature. **Canisters do not hold Schnorr keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private Schnorr keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. -```rust -#[update] -async fn sign(message: String, algorithm: SchnorrAlgorithm) -> Result { - let internal_request = ManagementCanisterSignatureRequest { - message: message.as_bytes().to_vec(), - derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], - key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), - }; - - let (internal_reply,): (ManagementCanisterSignatureReply,) = - ic_cdk::api::call::call_with_payment( - Principal::management_canister(), - "sign_with_schnorr", - (internal_request,), - 25_000_000_000, - ) - .await - .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; - - Ok(SignatureReply { - signature_hex: hex::encode(&internal_reply.signature), - }) -} -``` - ## Signature verification For completeness of the example, we show that the created signatures can be verified with the public key corresponding to the same canister and derivation -path. Note that the first byte of the BIP340 public key needs to be removed for -verification, which is done by the verification function below internally. - -```rust -#[query] -async fn verify( - signature_hex: String, - message: String, - public_key_hex: String, - algorithm: SchnorrAlgorithm, -) -> Result { - let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); - let msg_bytes = message.as_bytes(); - let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); - - match algorithm { - SchnorrAlgorithm::Bip340Secp256k1 => { - verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) - } - SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), - } -} - -fn verify_bip340_secp256k1( - sig_bytes: &[u8], - msg_bytes: &[u8], - secp1_pk_bytes: &[u8], -) -> Result { - assert_eq!(secp1_pk_bytes.len(), 33); - assert_eq!(sig_bytes.len(), 64); +path in javascript. Note that in contrast to the Rust implementation of this +example, the signature verification is not part of the canister API and happens +externally. - let sig = - k256::schnorr::Signature::try_from(sig_bytes).expect("failed to deserialize signature"); +Ed25519 can be verified as follows: +```javascript +import('@noble/curves/ed25519').then((ed25519) => { verify(ed25519.ed25519); }) + .catch((err) => { console.log(err) }); - let vk = k256::schnorr::VerifyingKey::from_bytes(&secp1_pk_bytes[1..]) - .expect("failed to deserialize BIP340 encoding into public key"); +function verify(ed25519) { + const test_sig = '1efa03b7b7f9077449a0f4b3114513f9c90ccf214166a8907c23d9c2bbbd0e0e6e630f67a93c1bd525b626120e86846909aedf4c58763ae8794bcef57401a301' + const test_pubkey = '566d53caf990f5f096d151df70b2a75107fac6724cb61a9d6d2aa63e1496b003' + const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - let is_signature_valid = vk.verify_raw(&msg_bytes, &sig).is_ok(); - - Ok(SignatureVerificationReply { is_signature_valid }) -} - -fn verify_ed25519( - sig_bytes: &[u8], - msg_bytes: &[u8], - pk_bytes: &[u8], -) -> Result { - use ed25519_dalek::{Signature, Verifier, VerifyingKey}; - - let pk: [u8; 32] = pk_bytes - .try_into() - .expect("ed25519 public key incorrect length"); - let vk = VerifyingKey::from_bytes(&pk).unwrap(); + console.log(ed25519.verify(test_sig, test_msg, test_pubkey)); + } +``` - let signature = Signature::from_slice(sig_bytes).expect("ed25519 signature incorrect length"); +BIP340 can be verified as follows: +```javascript +import('@noble/curves/secp256k1').then((bip340) => { verify(bip340.schnorr); }) + .catch((err) => { console.log(err) }); - let is_signature_valid = vk.verify(msg_bytes, &signature).is_ok(); +function verify(bip340) { + const test_sig = '1b64ca7a7f02c76633954f320675267685b3b80560eb6a35cda20291ddefc709364e59585771c284e46264bfbb0620e23eb8fb274994f7a6f2fcbc8a9430e5d7'; + // the first byte of the BIP340 public key is truncated + const pubkey = '0341d7cf39688e10b5f11f168ad0a9e790bcb429d7d486eab07d2c824b85821470'.substring(2) + const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - Ok(SignatureVerificationReply { is_signature_valid }) + console.log(bip340.verify(test_sig, test_msg, test_pubkey)); } ``` The call to `verify` function should always return `true` for correct parameters -and `false` or trap on errors otherwise. +and `false` or error otherwise. Similar verifications can be done in many other languages with the help of cryptographic libraries that support the `bip340secp256k1` signing *with diff --git a/rust/token_transfer/README.md b/rust/token_transfer/README.md index 47a94e465..2bbcf18f1 100644 --- a/rust/token_transfer/README.md +++ b/rust/token_transfer/README.md @@ -1,8 +1,5 @@ # Token transfer -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/token_transfer). - -## Overview Token transfer is a canister that can transfer ICRC-1 tokens from its account to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer). @@ -16,27 +13,17 @@ This sample will use the Rust variant. This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) - -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. - -:::info - -If you just want to interact with this example, follow steps 4-8 and 10-12 below. - -::: +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -### Step 1: Create a new `dfx` project and navigate into the project's directory. +## Step 1: Create a new `dfx` project and navigate into the project's directory ```bash dfx new --type=rust token_transfer --no-frontend cd token_transfer ``` -### Step 2: Determine ICRC-1 ledger file locations +## Step 2: Determine ICRC-1 ledger file locations :::info @@ -44,22 +31,22 @@ You can read more about how to [setup the ICRC-1 ledger locally](https://interne ::: -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2. Note that we are deploying the ICRC-1 ledger to the same canister id the ckBTC ledger uses on mainnet. This will make it easier to interact with it later. @@ -74,8 +61,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz", "specified_id": "mxzaz-hqaaa-aaaar-qaada-cai" } }, @@ -99,13 +86,13 @@ If you chose to download the ICRC-1 ledger files with the script, you need to re ... ``` -### Step 4: Start a local replica: +## Step 4: Start a local instance of the Internet Computer ```bash dfx start --background --clean ``` -### Step 5: Create a new identity that will work as a minting account: +## Step 5: Create a new identity that will work as a minting account ```bash dfx identity new minter --storage-mode plaintext @@ -113,20 +100,22 @@ dfx identity use minter export MINTER=$(dfx identity get-principal) ``` -:::info +:::info Transfers from the minting account will create Mint transactions. Transfers to the minting account will create Burn transactions. ::: -### Step 6: Switch back to your default identity and record its principal to mint an initial balance to when deploying the ledger: +## Step 6: Switch back to your default identity + +Record its principal to mint an initial balance to when deploying the ledger: ```bash dfx identity use default export DEFAULT=$(dfx identity get-principal) ``` -### Step 7: Deploy the ICRC-1 ledger locally: +## Step 7: Deploy the ICRC-1 ledger locally Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -162,11 +151,10 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 8: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 8: Verify that the ledger canister is healthy and working as expected -:::info - -You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) +> [!TIP] +> You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { @@ -181,7 +169,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 9: Prepare the token transfer canister: +## Step 9: Prepare the token transfer canister Replace the contents of the `src/token_transfer_backend/Cargo.toml` file with the following: @@ -271,11 +259,8 @@ ic_cdk::export_candid!(); Replace the contents of the `src/token_transfer_backend/token_transfer_backend.did` file with the following: -:::info - -The `token_transfer_backend.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). - -::: +> [!TIP] +> The `token_transfer_backend.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). ```did type Account = record { owner : principal; subaccount : opt vec nat8 }; @@ -285,19 +270,16 @@ service : { transfer : (TransferArgs) -> (Result) } ``` -### Step 10: Deploy the token transfer canister: +## Step 10: Deploy the token transfer canister ```bash dfx deploy token_transfer_backend ``` -### Step 11: Transfer funds to your canister: - -:::info +## Step 11: Transfer funds to your canister -Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. - -::: +> [!WARNING] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 7 for the following steps. Make the following call to transfer 10 tokens to the canister: @@ -316,7 +298,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 12: Transfer funds from the canister: +## Step 12: Transfer funds from the canister Now that the canister owns tokens on the ledger, you can transfer 1 token from the canister to another account, in this case back to the default account: diff --git a/rust/token_transfer_from/README.md b/rust/token_transfer_from/README.md index 5ebc7dea1..d17b8f3a7 100644 --- a/rust/token_transfer_from/README.md +++ b/rust/token_transfer_from/README.md @@ -1,9 +1,5 @@ # Token transfer_from -[View this samples code on GitHub](https://github.com/dfinity/examples/tree/master/rust/token_transfer_from). - -## Overview - `token_transfer_from_backend` is a canister that can transfer ICRC-1 tokens on behalf of accounts to other accounts. It is an example of a canister that uses an ICRC-1 ledger canister that supports the [ICRC-2](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-2) approve and transfer from standard. Sample code is available in [Motoko](https://github.com/dfinity/examples/tree/master/motoko/token_transfer_from) and [Rust](https://github.com/dfinity/examples/tree/master/rust/token_transfer_from). ## Architecture @@ -16,27 +12,17 @@ This sample will use the Rust variant. This example requires an installation of: -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/index.mdx). -- [x] Download and install [git.](https://git-scm.com/downloads) +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## How to get there - -The following steps will guide you through the process of setting up the token transfer canister for your own project. - -:::info - -If you just want to interact with this example, follow steps 4-6 and 8-10 below. - -::: - -### Step 1: Create a new `dfx` project and navigate into the project's directory. +## Step 1: Create a new `dfx` project and navigate into the project's directory ```bash dfx new --type=rust token_transfer_from --no-frontend cd token_transfer_from ``` -### Step 2: Determine ICRC-1 ledger file locations +## Step 2: Determine ICRC-1 ledger file locations :::info @@ -44,22 +30,22 @@ You can read more about how to [setup the ICRC-1 ledger locally](https://interne ::: -Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. At the time of writing, this is `d87954601e4b22972899e9957e800406a0a6b929`. +Go to the [releases overview](https://dashboard.internetcomputer.org/releases) and copy the latest replica binary revision. -The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`, so with the above revision it would be `https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz`. +The URL for the ledger Wasm module is `https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz`. -The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`, so with the above revision it would be `https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did`. +The URL for the ledger .did file is `https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did`. **OPTIONAL:** If you want to make sure, you have the latest ICRC-1 ledger files you can run the following script. ```sh -curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic/326df23607fc8280a047daba2d8462f1dfc57466/rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" +curl -o download_latest_icrc1_ledger.sh "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/scripts/download_latest_icrc1_ledger.sh" chmod +x download_latest_icrc1_ledger.sh ./download_latest_icrc1_ledger.sh ``` -### Step 3: Configure the `dfx.json` file to use the ledger : +## Step 3: Configure the `dfx.json` file to use the ledger Replace its contents with this but adapt the URLs to be the ones you determined in step 2. Note that we are deploying the ICRC-1 ledger to the same canister id the ckBTC ledger uses on mainnet. This will make it easier to interact with it later. @@ -73,8 +59,8 @@ Replace its contents with this but adapt the URLs to be the ones you determined }, "icrc1_ledger_canister": { "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/d87954601e4b22972899e9957e800406a0a6b929/rs/rosetta-api/icrc1/ledger/ledger.did", - "wasm": "https://download.dfinity.systems/ic/d87954601e4b22972899e9957e800406a0a6b929/canisters/ic-icrc1-ledger.wasm.gz", + "candid": "https://raw.githubusercontent.com/dfinity/ic//rs/rosetta-api/icrc1/ledger/ledger.did", + "wasm": "https://download.dfinity.systems/ic//canisters/ic-icrc1-ledger.wasm.gz", "specified_id": "mxzaz-hqaaa-aaaar-qaada-cai" } }, @@ -98,19 +84,16 @@ If you chose to download the ICRC-1 ledger files with the script, you need to re ... ``` -### Step 4: Start a local replica: +## Step 4: Start a local replica ```bash dfx start --background --clean ``` -### Step 5: Deploy the ICRC-1 ledger locally: - -:::info - -Transfers from the `minting_account` will create Mint transactions. Transfers to the minting account will create Burn transactions. +## Step 5: Deploy the ICRC-1 ledger locally -::: +> [!TIP] +> Transfers from the `minting_account` will create Mint transactions. Transfers to the minting account will create Burn transactions. Take a moment to read the details of the call made below. Not only are you deploying an ICRC-1 ledger canister, you are also: @@ -159,13 +142,10 @@ URLs: icrc1_ledger_canister: http://127.0.0.1:4943/?canisterId=bnz7o-iuaaa-aaaaa-qaaaa-cai&id=mxzaz-hqaaa-aaaar-qaada-cai ``` -### Step 6: Verify that the ledger canister is healthy and working as expected by using the command: +## Step 6: Verify that the ledger canister is healthy and working as expected -:::info - -You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) - -::: +> [!TIP] +> You can find more information on how to [interact with the ICRC-1 ledger](https://internetcomputer.org/docs/current/developer-docs/defi/icrc-1/using-icrc1-ledger#icrc-1-and-icrc-1-extension-endpoints) ````bash dfx canister call icrc1_ledger_canister icrc1_balance_of "(record { @@ -179,7 +159,7 @@ The output should be: (10_000_000_000 : nat) ```` -### Step 7: Prepare the token transfer canister: +## Step 7: Prepare the token transfer canister Replace the contents of the `src/token_transfer_from_backend/Cargo.toml` file with the following: @@ -271,11 +251,8 @@ ic_cdk::export_candid!(); Replace the contents of the `src/token_transfer_from_backend/token_transfer_from_backend.did` file with the following: -:::info - -The `token_transfer_from.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). - -::: +> [!TIP] +> The `token_transfer_from.did` file is a Candid file that describes the service interface of the canister. It was generated from the Rust code using the `candid-extractor` tool. You can read more about the [necessary steps](https://internetcomputer.org/docs/current/developer-docs/backend/rust/generating-candid). ```did type Account = record { owner : principal; subaccount : opt blob }; @@ -284,19 +261,16 @@ type TransferArgs = record { to_account : Account; amount : nat }; service : { transfer : (TransferArgs) -> (Result) } ``` -### Step 8: Deploy the token transfer canister: +## Step 8: Deploy the token transfer canister ```bash dfx deploy token_transfer_from_backend ``` -### Step 9: Approve the canister to transfer funds on behalf of the user: - -:::info - -Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. +## Step 9: Approve the canister to transfer funds on behalf of the user -::: +> [!TIP] +> Make sure that you are using the default `dfx` account that we minted tokens to in step 5 for the following steps. Make the following call to approve the `token_transfer_from_backend` canister to transfer 100 tokens on behalf of the `default` identity: @@ -317,7 +291,7 @@ If successful, the output should be: (variant { Ok = 1 : nat }) ``` -### Step 10: Let the canister transfer funds on behalf of the user: +## Step 10: Let the canister transfer funds on behalf of the user Now that the canister has an approval for the `default` identities tokens on the ledger, the canister can transfer 1 token on behalf of the `default` identity to another account, in this case to the canisters own account. diff --git a/rust/vetkd/README.md b/rust/vetkd/README.md index 470f68444..0e4da00fb 100644 --- a/rust/vetkd/README.md +++ b/rust/vetkd/README.md @@ -1,43 +1,43 @@ ---- -keywords: [advanced, rust, vetkeys, vetkd] ---- - # vetKD API -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/vetkd) - This repository provides a canister (`src/system_api`) that offers the vetKD system API proposed in https://github.com/dfinity/interface-spec/pull/158, implemented in an **unsafe** manner **for demonstration purposes**. Additionally, the repository provides: + * An example app backend canister (`src/app_backend`) implemented in **Rust** that makes use of this system API to provide caller-specific symmetric keys that can be used for AES encryption and decryption. * An example frontend (`src/app_frontend_js`) that uses the backend from Javascript in the browser. The frontend uses the [ic-vetkd-utils](https://github.com/dfinity/ic/tree/master/packages/ic-vetkd-utils) to create a transport key pair that is used to obtain a verifiably encrypted key from the system API, to decrypt this key, and to derive a symmetric key to be used for AES encryption/decryption. - + Because the `ic-vetkd-utils` are not yet published as NPM package at [npmjs.com](https://npmjs.com), a respective package file (`ic-vetkd-utils-0.1.0.tgz`) is included in this repository. +--- + ## Disclaimer The implementation of [the proposed vetKD system API](https://github.com/dfinity/interface-spec/pull/158) used in this example is **unsafe**, e.g., we hard-code a master secret key, rather than using a master secret key that is distributed among sufficiently many Internet Computer nodes through distributed key generation. **Do not use this in production or for sensitive data**! This example is solely provided **for demonstration purposes** to collect feedback on the mentioned vetKD system API. See also the respective disclaimer [in the system API canister implementation](https://github.com/dfinity/examples/blob/master/rust/vetkd/src/system_api/src/lib.rs#L19-L26). +--- + ## Prerequisites -- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` - [x] Install [Node.js](https://nodejs.org/en/download/). - [x] Install [Rust](https://www.rust-lang.org/tools/install), and add Wasm as a target (`rustup target add wasm32-unknown-unknown`). -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Running Locally +## Step 1: Setup project environment -- #### Step 1: Start a local internet computer. +Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```sh -dfx start +cd examples/rust/vetkd +dfx start --clean ``` -- #### Step 2: Open a new terminal window. +## Step 2: Open a new terminal window. -- #### Step 3: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: +## Step 3: Ensure `dfx` uses the canister IDs that are hard-coded in the Rust source code: ```sh cd examples/rust/vetkd @@ -46,13 +46,13 @@ dfx canister create system_api --specified-id s55qq-oqaaa-aaaaa-aaakq-cai Without this, the `dfx` may use different canister IDs for the `system_api` and `app_backend` canisters in your local environment. -- #### Step 4: Ensure that the required node modules are available in your project directory, if needed, by running the following command: +## Step 4: Ensure that the required node modules are available in your project directory, if needed, by running the following command: ```sh npm install ``` -- #### Step 5:. Register, build, and deploy the project: +## Step 5:. Register, build, and deploy the project: ```sh dfx deploy @@ -71,4 +71,4 @@ Backend canister via Candid interface: system_api: http://127.0.0.1:4943/?canisterId=avqkn-guaaa-aaaaa-qaaea-cai&id=s55qq-oqaaa-aaaaa-aaakq-cai ``` -- #### Step 6: Open the printed URL for the `app_frontend_js` in your browser. +## Step 6: Open the printed URL for the `app_frontend_js` in your browser. diff --git a/rust/x509/README.md b/rust/x509/README.md index 17f9fd5c4..4a6e64495 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -1,11 +1,5 @@ ---- -keywords: [advanced, rust, X.509, certificate, certificate signing request, certification authority, ed25519, threshold schnorr, schnorr, threshold ecdsa, ecdsa, secp256k1, signature] ---- - # X.509 -[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/rust/x509) - ## Overview We present a minimal example canister smart contract for showcasing two use @@ -41,19 +35,16 @@ up to the deployment and trying out the code on the mainnet. ## Prerequisites -- [x] Download and [install the IC - SDK](https://internetcomputer.org/docs/current/developer-docs/setup/index.md) - if you do not already have it.The minimum version of `dfx` that allows to - run this example locally is `0.23.0`. +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. +- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` + +The minimum version of `dfx` thatrun this example locally is - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -## Getting started +## Deploy and test the canister locally Sample code for `x509-example` is provided in the [examples repository](https://github.com/dfinity/examples), under [`/rust`](https://github.com/dfinity/examples/tree/master/rust/x509) sub-directory. -### Deploy and test the canister locally - -This tutorial will use the Rust version of the canister: ```bash cd examples/rust/x509 @@ -79,18 +70,18 @@ public methods the canister exposes. Since the canister exposes `root_ca_certificate` and `child_certificate` methods, those are rendered in the web UI. -### Deploying the canister on the mainnet +## Deploying the canister on the mainnet -To deploy this canister the mainnet, one needs to do two things: +To deploy this canister the mainnet, you must do two things: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -#### Acquire cycles to deploy +- #### Step 1: Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -#### Update source code with the right key ID +- #### Step 2: Update source code with the right key ID To deploy the sample code, the canister needs the right key name for the right environment. Specifically, one needs to initialize the canister with the key @@ -104,9 +95,9 @@ There are three options that are supported: * `key_1`: a master **production** key ID that is used in mainnet. Note that `dfx deploy` formats those name in `PascalCase` instead of -`snake_case` due to the formating of types in `rust`. +`snake_case` due to the formatting of types in `rust`. -#### Deploy to the mainnet via IC SDK +- #### Step 3: Deploy to the mainnet using the IC SDK To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -114,6 +105,7 @@ To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer- npm install dfx deploy --network ic ``` + If successful, you should see something like this: ```bash @@ -125,7 +117,7 @@ URLs: In the example above, `x509_example_rust` has the URL https://a3gq9-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=736w4-cyaaa-aaaal-qb3wq-cai and serves up the Candid web UI for this particular canister deployed on mainnet. -## Obtaining root CA certificate +## Obtaining the root CA certificate ### Using the Candid Web UI From 918e219a3edca28575a21741279131c8f31191b2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Thu, 19 Dec 2024 15:53:58 -0600 Subject: [PATCH 03/11] fix" " --- motoko/canister_logs/README.md | 54 ++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/motoko/canister_logs/README.md b/motoko/canister_logs/README.md index 545dd99b9..ad69e31b5 100644 --- a/motoko/canister_logs/README.md +++ b/motoko/canister_logs/README.md @@ -1,64 +1,66 @@ -# Canister logs - -## Prerequisites +--- +keywords: [beginner, motoko, canister logs, logging] +--- -- [x] Install the [IC - SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install). For local testing, `dfx >= 0.22.0` is required. -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` +# Canister logs -## Step 1: Setup project environment +[View this sample's code on GitHub](https://github.com/dfinity/examples/tree/master/motoko/canister_logs) -Navigate into the folder containing the project's files and start a local instance of the replica with the command: +## Prerequisites +This example requires an installation of: -```shell -dfx start --clean -``` +- [x] DFX version 0.19.0 or newer +- [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/setup/install/). +- [x] Download the following project files from GitHub: `git clone https://github.com/dfinity/examples/` You will need to have 3 terminal windows: -- Terminal A: Running a `dfx` instance and separating its output from anything else. -- Terminal B: Deploying a canister and seeing its output. -- Terminal C: Reading logs interactively. +- Terminal A: Running a DFX instance and separating its output from anything else +- Terminal B: Deploying a canister and seeing its output +- Terminal C: Reading logs interactively + +### Step 1: Navigate into the folder containing the project's files and start a local instance of the replica with the command: ```shell # Terminal A -- for running DFX and separating its output from anything else. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs +$ dfx start --clean # Terminal B -- for deploying the canister and calling its methods. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs # Terminal C -- for polling logs. -cd examples/motoko/canister_logs +$ cd examples/motoko/canister_logs ``` -## Step 2: Deploy the canister +### Step 2: Deploy the canister: ```shell # Terminal B -dfx deploy +$ dfx deploy ``` -## Step 3: Check canister logs +### Step 3: Check canister logs: Expect to see logs from timer traps. ```shell # Terminal B -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs [0. 2024-05-23T08:32:26.203980235Z]: right before timer trap [1. 2024-05-23T08:32:26.203980235Z]: [TRAP]: timer trap [2. 2024-05-23T08:32:31.836721763Z]: right before timer trap [3. 2024-05-23T08:32:31.836721763Z]: [TRAP]: timer trap ``` -## Step 4: Call `print` method and check the logs +### Step 4: Call `print` method and check the logs: ```shell # Terminal B -dfx canister call CanisterLogs print hi +$ dfx canister call CanisterLogs print hi () # Expect to see new log entry. -dfx canister logs CanisterLogs +$ dfx canister logs CanisterLogs ... [8. 2024-05-23T08:32:46.598972616Z]: right before timer trap [9. 2024-05-23T08:32:46.598972616Z]: [TRAP]: timer trap @@ -68,7 +70,7 @@ dfx canister logs CanisterLogs ... ``` -## Step 5: Start constantly polling logs +### Step 5: Start constantly polling logs: In order not to call `dfx canister logs CanisterLogs` after every canister call in a separate terminal window/pane C start a script that will constantly poll logs: @@ -84,7 +86,7 @@ $ ./poll_logs.sh ... ``` -## Step 6: Call `print`, `trap` and other canister methods +### Step 6: Call `print`, `trap` and other canister methods: ```shell # Terminal B From 648f33f938a49ea821811ae5bdea86be4fb3fbe3 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 15:58:32 -0600 Subject: [PATCH 04/11] Update rust/threshold-ecdsa/README.md --- rust/threshold-ecdsa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 031be0e66..1011152fe 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -62,7 +62,7 @@ Deploying to the Internet Computer requires [cycles](https://internetcomputer.or ### Update source code with the right key ID -To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/main.mo` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. +To deploy the sample code, the canister needs the right key ID for the right environment. Specifically, one needs to replace the value of the `key_id` in the `src/ecdsa_example_rust/src/lib.rs` file of the sample code. Before deploying to the mainnet, one should modify the code to use the right name of the `key_id`. There are three options: From 1312a1f17752934dffd96c357a6918dbcc989625 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:11:31 -0600 Subject: [PATCH 05/11] Apply suggestions from code review --- rust/threshold-ecdsa/README.md | 3 +-- rust/threshold-schnorr/README.md | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rust/threshold-ecdsa/README.md b/rust/threshold-ecdsa/README.md index 1011152fe..49a96a9b3 100644 --- a/rust/threshold-ecdsa/README.md +++ b/rust/threshold-ecdsa/README.md @@ -71,14 +71,13 @@ There are three options: * `key_1`: a master **production** key ID that is used in mainnet. > [!WARNING] -> To deploy to IC mainnet, one needs to replace the value in `key_id` fields with the values `"dfx_test_key"` to instead have either `"test_key_1"` or `"key_1"` depending on the desired intent. +> To deploy to IC mainnet, one needs to replace the value in `key_id `fields with the values `EcdsaKeyIds::TestKeyLocalDevelopment.to_key_id()` (mapping to `dfx_test_key`) to instead have either `EcdsaKeyIds::TestKey1.to_key_id()` (mapping to `test_key_1`) or `EcdsaKeyIds::ProductionKey1.to_key_id()` (mapping to `key_1`) depending on the desired intent. ### Deploying To [deploy via mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: ```bash -npm install dfx deploy --network ic ``` If successful, you should see something like this: diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 45ed865d6..87c52df99 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -47,14 +47,11 @@ make deploy To test (includes deploying): ```bash -npm install @noble/curves make test ``` #### What this does - `make deploy` deploys the canister code on the local version of the IC -- `npm install @noble/curves` installs a test javascript dependency -- `make test` deploys and tests the canister code on the local version of the IC If deployment was successful, you should see something like this: @@ -66,6 +63,7 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the +`sign`, and `verify` methods, those are rendered in the web UI. public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. @@ -90,11 +88,22 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. +For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives +the key ID as follows and can be deployed locally: +`SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` + IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. + +IMPORTANT: To deploy to IC mainnet, one needs to replace +`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key +id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or +`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. +Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. + ### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -112,10 +121,10 @@ URLs: ``` The implementation of this canister in Rust is (`schnorr_example_rust`) is -deployed on mainnet. It has the URL +deployed on the mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on -mainnet. +the mainnet. ## Obtaining public keys From f36dddb23f9217328b012e63f14f96e421b34a42 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:12:16 -0600 Subject: [PATCH 06/11] Update README.md --- rust/threshold-schnorr/README.md | 149 ++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 53 deletions(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index 87c52df99..4c1dbc0d3 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -47,11 +47,14 @@ make deploy To test (includes deploying): ```bash +npm install @noble/curves make test ``` #### What this does - `make deploy` deploys the canister code on the local version of the IC +- `npm install @noble/curves` installs a test javascript dependency +- `make test` deploys and tests the canister code on the local version of the IC If deployment was successful, you should see something like this: @@ -63,7 +66,6 @@ URLs: ``` If you open the URL in a web browser, you will see a web UI that shows the -`sign`, and `verify` methods, those are rendered in the web UI. public methods the canister exposes. Since the canister exposes `public_key` and `sign`, those are rendered in the web UI. @@ -88,22 +90,11 @@ There are three options that are planed to be supported: * `test_key_1`: a master **test** key ID that is used in mainnet. * `key_1`: a master **production** key ID that is used in mainnet. -For example, the default code in `src/schnorr_example_rust/src/lib.rs` derives -the key ID as follows and can be deployed locally: -`SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm)` - IMPORTANT: To deploy to IC mainnet, one needs to replace `"dfx_test_key"` with either "test_key_1"` or `"key_1"` depending on the desired intent. Both uses of key ID in `src/schnorr_example_rust/src/main.mo` must be consistent. - -IMPORTANT: To deploy to IC mainnet, one needs to replace -`SchnorrKeyIds::TestKeyLocalDevelopment` (which maps to the `"dfx_test_key"` key -id) with either `SchnorrKeyIds::TestKey1` (`"test_key_1"`) or -`SchnorrKeyIds::ProductionKey1` (`"key_1"`) depending on the desired intent. -Both uses of key ID in `src/schnorr_example_rust/src/lib.rs` must be consistent. - ### Deploying To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: @@ -121,10 +112,10 @@ URLs: ``` The implementation of this canister in Rust is (`schnorr_example_rust`) is -deployed on the mainnet. It has the URL +deployed on mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on -the mainnet. +mainnet. ## Obtaining public keys @@ -145,6 +136,42 @@ Ed25519 public key. } ``` +### Code walkthrough + +Open the file `wasm_only.rs`, which will show the following Rust code that +demonstrates how to obtain a Schnorr public key. + +```rust +#[update] +async fn public_key(algorithm: SchnorrAlgorithm) -> Result { + let request = ManagementCanisterSchnorrPublicKeyRequest { + canister_id: None, + derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], + key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), + }; + + let (res,): (ManagementCanisterSchnorrPublicKeyReply,) = + ic_cdk::call(Principal::management_canister(), "schnorr_public_key", (request,)) + .await + .map_err(|e| format!("schnorr_public_key failed {}", e.1))?; + + Ok(PublicKeyReply { + public_key_hex: hex::encode(&res.public_key), + }) +} +``` +In the code above, the canister calls the `schnorr_public_key` method of the [IC management canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) (`aaaaa-aa`). + + +**The [IC management +canister](https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister) +is just a facade; it does not exist as a canister (with isolated state, Wasm +code, etc.). It is an ergonomic way for canisters to call the system API of the +IC (as if it were a single canister). In the code below, we use the management +canister to create a Schnorr public key. Canister ID `"aaaaa-aa"` +declares the IC management canister in the canister code.** + + ### Canister root public key For obtaining the canister's root public key, the derivation path in the API can be simply left empty. @@ -158,51 +185,67 @@ For obtaining the canister's root public key, the derivation path in the API can Computing threshold Schnorr signatures is the core functionality of this feature. **Canisters do not hold Schnorr keys themselves**, but keys are derived from a master key held by dedicated subnets. A canister can request the computation of a signature through the management canister API. The request is then routed to a subnet holding the specified key and the subnet computes the requested signature using threshold cryptography. Thereby, it derives the canister root key or a key obtained through further derivation, as part of the signature protocol, from a shared secret and the requesting canister's principal identifier. Thus, a canister can only request signatures to be created for its canister root key or a key derived from it. This means, that canisters "control" their private Schnorr keys in that they decide when signatures are to be created with them, but don't hold a private key themselves. -## Signature verification - -For completeness of the example, we show that the created signatures can be -verified with the public key corresponding to the same canister and derivation -path in javascript. Note that in contrast to the Rust implementation of this -example, the signature verification is not part of the canister API and happens -externally. - -Ed25519 can be verified as follows: -```javascript -import('@noble/curves/ed25519').then((ed25519) => { verify(ed25519.ed25519); }) - .catch((err) => { console.log(err) }); - -function verify(ed25519) { - const test_sig = '1efa03b7b7f9077449a0f4b3114513f9c90ccf214166a8907c23d9c2bbbd0e0e6e630f67a93c1bd525b626120e86846909aedf4c58763ae8794bcef57401a301' - const test_pubkey = '566d53caf990f5f096d151df70b2a75107fac6724cb61a9d6d2aa63e1496b003' - const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); - - console.log(ed25519.verify(test_sig, test_msg, test_pubkey)); - } +```rust +#[update] +async fn sign(message: String, algorithm: SchnorrAlgorithm) -> Result { + let internal_request = ManagementCanisterSignatureRequest { + message: message.as_bytes().to_vec(), + derivation_path: vec![ic_cdk::api::caller().as_slice().to_vec()], + key_id: SchnorrKeyIds::TestKeyLocalDevelopment.to_key_id(algorithm), + }; + + let (internal_reply,): (ManagementCanisterSignatureReply,) = + ic_cdk::api::call::call_with_payment( + Principal::management_canister(), + "sign_with_schnorr", + (internal_request,), + 25_000_000_000, + ) + .await + .map_err(|e| format!("sign_with_schnorr failed {e:?}"))?; + + Ok(SignatureReply { + signature_hex: hex::encode(&internal_reply.signature), + }) +} ``` -BIP340 can be verified as follows: -```javascript -import('@noble/curves/secp256k1').then((bip340) => { verify(bip340.schnorr); }) - .catch((err) => { console.log(err) }); -function verify(bip340) { - const test_sig = '1b64ca7a7f02c76633954f320675267685b3b80560eb6a35cda20291ddefc709364e59585771c284e46264bfbb0620e23eb8fb274994f7a6f2fcbc8a9430e5d7'; - // the first byte of the BIP340 public key is truncated - const pubkey = '0341d7cf39688e10b5f11f168ad0a9e790bcb429d7d486eab07d2c824b85821470'.substring(2) - const test_msg = Uint8Array.from(Buffer.from("hello", 'utf8')); +## Signature verification - console.log(bip340.verify(test_sig, test_msg, test_pubkey)); +For completeness of the example, we show that the created signatures can be +verified with the public key corresponding to the same canister and derivation +path path. Note that the first byte of the BIP340 public key needs to be removed for +verification, which is done by the verification function below internally. + +```rust +#[query] +async fn verify( + signature_hex: String, + message: String, + public_key_hex: String, + algorithm: SchnorrAlgorithm, +) -> Result { + let sig_bytes = hex::decode(&signature_hex).expect("failed to hex-decode signature"); + let msg_bytes = message.as_bytes(); + let pk_bytes = hex::decode(&public_key_hex).expect("failed to hex-decode public key"); + + match algorithm { + SchnorrAlgorithm::Bip340Secp256k1 => { + verify_bip340_secp256k1(&sig_bytes, msg_bytes, &pk_bytes) + } + SchnorrAlgorithm::Ed25519 => verify_ed25519(&sig_bytes, &msg_bytes, &pk_bytes), + } } -``` - -The call to `verify` function should always return `true` for correct parameters -and `false` or error otherwise. -Similar verifications can be done in many other languages with the help of -cryptographic libraries that support the `bip340secp256k1` signing *with -arbitrary message length* as specified in -[BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#user-content-Messages_of_Arbitrary_Size) -and `ed25519` signing. +fn verify_bip340_secp256k1( + sig_bytes: &[u8], + msg_bytes: &[u8], + secp1_pk_bytes: &[u8], +) -> Result { + assert_eq!(secp1_pk_bytes.len(), 33); + assert_eq!(sig_bytes.len(), 64); +``` ## Conclusion From 1cf098147a71fb36ca491f797e9319ee3b48cfec Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:36 -0600 Subject: [PATCH 07/11] Update rust/x509/README.md --- rust/x509/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 4a6e64495..d6596204d 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -38,7 +38,6 @@ up to the deployment and trying out the code on the mainnet. - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -The minimum version of `dfx` thatrun this example locally is - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Deploy and test the canister locally From 2863b0c8111f8d7e3042eb6a112e2cc255679577 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:42 -0600 Subject: [PATCH 08/11] Update rust/x509/README.md --- rust/x509/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index d6596204d..80a35be82 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -71,7 +71,7 @@ web UI. ## Deploying the canister on the mainnet -To deploy this canister the mainnet, you must do two things: +Before deploying this canister to the mainnet, you must do the following: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. From 6d9ebfff74bcc759939c21ed25f8263ecaf65adb Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:14:48 -0600 Subject: [PATCH 09/11] Update rust/x509/README.md --- rust/x509/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 80a35be82..74526d329 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -38,7 +38,6 @@ up to the deployment and trying out the code on the mainnet. - [x] Install the [IC SDK](https://internetcomputer.org/docs/current/developer-docs/getting-started/install) v`0.23.0` or newer. - [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` -- [x] Clone the example dapp project: `git clone https://github.com/dfinity/examples` ## Deploy and test the canister locally From b53118e326123f553fdf8c36f7406fac6bbd72fb Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:18:18 -0600 Subject: [PATCH 10/11] Update README.md --- rust/x509/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/x509/README.md b/rust/x509/README.md index 74526d329..500429750 100644 --- a/rust/x509/README.md +++ b/rust/x509/README.md @@ -75,11 +75,11 @@ Before deploying this canister to the mainnet, you must do the following: - Acquire cycles (equivalent of "gas" in other blockchains). This is necessary for all canisters. - Update the sample source code to have the right key ID. This is unique to this canister. -- #### Step 1: Acquire cycles to deploy +#### Step 1: Acquire cycles to deploy Deploying to the Internet Computer requires [cycles](https://internetcomputer.org/docs/current/developer-docs/getting-started/tokens-and-cycles) (the equivalent of "gas" on other blockchains). -- #### Step 2: Update source code with the right key ID +#### Step 2: Update source code with the right key ID To deploy the sample code, the canister needs the right key name for the right environment. Specifically, one needs to initialize the canister with the key @@ -95,7 +95,7 @@ There are three options that are supported: Note that `dfx deploy` formats those name in `PascalCase` instead of `snake_case` due to the formatting of types in `rust`. -- #### Step 3: Deploy to the mainnet using the IC SDK +#### Step 3: Deploy to the mainnet using the IC SDK To [deploy via the mainnet](https://internetcomputer.org/docs/current/developer-docs/setup/deploy-mainnet.md), run the following commands: From dbba00a4388703a98e3efdee156e657c6d2778a2 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:18:43 -0600 Subject: [PATCH 11/11] Update rust/threshold-schnorr/README.md --- rust/threshold-schnorr/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/threshold-schnorr/README.md b/rust/threshold-schnorr/README.md index af5af3756..5ec1f0764 100644 --- a/rust/threshold-schnorr/README.md +++ b/rust/threshold-schnorr/README.md @@ -129,7 +129,7 @@ URLs: schnorr_example_rust: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai ``` -The implementation of this canister in Rust is (`schnorr_example_rust`) is +The implementation of this canister in Rust (`schnorr_example_rust`) is deployed on mainnet. It has the URL https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=enb64-iaaaa-aaaap-ahnkq-cai and serves up the Candid web UI for this particular canister deployed on