Exploring calculator functions
In this tutorial, you are going to write a simple calculator program that creates a single actor with several public entry-point functions to perform basic arithmetic operations.
For this tutorial, the actor is named Calc
.
The program uses the cell
variable to contain an integer number that represents the current result of a calculator operation.
This program supports the following function calls:
-
The
add
function call accepts input and performs addition. -
The
sub
function call accepts input and performs subtraction. -
The
mul
function call accepts input and performs multiplication. -
The
div
function call accepts input and performs division. -
The
clearall
function clears thecell
value stored as the result of previous operations, resetting thecell
value to zero.
The div
function also includes code to prevent the program from attempting to divide by zero.
Before you begin
Before starting the tutorial, verify the following:
-
You have downloaded and installed the DFINITY Canister SDK package as described in Download and install.
-
You have stopped any Internet Computer network processes running on the local computer.
This tutorial takes approximately 20 minutes to complete.
Create a new project
To create a new project for this tutorial:
-
Open a terminal shell on your local computer, if you don’t already have one open.
-
Change to the folder you are using for your Internet Computer sample projects.
-
Create a new project by running the following command:
dfx new calc
-
Change to your project directory by running the following command:
cd calc
Modify the default configuration
For this tutorial, let’s modify the default dfx.json
configuration file to use a more specific name for its main program.
To modify the default dfx.json
configuration file:
-
Open the
dfx.json
configuration file in a text editor. -
Change the
main
key setting from the defaultmain.mo
program name tocalc_main.mo
.For example:
"main": "src/calc/calc_main.mo",
For this tutorial, you are changing the name of the source file from
main.mo
tocalc_main.mo
to illustrate how this setting in thedfx.json
file determines the source file to be compiled. -
Save your changes and close the file to continue.
Modify the default program
For this tutorial, you need to replace the default program with a program that performs basic arithmetic operations.
To replace the default program:
-
Check that you are still in your project directory, if needed.
-
Copy the template
main.mo
file to create a new file namedcalc_main.mo
by running the following command:cp src/calc/main.mo src/calc/calc_main.mo
-
Open the
src/calc/calc_main.mo
file in a text editor and delete the existing content. -
Copy and paste the following sample code into the
calc_main.mo
file:// This single-cell calculator defines one calculator instruction per // public entry point (add, sub, mul, div). // Create a simple Calc actor. actor Calc { flexible var cell : Int = 0; // Define functions to add, subtract, multiply, and divide public func add(n:Int) : async Int { cell += n; cell }; public func sub(n:Int) : async Int { cell -= n; cell }; public func mul(n:Int) : async Int { cell *= n; cell }; public func div(n:Int) : async ?Int { if ( n == 0 ) { // null encodes div-by-zero error return null } else { cell /= n; ?cell } }; // Clear the calculator and reset to zero public func clearall() : async Int { if (cell : Int != 0) cell -= cell; return cell }; };
You might notice that this sample code uses integer (
Int
) data types, enabling you to use positive or negative numbers. If you wanted to restrict the functions in this calculator code to only use positive numbers, you could change the data type to only allow natural (Nat
) data. -
Save your changes and close the file to continue.
Start the local network
Before you can build the calc
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:
-
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/calc
in the new terminal if yourcalc
project is in theic-projects
working 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 start
After you start the local network, the terminal displays messages about network operations.
-
Leave the terminal that displays network operations open and switch your focus to your original terminal where you created your new project.
Register canister identifiers
After you connect to the Internet Computer network running locally in your development environment, you can register with the network to generate unique, network-specific canister identifiers for your project.
To register canister identifiers for the local network:
-
Check that you are still in your project directory, if needed.
-
Register unique canister identifiers for the canisters in the project by running the following command:
dfx canister create --all
The command displays the network-specific canister identifiers for the canisters defined in the
dfx.json
configuration file."calc" canister created with canister id: "75hes-oqbaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q" "calc_assets" canister created with canister id: "cxeji-wacaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q"
Build and deploy the program
You now have a program that you can compile into an executable WebAssembly module that you can deploy on your local Internet Computer network.
To build and deploy the program:
-
Check that you are still in your project directory by running the
pwd
command, if necessary. -
Build the WebAssembly executable by running the following command:
dfx build calc
For this tutorial, you can build your project using the
calc
canister name because the project is a simple terminal-based applications that doesn’t include any front-end assets. -
Deploy your
calc
project on the local network by running the following command:dfx canister install calc
Verify calculator functions on the canister
You now have a program deployed as a canister on your local Internet Computer network.
You can test the program by using dfx canister call
commands.
To test the program you have deployed:
-
Use the
dfx canister call
command to call thecalc
canisteradd
function and pass it the input argument10
by running the following command:dfx canister call calc add '(10)'
When you pass an argument enclosed by the single quotation marks and parentheses,the interface description language (IDL) parses the argument type, so you don’t need to specify the argument type manually.
Verify that the command returns the value expected for the
add
function. For example, the program displays output similar to the following:(10)
-
Call the
mul
function and pass it the input argument3
by running the following command:dfx canister call calc mul '(3)'
Verify that the command returns the value expected for the
mul
function. For example, the program displays output similar to the following:(30)
-
Call the
sub
function and pass it the input argument5
of typenumber
by running the following command:dfx canister call calc sub '(5)'
Verify that the command returns the value expected for the
sub
function. For example, the program displays output similar to the following:(25)
-
Call the
div
function and pass it the input argument5
by running the following command:dfx canister call calc div '(5)'
Verify that the command returns the value expected for the
div
function. For example, the program displays output similar to the following:(opt 5)
You might notice that the
div
function returns an optional result. The program makes the result optional to enable thediv
function to returnnull
in the case of a division-by-zero error.Because the cell variable in this program is an integer, you can also call its functions and specify negative input values. For example, you might run the following command:
dfx canister call calc mul '(-4)'
which returns:
(-20)
-
Call the
clearall
function and verify it resets thecell
value to zero:dfx canister call calc clearall
For example, the program displays output similar to the following:
(0)
Test functions in a browser
The canister interface description language—often referred to as Candid or more generally as the IDL—provides a common language for specifying the signature of a canister service.
The language provides a unified way of interacting with canisters in various languages and tools, such as the dfx
command-line interface, JavaScript, and Motoko.
Based on the type signature of the actor, Candid provides a web interface that allows you to call canister functions for testing and debugging.
To use the Candid web interface to test canister functions:
-
Deploy your project using the
dfx canister install
command and copy the canister identifier associated with the main actor for your application. -
Open a browser and navigate to the address and port number specified in the
dfx.json
configuration file.By default, the
local
network binds to the127.0.0.1:8000
address and port number. -
Add the
candid
endpoint to access the Candid web interface followed by the requiredcanisterId
parameter and canister identifier.For example, the full URL should look similar to the following but with the
canister_identifier
that was returned by thedfx canister install
command:http://127.0.0.1:8000/candid?canisterId=<YOUR-CANISTER-IDENTIFIER>
-
Review the list of function calls and types defined in the program.
-
Type a value of the appropriate type for a function or click Lucky to generate a value, then click Call or Query to see the result.
Note that depending on the data type, the Candid interface might display additional configuration settings for testing functions. For example, if a function takes an array, you might need to specify the number of items in the array before entering values.
Stop the local network
After you finish experimenting with your program, you can stop the local Internet Computer network so that it doesn’t continue running in the background.
To stop the local network:
-
In the terminal that displays network operations, press Control-C to interrupt the local network process.
-
Stop the Internet Computer network by running the following command:
dfx stop