Canisters and code
One of the most important principles to keep in mind is that the Internet Computer is primarily a distributed and decentralized platform for running software.
When you write source code for an application that runs on the Internet Computer, you compile the source code into a WebAssembly module. When you deploy the WebAssembly module that contains your program on an Internet Computer replica, the program is executed inside of a conceptual computational unit called a software canister.
Once deployed, end-users can interact with the software canister by accessing the entry point functions you have defined for that canister through a front-end client such as a browser.
A software canister is similar to a container in that both are deployed as a software unit that contains compiled code and dependencies for an application or service.
Containerization allows for applications to be decoupled from the environment, allowing for easy and reliable deployment. The canister differs from a container, however, in that it also stores information about the current software state with a record of preceding events and user interactions.
While a containerized application might include information about the state of the environment in which the application runs, a software canister is able to persist a record of state changes that resulted from an application’s functions being used.
This concept of a canister consisting of both program and state is an important one because when a canister function is invoked by sending a message to one of its entry points, there are only two types of calls: non-committing query calls and committing update calls.
|Type||Key points to remember|
Allow the user to query the current state of a canister or call a function that operates on the canister’s state without changing it.
Allow the user to change the state of the canister and have changes persisted.
As a developer, it is important to recognize this relationship between the calls that query the canister and the calls that change the canister state. In particular, you should keep in mind the inherent tradeoff between security and performance.
For programmers and software developers, the Internet Computer platform provides unique capabilities and opportunities within a framework that simplifies how you can design, build, and deploy applications. A key part of this framework is a new, general purpose programming language, Motoko. Motoko is a programming language that has been specifically designed to take full advantage of the unique features that the Internet Computer provides, including:
The ability to define programs directly using
actorobjects and classes.
The use of
awaitsyntax to enable programming asynchronous messaging as if it was synchronous processing.
Automatic support for message serialization and deserialization.
The ability to leverage orthogonal persistence using data structures without external databases or storage volumes.
As a modern, high-level programming language, Motoko provides some key features of its own, including:
Support for big integer operations and overflow protection.
A sound type system that statically checks each program to ensure it can execute without type errors on all possible inputs.
Support for function abstractions, user-defined type definitions, and user-defined actors.
For more detailed information about the Motoko programming language itself, including syntactical conventions and supported features, see the Motoko Programming Language Guide.
The following diagram provides a simplified drill-down view of the development environment as part of the Internet Computer ecosystem.
One of the most important principles to keep in mind when preparing to write programs using the Motoko programming language is that Motoko uses an actor-based programming model.
An actor is a special kind of object that processes messages in an isolated state, enabling messages to be handled remotely and asynchronously. Many key features of the Internet Computer platform depend on this type of secure and efficient asynchronous message handling.
In general, each software canister includes the compiled code for one actor object. Each canister also includes some additional information such as interface descriptions or front-end assets. You can create projects that include multiple canisters, but each canister can only include one actor.
When you compile Motoko code, the result is a WebAssembly module. WebAssembly is a low-level computer instruction format that is portable and abstracts program execution cleanly over most modern computer hardware. It is broadly supported for programs that run on the internet and a natural fit for deploying applications that are intended to run on the Internet Computer platform.
With Motoko, developers can compile to portable WebAssembly while still delivering secure applications using a simple and high-level language.
The Motoko language offers many of the features that are common to other higher-level modern languages—like type safety and pattern-matching. In addition, Motoko provides built-in support for defining messaging services using actors in a way that is especially well-suited to the Internet Computer platform and is easy to learn whether you are a new or experienced programmer.
This guide provides an introduction to the basic features of the Motoko programming language in the context of writing programs using the SDK. For more detailed information about the Motoko programming language itself, see the Motoko Programming Language Guide.
One of the main differences between a user-initiated canister operation and a canister-to-canister operation is that canisters have an explicitly registered identity on the [IC].
There is no central registry for user principals. Instead, user identifiers are associated specifically with the canisters each user accesses through one or more public-private key pairs. The user’s private key is used to sign messages, which are sent along with their public key to a canister. The [IC] authenticates the user and passes the principal to the canister for the authorization of their operation.
At a high level, first-time users generate an unsigned key pair and derive their principal identifier from the public key during their first interaction with the Internet Computer. Returning users are authenticated using the private key (or keys) that have been stored securely by the user agent. Users with access to multiple canisters can manage the keys and devices used for authentication associated with each canister.
A single user can have multiple public-private key pairs for accessing canisters from different devices—such as browsers running on different computers, mobile phones, or tablets—but these derived keys all map to a primary identifier.
In general, all canisters consume resources in the form of CPU cycles for execution, bandwidth for routing messages, and memory for persisted data. Canisters maintain an account balance of cycles to pay for the cost of communication, computation, and storage that their applications consume.
Cycles are intended to reflect the real cost of operations including physical hardware, rack space, energy, storage devices, and bandwidth in a stable or deflationary way so that the cost of program execution remains the same or decreases with operational efficiency.
Programs must be able to pay for complete execution (all or nothing), but the cost associated with a unit of cycles will make efficient programs cost-effective.
By setting limits on how many cycles a canister can consume, the platform can prevent malicious code from draining resources.
The relative stability of operational costs makes it easier to predict the cycles required to process, for example, a million messages.
The cycles available for program execution are held in a wallet canister. For local deployment, wallet canisters are automatically created and issued cycles. To deploy your application on the Internet Computer network running on external nodes and subnets, however, you’ll need to provide a principal and be issued a wallet canister identifier.
|When you deploy canisters locally or to an Internet Computer test network, program execution consumes cycles but there are no funds associated with those cycles. However, it is possible that in calculating the operations to be performed, executing a program might result in an “out of cycles” exception because the operations would exceed a predefined threshold. If you see this exception in testing, you can temporarily configure a higher cycles limit by setting a command-line option.|
If you are looking for more information about canisters, check out the following related resources: