Hello, World! Rust CDK Quick Start

The DFINITY Canister Development Kit (CDK) for Rust provides tools, sample code, and documentation to help you create programs to run on the Internet Computer network. This Hello, World! Rust CDK Quick Start assumes that you are installing the DFINITY Rust CDK for the first time.

To help you get started, this tutorial illustrates how to modify the traditional "Hello World" first program to use the DFINITY Rust CDK. This simple program has just one function that prints text to a terminal, but it provides a good model for understanding the workflow when writing programs in Rust that you want to deploy on the Internet Computer.

Before you begin

Before you start your project, verify the following:

  • You have an internet connection and access to a shell terminal on your local macOS or Linux computer.

  • You have downloaded and installed the Rust programming language and Cargo as described in the Rust installation instructions for your operating system.

    curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

    The Rust tool chain must be at version 1.46.0, or later.

  • You have downloaded and installed the DFINITY Canister Software Development Kit (SDK) package as described in Download and install.

  • You have cmake installed. For example, use Homebrew with the following command:

    brew install cmake

    For instructions on how to install Homebrew, see the Homebrew Documentation.

  • You have stopped any Internet Computer network processes running on the local computer.

If you aren’t sure how to open a new terminal shell on your local computer, run commands in a terminal, or how to check for and install packages, see Preliminary steps for newcomers. If you are comfortable meeting the prerequisites without instructions, continue to Create a new project.

Create a new project

Applications for the Internet Computer start as projects. You can create new projects for the Internet Computer using either Cargo or the DFINITY Canister SDK. Because you are building this project to be deployed on the Internet Computer, this tutorial focuses on how to create, build, and deploy a Rust program by using the dfx parent command and its subcommands. However, creating a new project with cargo new adds some default files to the project directory structure—such as the Cargo.lock and Cargo.toml files—that you will need in your development environment.

  • If you decide to use Cargo to create your project, you will need to manually add some files that the DFINITY Canister Development Kit (CDK) for Rust requires.

  • If you decide to use DFINITY Canister SDK to create your project, you will need to manually add some files that Cargo requires.

To create a new project using the DFINITY Canister SDK:

  1. Open a terminal shell on your local computer, if you don’t already have one open.

  2. Create a new project named rust_hello by running the following command:

    dfx new rust_hello

    The dfx new rust_hello command creates a new rust_hello project directory, template files, and a new rust_hello Git repository for your project.

  3. Change to your project directory by running the following command:

    cd rust_hello

Modify the default configuration

Creating a new project adds several template files to your project directory much like when you create a new Rust package using the cargo new command. You need to modify these default files and add some Rust-specific files to your project before you can build canisters that run on the Internet Computer.

To modify the default configuration for a Motoko project, you’ll need to complete the following steps:

Edit the default canister settings

One of the template files included in your project directory is a default dfx.json configuration file. This file contains settings required to build a project for the Internet Computer much like the Cargo.toml file provides build and package management configuration details for Rust programs. You need to modify the default settings in the dfx.json configuration file to build Rust programs that run on the Internet Computer as canisters.

To modify the dfx.json configuration file:

  1. Check that you are still in the root directory for your project, if needed.

  2. Open the dfx.json configuration file in a text editor.

  3. Notice that under the canisters key, you have some default settings for the rust_hello canister such as the default path to the main program file and a default type of motoko.

  4. Replace the canisters.rust_hello.main key and setting with a canisters.rust_hello.build key and specify the cargo build command to execute.

    For example:

    "build": "cargo build --target wasm32-unknown-unknown --package rust_hello --release",
  5. Add a canisters.rust_hello.candid key and specify the location of the Candid interface description file to use for the canister.

    For example:

    "candid": "src/rust_hello/src/rust_hello.did",
  6. Add a canisters.rust_hello.wasm key and specify the location of the compiled WebAssembly file to use for the canister.

    For example:

    "wasm": "target/wasm32-unknown-unknown/release/rust_hello.wasm",
  7. Modify the canisters.rust_hello.type key and specify custom as the canister type.

    For example:

    "type": "custom"
  8. Remove all of the rust_hello_assets configuration settings from the file.

    The sample program for this tutorial doesn’t use any front-end assets, so you can remove those settings from the configuration file.

    You can also remove the defaults and dfx keys for this tutorial.

    For example, the configuration file looks like this after you remove the `unused sections:

    {
      "canisters": {
        "rust_hello": {
          "build": "cargo build --target wasm32-unknown-unknown --package rust_hello --release",
          "candid": "src/rust_hello/rust_hello.did",
          "wasm": "target/wasm32-unknown-unknown/release/rust_hello.wasm",
          "type": "custom"
        }
       },
      "networks": {
        "local": {
          "bind": "127.0.0.1:8000",
          "type": "ephemeral"
        }
      },
      "version": 1
    }
  9. Save your changes and close the file to continue.

Add a Cargo.toml file to the project

Because we are creating this new Rust project for the Internet Computer using the DFINITY Canister SDK, you need to manually create some Rust-specific files in specific locations within the project directory. Let’s start by creating the Cargo.toml configuration file that describes the packages in our project.

To add a Cargo.toml configuration file for the project:

  1. Check that you are still in the root directory for your project, if needed.

  2. Create a new file in the current directory named Cargo.toml.

  3. Open the Cargo.toml in a text editor.

  4. Use the [workspace] key to specify the source file directory for your program.

    For example:

    [workspace]
    members = [
        "src/rust_hello",
    ]
  5. Save your changes and close the file to continue.

Add Rust files to the source directory

Creating a new project creates a default src/rust_hello directory with a template main.mo. We’ll replace this default program with a Rust library lib.rs package and Cargo.toml files.

To prepare the source directory with Rust files:

  1. Check that you are in the root directory for your project, if needed.

  2. Create a new cargo package using a library template by running the following command:

    cargo init --lib src/rust_hello

    This command creates a src/rust_hello/src directory with a library (lib.rs) package and a Cargo.toml file in the src/rust_hello directory.

  3. Open the src/rust_hello/Cargo.toml file in a text editor.

    You use this file to configure the details used to build the Rust package.

    At a minimum, you need to configure the following sections with basic information about the package name, the crate type, and the version of the DFINITY Rust CDK libraries to use.

    • [package]

    • [lib]

    • [dependencies]

  4. Delete the existing [dependencies] section and replace it with the following:

    [lib]
    crate-type = ["cdylib"]
    
    [dependencies]
    ic-cdk = "0.3"
    ic-cdk-macros = "0.3"
    When you deploy the app later in the tutorial, you might get an error message that the dependency version is wrong. If there is a newer version of the DFINITY Rust CDK, update the dependencies in the src/rust_hello/Cargo.toml file to match the latest version.
  5. Save your changes and close the file to continue.

Replace the default program

Now that you have the files in place for your Rust program, we can replace the template main.mo program with the Rust program we want to deploy on the Internet Computer.

To replace the default program:

  1. Check that you are still in the root directory for your project, if needed.

  2. Delete the template src/rust_hello/main.mo file by running the following command:

    rm src/rust_hello/main.mo
  3. Open the template src/rust_hello/src/lib.rs file in a text editor and delete the existing content.

  4. Write a simple print function that uses the DFINITY Rust CDK query macro.

    For example:

    #[ic_cdk_macros::query]
    fn print() {
        ic_cdk::print("Hello World from DFINITY!");
    }
  5. Save your changes and close the file to continue.

Add an interface description file

Candid is an interface description language (IDL) for interacting with canisters running on the Internet Computer. Candid files provide a language-independent description of a canister’s interfaces including the names, parameters, and result formats and data types for each function a canister defines.

By adding Candid files to your project, you can ensure that data is properly converted from its definition in Rust to run safely on the Internet Computer.

To see details about the Candid interface description language syntax, see the Candid Guide or the Candid crate documentation.

To add a Candid file for this tutorial:

  1. Check that you are still in the root directory for your project, if needed.

  2. Create a new file in the src/rust_hello/src/ directory named rust_hello.did.

  3. Open the src/rust_hello/src/rust_hello.did file in a text editor.

  4. Copy and paste the following service definition for the print function:

    service : {
        "print": () -> () query;
    }

    This definition specifies that the data passed to the print function is returned unchanged as a query result.

  5. Save your changes and close the file to continue.

Start the local network

Before you can build your project, you need to connect to the Internet Computer network either running locally in your development environment or running remotely on a sub-network that you can access.

To start the network locally:

  1. Check that you are still in the root directory for your project, if needed.

  2. Start the Internet Computer network on your local computer in the background by running the following command:

    dfx start --background

    Depending on your platform and local security settings, you might see a warning displayed. If you are prompted to allow or deny incoming network connections, click Allow.

Register, build, and deploy your project

After you connect to the Internet Computer network running locally in your development environment, you can register, build, and deploy your project locally.

To register, build, and deploy:

  1. Check that you are still in root directory for your project directory, if needed.

  2. Register, build, and deploy the canisters specified in the dfx.json file by running the following command:

    dfx deploy

    The dfx deploy command output displays information about each of the operations it performs similar to the following excerpt:

    Creating a wallet canister on the local network.
    The wallet canister on the "local" network for user "pubs_user_id" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
    Deploying all canisters.
    Creating canisters...
    Creating canister "rust_hello"...
    "rust_hello" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"
    Building canisters...
    Executing 'cargo build --target wasm32-unknown-unknown --package rust_hello --release'
        Updating crates.io index
       Compiling unicode-xid v0.2.2
       ...
    Building canisters...
    Executing 'cargo build --target wasm32-unknown-unknown --package rust_hello --release'
       Compiling rust_hello v0.1.0 (/Users/lisagunn/CDK-RS-APR-2021/rust_hello/src/rust_hello)
        Finished release [optimized] target(s) in 1.26s
    Installing canisters...
    Creating UI canister on the local network.
    The UI canister on the "local" network is "rkp4c-7iaaa-aaaaa-aaaca-cai"
    Installing code for canister rust_hello, with canister_id r7inp-6aaaa-aaaaa-aaabq-cai
    Deployed canisters.

Test the program

To test the deployed program locally:

  1. Check that you are still in root directory for your project directory, if needed.

  2. Call the print function in the program by running the following command:

    dfx canister call rust_hello print
  3. Verify that the call to the rust_hello canister print function displays the Hello World from DFINITY! greeting.

    For example:

    [Canister ryjl3-tyaaa-aaaaa-aaaba-cai] Hello World from DFINITY!
    ()

Stop the local network

After testing the application, you can stop the local Internet Computer network so that it doesn’t continue running in the background.

To stop the local network:

  1. In the terminal that displays network operations, press Control-C to interrupt the local network process.

  2. Stop the local Internet Computer network running on your local computer by running the following command:

    dfx stop