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 types of 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 the cell value stored as the result of previous operations, resetting the cell 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 SDK as described in Getting started.

  • You have stopped any network replica 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:

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

  2. Change to the folder you are using for your Internet Computer sample projects.

  3. Create a new project by running the following command:

    dfx new calc
  4. Change to your project directory by running the following command:

    cd calc

Modify the default configuration

You have already seen that creating a new project adds a default dfx.json configuration file to your project directory. In this tutorial, you will modify several of the default settings to illustrate ways you can customize your project environment.

To modify the default dfx.json configuration file:

  1. Open the dfx.json configuration file in a text editor, then change the default main.mo program name to calc_main.mo.

    For example:

    {
      "canisters": {
        "calc": {
          "frontend": {
            "entrypoint": "src/calc/public/index.js"
          },
          "main": "src/calc/calc_main.mo"
        }

    For this tutorial, you are changing the name of the source file from main.mo to calc_main.mo to illustrate how the setting in the dfx.json file determines the source file to be compiled.

Modify the default template program

You have already seen that creating a new project creates a default src directory with a template main.mo file. In this tutorial, you will create a new calc_main.mo file for the simple calculator program.

To modify the default template source code:

  1. Change to the source code directory for your project by running the following command:

    cd src/calc
  2. Rename the template main.mo file to calc_main.mo by running the following command:

    mv main.mo calc_main.mo
  3. Open the calc_main.mo file in a text editor and delete the existing content.

  4. 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 {
      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.

Build and deploy the program

You now have a program that you can compile into an executable WebAssembly module that you can deploy—using the canister model—on your local replica network.

To build the program executable:

  1. Change to the root directory for your project,

    For example, if your project directory is ~/ic-projects, run the following command:

    cd ~/ic-projects/calc
  2. Build the WebAssembly executable by running the following command:

    dfx build --skip-frontend
  3. Start the Internet Computer network on your local computer by running the following command:

    dfx start --background
  4. 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 replica network and can test your program by using dfx canister call commands.

To test the program you have deployed on the local replica network:

  1. Use the dfx canister call command to call the calc canister add function and pass it the input argument 10 of type number by running the following command:

    dfx canister call calc add 10 --type number

    Verify that the command returns the value expected for the add function. For example, the program displays output similar to the following:

    (10)
  2. Call the mul function and pass it the input argument 3 but let the interface description language (IDL) parse the argument type 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)
  3. Call the sub function and pass it the input argument 5 of type number by running the following command:

    dfx canister call calc sub 5 --type number

    Verify that the command returns the value expected for the sub function. For example, the program displays output similar to the following:

    (25)
  4. Call the div function and pass it the input argument 5 but let the interface description language (IDL) parse the argument type 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)
  5. Call the clearall function and verify it resets the cell value to zero:

    dfx canister call calc clearall

    For example, the program displays output similar to the following:

    (0)

Testing 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:

  1. Deploy your project using the dfx canister install command and copy the canister identifier that begins with the ic: prefix.

  2. Open a browser and navigate to the address and port number specified in the dfx.json configuration file.

    By default, the URL uses the localhost address (127.0.0.1) and port number 8000.

  3. Add the candid endpoint to access the Candid web interface followed by the required canisterId parameter and canister identifier.

    For example, the full URL should look similar to the following but with the ic:_canister_identifier_ that was returned by the dfx canister install command:

    http://localhost:8000/candid?canisterId=ic:81DDA04F69F40FEEAC
  4. Review the list of function calls and types defined in the program.

  5. 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.

    Calculator functions

Stop the local network

  1. Stop the Internet Computer processes running on your local computer by running the following command:

    dfx stop