Overview of ICP
The Internet Computer Protocol (ICP) is a blockchain based on threshold cryptography, state machine replication, and a novel consensus algorithm.
It was carefully designed to give smart contracts near native performance and scalability while maintaining the security of decentralized execution. In addition to classical DeFi smart contracts, such as ledgers and exchanges, ICP can run compute- and storage-heavy applications such as image classification fully onchain.
Another important design aspect of ICP is its seamless and secure integration with existing ecosystems. Smart contracts on ICP can host web assets and serve HTTP requests from users, thus fulfilling the promise of Web3. They can also interact with RPC nodes of other blockchains and Web2 servers through secure HTTP requests. These features, combined with threshold signatures, give smart contracts the ability to hold assets and make transactions on other blockchains such as Bitcoin and Ethereum.
Read on to learn more about how these features are made possible.
Subnets
A blockchain can only run as fast and offer as many resources as a single node. One of the keys to overcoming this limit is sharding. ICP shards smart contracts over multiple instances of the blockchain. Each instance is called a subnet and has its own set of decentralized nodes running the consensus algorithm among themselves, building their own chain of blocks, and executing smart contracts. Each subnet runs in parallel with other subnets. A smart contract on one subnet can communicate with another smart contract on a different subnet through sending messages. Users can also send messages to smart contracts. The following diagram shows the flow of a message on ICP:
- The message goes to one of the boundary nodes (RPC nodes).
- The boundary node routes the message to the subnet that hosts the target smart contract.
- The consensus algorithm of that subnet adds the message to a new block in the subnet's blockchain.
- The message is added to the input queue of the target smart contract.
- The smart contract executes the message.
Note that steps 3-5 are asynchronous and decoupled from each other, which may be unusual for developers who are used to Ethereum-style atomic transactions that are executed when they are added to a block. The motivation for this design is scalability.
Subnets can have different sizes, i.e., replication factors, which determine the cost of running smart contracts on that subnet. It also impacts the time to finality and security.
Threshold signatures
Each ICP subnet has a fixed public key. The corresponding private key is not stored on a single node, nor is it ever available on any node. Instead, it is split into multiple secret shares and distributed over all nodes using threshold cryptography. Nodes can collectively sign messages to users and other subnets using these secret shares. This makes validation of the state and results trivial for users since all they need to do is verify the digital signature against the fixed public key without downloading and validating blocks in the blockchain.
This feature has profound implications and use cases:
- There is no need to keep the blocks in the blockchain available forever, which would be a scalability bottleneck. In fact, ICP actively garbage collects old blocks to keep storage usage bounded.
- Smart contracts can have their own secret keys and can sign transactions for other blockchains such as Bitcoin and Ethereum. This enables trustless interaction with those blockchains.
This feature is called Chain-Key Cryptography on ICP.
Smart contracts
ICP uses WebAssembly as the virtual machine for executing smart contracts. This means developers can write smart contracts in popular programming languages such as JavaScript, TypeScript, Rust, Python, and Motoko, which is specifically designed for ICP.
Furthermore, a single smart contract on ICP is powerful enough to host an entire Ethereum Virtual Machine (EVM). This allows the deployment of EVM smart contracts written in Solidity.
A unique feature of ICP is that smart contracts can handle HTTP requests and serve web assets such as HTML, JS, and CSS. In other words, it is possible to write a Web3 application with both backend and frontend hosted fully onchain. Smart contracts can also make requests to other Web2 services outside ICP.
Ethereum developers may be used to the notion that smart contracts run sequentially within an atomic transaction. ICP embraces scalability and runs smart contracts in parallel. In that regard, smart contracts are similar to processes or microservices from traditional programming. Smart contracts can be fully autonomous and can schedule execution using timers without relying on users sending messages.
In terms of storage, a smart contract can store arbitrary data in its WebAssembly memory. Additionally, a smart contract can use a larger stable memory. The difference between the two memories is important for upgradable smart contracts: the WebAssembly memory is cleared on an upgrade whereas the stable memory is preserved (hence the name “stable”). For immutable smart contracts, there is no observable difference between the two memories except for the size and functions to access them.
In the context of ICP, smart contracts are referred to as canisters.
Accounts and keys
ICP derives the address of a user account from the user’s public key by hashing it.
The textual encoding of an address includes a checksum that looks something like this:
mh4eq-xsi7l-lgz7s-gmxoh-stiey-277n4-lev4o-q6hah-22sk6-ahlhm-qae
ICP supports multiple types of keys (ECDSA, Ed25519, BLS). Developer tools usually generate and accept keys in PEM format.
Smart contracts can provide user accounts as a service. Internet Identity is an example of a smart contract that allows Web2 users to have blockchain accounts that leverage user authentication to map the user to an identity and provide delegation to the relying party.
You can also use hardware and browser-extension wallets.
In the context of ICP, addresses are referred to as principals.
Tokens
Accounts on ICP do not have built-in balances, which is a large design difference when compared to other chains like Ethereum. All tokens are implemented by smart contracts. ICP has an equivalent of the ERC-20 standard, called ICRC-2. If a smart contract implements ICRC-2, then it implements a fungible token and has a ledger for it.
Messages
The programming model of ICP is similar to the Actor model, where calls are made by sending messages instead of transactions. The difference between a transaction and a message becomes apparent only when the smart contract calls other smart contracts. A transaction is atomic in the sense that it rolls back all state changes if any of the calls fail. A message does not have such atomicity guarantees across calls. Programming on ICP is more asynchronous compared to Ethereum. If the smart contract does not make any calls, then the message behaves exactly like a transaction.
Cycles
On other blockchains, such as Ethereum, users pay a variable fee for sending and executing transactions depending on the current gas price. In order to simplify the experience of users browsing Web3 applications, ICP employs a “reverse gas model”, where canisters pay for consumed resources by burning cycles. This is similar to gas in Ethereum, but has a fixed price correlating to a group of fiat currencies.
Governance
ICP is governed by a decentralized autonomous organization (DAO) community called the Network Nervous System (NNS). It is implemented as a set of smart contracts running on ICP itself. Community members can participate in governance by staking ICP tokens and voting on proposals. All operational changes to ICP, such as upgrading nodes, go through voting. NNS automatically executes proposals that have passed voting, which ensures that nodes run the same version of the protocol and thus avoids hard forks.
Governance and node ownership are decoupled. It is possible to participate in governance without having a node, and vice versa.
Nodes
Becoming a node provider on ICP requires voting from the DAO community. There are two reasons for this:
- It ensures that the hardware meets the high standards of ICP: 64 CPU cores, 512GiB of RAM, 30TB of NVMe SSD. Such nodes can sustain high throughput and enable powerful Web3 applications.
- It ensures that the identity of the node provider is known to the community. The node provider has signed a declaration of good intent and may be liable if the node misbehaves. This makes Sybil attacks harder to pull off and allows for the ability to reduce the number of nodes while keeping the Nakamoto coefficient high. Nodes are assigned to subnets such that they maximize decentralization, in terms of operators, geography, and jurisdiction. This is called deterministic decentralization.
Currently, subnets contain between 13 and 40 nodes, and most of them are geographically distributed. However, there can also be localized subnets to support applications that need to comply with local regulations.
Quick comparison with Ethereum
Ethereum | ICP | |
---|---|---|
Virtual machine | EVM | WebAssembly |
Onchain Web3 | - | Yes |
Bridgeless Bitcoin | - | Yes |
Smart contracts can sign messages | - | Yes |
HTTP calls to Web2 from smart contracts | - | Yes |
Languages | Solidity, Vyper, Yul | JS, Python, Rust, Solidity, Motoko, and more |
Programming model | Atomic transactions | Async message passing |
Upgradeability | Immutable | Upgradable or immutable |
Gas model | User pays | Smart contract pays |
Gas price | Variable | Fixed |
Compute | Few million instructions per block (based on the 30 million gas limit) | 2 billion instructions per block (per subnet) |
Finality | ~15min | ~1.4s |
Average tx/msg fee | ~$1 | ~$0.000001 |
Stack size | 32KiB (1024 of 256-bit values) | 5MiB |
Code size | 24KiB (more with code sharing) | 10MiB |
Memory size | Few KB | 404GiB (4GiB Wasm memory + 400GiB of stable memory) |
Storage cost | $18M per GiB (based on 640K gas per KB) | $5 per GiB per year |
Number of nodes | ~7K | ~500 in total, 13-40 per subnet |