Developer Resources
How to Use Candid?
Learn how you can use Candid, the Internet Computer’s interface description language
Using Candid
Performing typical tasks with Candid
In the following examples, we’re going to assume that a counter
canister with the following interface is already deployed on the IC network:
Let’s continue by exploring how developers can interact with the counter
canister via Candid.
Interacting with a Service in a Terminal
The most common way developers interact with the Internet Computer and canister smart contracts is by using the official DFINITY Canister SDK dfx
command-line interface. The tool provides you with the dfx canister call
command for calling a specific deployed canister. If applicable, the tool also provides a method of the smart contract’s service. Arguments can be passed to a method if you specify them as Candid textual values when running the command.
Multiple argument values wrapped in inside parenthesis and separated by commas (,
) can be specified when passing the Candid textual values on the command line.
Here’s how you can use the dfx canister call
command to pass arguments for the inc method by calling the counter canister service.
It is also possible to omit the arguments. In this case, dfx
will generate a random value matching the method type:
Interacting with a Service from a Browser
Candid provides developers a web interface which is called the Candid UI. It enables you to call canister functions from a web browser for testing and debugging purposes. With the help of the UI, you do not have to write front-end code.
Please follow these steps if you wish to test the counter
canister via the Candid UI:
1. Finding the Candid UI canister identifier
You can use the dfx canister id __Candid_UI command to identify the identifier associated with the counter canister
Running the command will display the canister identifier in an output similar to this:
2. Starting the local canister execution environment
Run the following command to start the local execution environment:
3. Navigating to the specified address and port number
Identify the port number and address specified in the configuration file (dfx.json
). The address and port number the local environment binds to is: 127.0.0.1:8000
4. Adding the required parameter and canister identifier
Running the dfx canister id
command will return the Candid UI canister identifier and the canisterId
parameter. To get the full URL, add the CANDID-UI-CANISTER-IDENTIFIER
:
If you navigate to the address, a form will be displayed where you can provide the canister identifier or select a (.did
) file.
You can also lookup the identifier for a specific canister name by adding its name to the command, for example:
5. Displaying the service description
Once you’ve specified a description file or a canister identifier, you can click on Go
. This will display the service description.
6. Reviewing function calls and types
Before continuing, be sure to review the list of types and function calls defined in the program.
7. Displaying the results
Lastly, you can either click on Random so that a value is generated or type a value. To see the results, either click on Query
or Call
.
Interacting with a Service from a Motoko Canister
The advantage of using Motoko to write a canister smart contract is that the Motoko compiler automatically creates a Candid description that is translated from the signature of the canister’s top-level actor class
or actor
. Additionally, the dfx build
command makes sure that the service description is being properly referenced.
The following is an example of a hello
canister in Motoko that is calling the counter
canister:
To ensure that the Candid description, as well as the counter canister identifier, are correctly passed to the Motoko compiler, an import Counter "canister:Counter"
declaration is added. The Candid type is then translated by the Motoko compiler into the native Motoko type that is appropriate.
With the help of this translation, you can natively call the inc
method as if the method were a Motoko function. This is even the case if you do not have access to the source code of the imported canister and also if a different language is used to implement the canister.
Additionally, the Candid description is being auto-generated which allows other canisters to seamlessly interact with the canister as well.
You can find the generated description in your project build directory: .dfx/local/canisters/hello/hello.did
Interacting with a Service from a Rust Canister
If you are using Rust to write a canister, you will have to manually write the Candid service description. As an example, let’s have a look at a hello
canister in which you would like to call the counter
canister written in Rust:
In order to ensure that the Candid description as well as the counter
canister identifier are correctly passed to the Rust CDK, the #[import(canister = "counter")]
declaration is added. The Candid type is then translated by the Rust CDK into the appropriate native Rust type.
With the help of this translation, you can natively call the inc
method as if the method were a Rust function. This is even the case if you do not have access to the source code of the imported canister and also if a different language is used to implement the canister.
If you want other canisters not contract to interact with your hello canister, a .did
file needs to be created manually:
Interacting with a Service from a JavaScript
Feel free to have a look at the provided dfinity/agent npm package which shows you how to import canister smart contracts using Candid. As an example, let’s have a look at how you can call the counter
canister via JavaScript:
The processing of the counter’s import dependency by the dfx build
command and the webpack
configuration ensures that the Candid description and the canister identifier are correctly passed to the JavaScript program. What happens behind the scenes is that the Candid service description gets translated by dfx build
into a JavaScript module which can be found here: .dfx/local/canister/counter/counter.did.js
. The Candid type is then being translated into native JavaScript values by the dfinity/agent
package.
With the help of this translation, you can natively call the inc
method as if the method were a JavaScript function. This is even the case if you do not have access to the source code of the imported canister and also if a different language is used to implement the canister.
Creating a New Candid Implementation
Aside from the aforementioned Motoko, Rust, and JavaScript implementations, the following committee-supported Candid libraries are available as well:
- Haskell
- Elm
- Kotlin
- AssemblyScript