Develop using different languages
Most of the examples in this guide use Motoko—the programming language specifically designed to work with the Internet Computer. Potentially, however, you can write programs in any language that compiles to WebAssembly to deploy applications that run on the Internet Computer. This section provides some high-level guidance for writing programs in different languages and how to deploy them on the Internet Computer.
Using Rust
You can create Rust projects to run on the Internet Computer by using Cargo and compiling your program to use WebAssembly as the target output.
This section provides a summary of the key steps involved in deploying a Rust program as a smart contract canister on the Internet Computer. You should note, however, that the steps described here only illustrate one approach. Other implementation approaches are also possible.
Note that the Rust canister development kit (Rust CDK) for provides some shortcuts to make it easier to write functions as query and update calls and includes several examples to get you started building Rust-based projects, but you can also develop applications for the Internet Computer without using the Rust CDK.
Create a project
Because most Rust programmers use Cargo to handle build and package management tasks—such as downloading and compiling the libraries your program depends on—your first step is to create a new Rust project using the Cargo command-line interface.
Alternatively, you could create a new project using DFINITY Canister Software Development Kit (SDK) instead of Cargo, but creating a project using Cargo represents the typical workflow for creating Rust projects.
To create a new Rust project:
-
Open a terminal shell on your local computer, if you don’t already have one open.
-
Verify that you have Cargo installed by running the following command:
cargo --version -
Change to the folder you are using for your Internet Computer or Rust sample projects.
-
Create a new project by running a command similar to the following:
cargo new my_rust_programThis command creates a new
my_rust_programdirectory with a defaultCargo.tomlfile and asrcdirectory with a defaultmain.rsfile. -
Change to your project directory by running the following command:
cd my_rust_programIf you list the contents of this directory, you’ll see that it only contains the
Cargo.tomlfile andsrcdirectory. To compile this project to run on the Internet Computer, you’ll need some additional files.
Modify the Cargo configuration file
The Cargo.toml file provides a manifest for each Rust package.
The manifest contains sections that specify configuration details for the package.
To prepare the Rust project to run on the Internet Computer, we’ll copy the default Cargo.toml file then modify some of the configuration details for the project.
To modify the Cargo.toml file:
-
Check that you are in the root directory for your project by running the
pwdcommand, if necessary. -
Copy the default
Cargo.tomlfile to thesrcdirectory by running the following command:cp Cargo.toml src/Cargo.tomlProjects that run on the Internet Computer typically use one project-level
Cargo.tomlfile to set up a workspace for the canister members of the project and a secondCargo.tomlfile in the source code directory to configure settings for each canister. -
Open the
Cargo.tomlfile that is the root directory of your project in a text editor.By default, the file contains the
[package]and the[dependencies]sections. -
Replace the
[package]section with a[workspace]section similar to the following:[workspace] members = [ "src/my_rust_program", ]For information about the
[workspace]section and[workspace]keys, see Workspaces. For information about the other sections and keys you can configure in theCargo.tomlfile, see The Manifest Format. -
Remove the
[dependencies]section. -
Save your changes and close the file to continue.
-
Open the
src/Cargo.tomlfile in a text editor. -
Add a
[lib]section with the path to the main source code similar to the following:[lib] path = "main.rs" -
Update the
[dependencies]section with any package dependencies. -
Save your changes and close the file to continue.
Add a canister configuration file
When you create a new project using the DFINITY Canister SDK, the dfx new command automatically adds a default dfx.json configuration file to the project directory.
Because we created the Rust project using Cargo, you need to manually create this file in your project directory.
To add the dfx.json configuration file:
-
Check that you are still in your project directory by running the
pwdcommand, if necessary. -
Create a new
dfx.jsonconfiguration file in the root directory for your project. -
Open the `dfx.json`file in a text editor.
-
Add the
versionandcanisterskeys with settings similar to the following to thedfx.jsonfile:{ "version": 1, "canisters": { "my_rust_program": { "type": "custom", "candid": "src/my_rust_program.did", "wasm": "target/wasm32-unknown-unknown/debug/my_rust_program.wasm", "build": "cargo build --target wasm32-unknown-unknown --package my_rust_program" } } }Let’s take a closer look at these settings.
-
The
versionsetting is used to identify the version of the software used to create the project. -
The
canisterssection specifies the name of the project’s canisters. In this case, there’s only one canister and it is namedmy_rust_program. -
The
typekey is set tocustombecause this canister is not one of the currently recognized (motokoorassets) canister types. -
The
candidkey specifies the name and location of the Candid interface description file to use for this project. -
The
wasmkey specifies the path to the WebAssembly file generated by thecargo buildcommand. -
The
buildkey specifies thecargocommand used to compile the output.
These are the minimum settings required. As you build more complex programs, you might need to include additional configuration details in the
Cargo.tomlfile, thedfx.jsonfile, or both files. -
-
Save your changes and close the file to continue.
Create a Candid interface description file
In addition to the dfx.json configuration file, you need to have a Candid interface description file—for example, my_rust_program.did—to map your program’s input parameters and return value formats to their language-agnostic representation in Candid.
To add the Candid interface description file:
-
Check that you are still in your project directory by running the
pwdcommand, if necessary. -
Create a new Candid interface description file—for example,
my_rust_program.did—in thesrcdirectory for your project. -
Open the Candid interface description file in a text editor and add a description for each function the program defines.
For example, if the
my_rust_programis a simple program that increments a counter using theincrement,read, andwritefunctions, themy_rust_program.didfile might look like this:service : { "increment": () -> (); "read": () -> (nat) query; "write": (nat) -> (); } -
Save your changes and close the file to continue.
Modify the default program
When you create a new project, your project src directory includes a template main.rs file with the "Hello, World!" program.
To modify the template source code:
-
Open the template
src/main.rsfile in a text editor and delete the existing content. -
Write the program you want to deploy on the Internet Computer.
As you write your program, keep in mind that there are two types of calls—update calls and query calls—and that update functions use asynchronous messaging.
-
Save your changes and close the
main.rsfile.
Connect to a network and deploy
Before you can deploy and test your program, you need to do the following:
-
Connect to the Internet Computer network either running locally in your development environment or running remotely on a subnet that you can access.
-
Register a network-specific identifier for the application
-
Compile the program with a target output of WebAssembly.
Because you configured the custom dfx.json file with a cargo build command that compiles to WebAssembly, you can use the dfx command-line interface and standard work flow to perform all of the remaining steps.
To build and deploy the program locally:
-
Check that you are still in your project directory by running the
pwdcommand, if necessary. -
Open a new terminal window or tab on your local computer and navigate to your project directory.
For example, you can do either of the following if running Terminal on macOS:
-
Click Shell, then select New Tab to open a new terminal in your current working directory.
-
Click Shell and select New Window, then run
cd ~/ic-projects/location_helloin the new terminal if yourlocation_helloproject is in theic-projectsworking folder.
You should now have two terminals open with your project directory as your current working directory**.
-
-
Start the Internet Computer network on your local computer by running the following command:
dfx startDepending 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.
-
Leave the terminal that displays network operations open and switch your focus to your original terminal where you created your project.
-
Register a unique canister identifier for the application by running the following command:
dfx canister create --all -
Build the program by running the following command:
dfx build -
Deploy the program on the local network by running the following command:
dfx canister install --all -
Test functions in the program from the command-line or in a browser.
Using C
Because the Internet Computer supports applications compiled to standard WebAssembly modules, you can use standard compilers and toolchains to build applications in languages such as C, C++, Objective-C, and Objective-C++ programming languages and the Clang compiler.
To illustrate how to migrate programs written in C to run on the Internet Computer, let’s look at the simple reverse.c program in the examples repository.
The reverse.c program contains one function—named go—that reverses a string in place.
Set up the development environment
To compile the reverse.c program into WebAssembly, you need to have the clang compiler and standard libraries installed.
You can check whether you have clang installed on your local computer by running the following command:
clang --version
If clang is installed, the command displays information similar to the following:
clang version 10.0.0 Target: x86_64-apple-darwin19.5.0 Thread model: posix InstalledDir: /usr/local/opt/llvm/bin
If the command doesn’t return version information, install clang before continuing.
The steps to install clang vary depending on the operating system you are using.
On Debian Linux, for example, run the following command:
sudo apt-get install clang lld gcc-multilib
On macOS, you can install clang by installing the Developer Command-Line Tools or by installing LLVM using Homebrew.
For example, if clang is not installed, run the following command:
brew install llvm
Compile the program into WebAssembly
You can compile a C program to run as a WebAssembly module by first compiling using clang, then linking using wasm-ld.
Depending on the operating system and version of clang you are using, you might use a different version of the WebAssembly linker, such as wasm-ld on macOS or wasm-ld-8 on Debian.
To compile to WebAssembly on macOS:
-
Compile the program by running the following clang command:
clang --target=wasm32 -c -O3 reverse.c -
Run the linker to create the WebAssembly module by running the following
wasm-ldcommand:wasm-ld --no-entry --export-dynamic --allow-undefined reverse.o -o reverse.wasm
Create a minimal configuration file
Next, you need to prepare a simple configuration file that identifies the reverse program binary as a package that can be installed on the Internet Computer and a build directory so that you can use the dfx command-line interface to install and run the package as a canister.
To prepare a configuration file and build directory:
-
Create a
dfx.jsonfile with a canisters key by running the following command:echo '{"canisters":{"reverse":{"main":"reverse"}}}' > dfx.json -
Create a
builddirectory for the program by running the following command:mkdir build -
Create a
reversedirectory for the program by running the following command:mkdir build/reverse -
Copy the WebAssembly modules to the new
build/reversedirectory by running the following command:cp reverse.wasm build/reverse/
Create a minimal interface description file
In a standard development workflow, running the dfx build command creates several files in the canisters output directory, including one or more Candid interface description (.did) files that handle type matching for the data types associated with a program’s functions.
For details about the syntax to use for different data types, see the Candid Guide and Candid specification.
To create a Candid interface description file for this program:
-
Open a terminal in the
builddirectory you created for thereverse.cprogram source -
Create a new text file named
reverse.did. -
Add a description of the
gofunction.For example:
service : { "go": (text) -> (text); } -
Save your changes and close the file to continue.
Deploy and test the program
Before you can deploy and test your program, you need to do the following:
-
Connect to the Internet Computer network either running locally in your development environment or running remotely on a subnet that you can access.
-
Register a network-specific identifier for the application.
To deploy and test the application locally:
-
Open a new terminal window or tab on your local computer.
For example, if running Terminal on macOS,click Shell, then select New Tab to open a new terminal in your current working directory.
-
Start the Internet Computer network on your local computer in your second terminal by running the following command:
dfx start -
Register a unique canister identifier for the
reverseapplication by running the following command:dfx canister create --all -
Deploy the default program on the local network by running the following command:
dfx canister install --all -
Call the
gofunction in the program by running the following command:dfx canister call reverse go reward ("drawer")
You can find additional examples of C programs in the examples repository.