Canton is fundamentally different from other blockchains. It's a "network of networks" where data is distributed on a need-to-know basis, not globally replicated.
Validators (formerly called participants) are the nodes that store contract data and execute smart contract code. Unlike other blockchains where nodes are ephemeral/exchangeable, Canton validators have state.
The Global Synchronizer (sync.global) is the decentralized backbone using BFT consensus. It orders, buffers, and forwards encrypted messages between validators without understanding transaction contents. Operated by Super Validators.
Contract instances defined by templates (contract types). Transactions are executed by calling choices on contracts. Smart contracts specify permissions for parties...who validates, who controls, who sees.
In Ethereum/Solana, all state and transactions are replicated to all nodes. In Canton, state and transactions are distributed ONLY to validators specified in the smart contracts. This is privacy by design at the protocol level.
Party: alice::abc123
Party: bob::def456
Party: charlie::ghi789
The complete flow from application to MainNet. Currently you need approval from existing Super Validators, Validators, or Canton Foundation.
New validators must be approved following a request from an existing Super Validator, Validator, application provider, or Foundation member. Apply via the Foundation form or contact a sponsor.
Fill out validator request form → feeds into Google Sheet → manual compliance scrubbing (banned countries, invalid emails rejected) → tokenomics committee reviews weekly
After approval, provide your fixed egress IP address. This gets whitelisted across DevNet, TestNet, and MainNet. Super Validators adopt config changes via on chain vote.
Prepare container environment (VM or Kubernetes cluster). Set up OIDC authentication (Auth0, Keycloak, etc.). Download packages from your sponsor Super Validator.
Receive onboarding secret from sponsor. Use it to connect your validator to DevNet. Get your node running and test all functionality here first.
Once stable on DevNet, request TestNet access. Sponsor submits request to Featured Applications and Validators committee. Requires formal validator approval.
Final step: MainNet whitelisting. Same process as TestNet. Min. 7 day wait period for Super Validators to adopt config and conduct on chain vote. Once live, eligible for validator rewards (Canton Coin).
Understanding how Canton's smart contract layer works: from templates to transactions
A template specifies the data structure (fields), stakeholders (signatories, observers), and choices (actions) for a contract type. Think of templates as "classes" for contracts.
template Asset
with
issuer : Party
owner : Party
symbol : Text
quantity : Decimal
where
signatory issuer, owner
observer []
choice Transfer : ContractId Asset
with
newOwner : Party
controller owner
do
create this with owner = newOwner
Contracts are instances of templates. Creating a contract requires authority from all signatories. The contract becomes "active" on the ledger and visible to all stakeholders.
-- Alice creates an asset (she's both issuer and owner)
assetCid <- submit alice do
createCmd Asset with
issuer = alice
owner = alice
symbol = "USD"
quantity = 1000.0
Choices are the ONLY way to transform contracts. Exercise a choice to update state. Choices can be consuming (archives the contract) or non consuming (keeps it active).
-- Alice transfers asset to Bob
newAssetCid <- submit alice do
exerciseCmd assetCid Transfer with
newOwner = bob
-- This archives the old contract and creates a new one
-- Bob is now the owner
ALL actions in a transaction happen atomically...all succeed or all fail. No partial execution. This enables atomic cross app composability (e.g., DvP settlement).
| Role | Purpose | Guarantees |
|---|---|---|
| Signatory | Parties whose authority is required to create or archive the contract | See all actions where contract is created/archived. Every contract must have ≥1 signatory. |
| Observer | Parties who can see the contract | Guaranteed visibility of contract and all create/archive actions. Know about each other. |
| Controller | Parties who can execute specific choices | Must authorize choice execution. Not automatically observers. |
// Example: Query active contracts via JSON Ledger API V2
const response = await fetch('http://localhost:8080/v2/state/active-contracts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'ContentType': 'application/json'
},
body: JSON.stringify({
"filter": {
"filtersForAnyParty": {
"cumulative": [{
"identifierFilter": { "WildcardFilter": { "value": {} } }
}]
}
},
"activeAtOffset": 0
})
});
// Exercise a choice via submit-and-wait
const result = await fetch('http://localhost:8080/v2/commands/submit-and-wait', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"actAs": ["Alice::1220..."],
"userId": "app1",
"commands": [{
"ExerciseCommand": {
"choice": "Transfer",
"choiceArgument": { "newOwner": "Bob::1220..." },
"contractId": "00abc...",
"templateId": "#MyApp:Asset:Asset"
}
}]
})
});
# Example: Connect to gRPC Ledger API V2 (Python)
import grpc
from com.daml.ledger.api.v2 import update_service_pb2_grpc
from com.daml.ledger.api.v2 import state_service_pb2_grpc
# Connect to validator gRPC endpoint
channel = grpc.insecure_channel('localhost:6865')
# Use Update Service to stream transactions
update_client = update_service_pb2_grpc.UpdateServiceStub(channel)
# Get active contracts using State Service
state_client = state_service_pb2_grpc.StateServiceStub(channel)
# High-performance streaming for real-time updates
# Supports Command, Update, and State services
# Example: Admin API: Party management (Python)
import grpc
from com.digitalasset.canton.admin.participant.v30 import party_service_pb2
# Connect to admin API (port from config, default often 14012)
admin_channel = grpc.insecure_channel('localhost:14012')
# Allocate a new party
party_request = party_service_pb2.AllocatePartyRequest(
party_id_hint='alice',
display_name='Alice'
)
# Note: Admin API is for validator operations & management
# Use Ledger API (JSON/gRPC) for application development
Beyond the Ledger API, Canton Network provides specialized APIs for wallets, dApps, scanning, and validator operations.
For wallet providers and exchanges integrating Canton Coin
// Install Wallet SDK
npm install @canton-network/wallet-sdk
// Or for dApp development only (smaller bundle)
npm install @canton-network/dapp-sdk
Public API for network data and Canton Coin information
# Get Canton Coin price from open mining round
curl -X POST https://scan.sv-1.global.canton.network.sync.global/api/scan/v0/open-and-issuing-mining-rounds \
-H "Content-Type: application/json" \
-d "{}"
REST API for validator node and wallet operations
# Create transfer offer (Validator API)
POST /v0/wallet/transfer-offers
Authorization: Bearer <JWT>
# Buy traffic for validator
POST /v0/wallet/buy-traffic-requests
Standard interface for dApp-to-wallet communication
// dApp requests wallet connection
const wallet = await walletGateway.connect();
// Request transaction signature
const signed = await wallet.signTransaction(tx);
| API | Purpose | Who Uses It | Key Features |
|---|---|---|---|
| Ledger API JSON/gRPC |
Core contract operations | Application developers | Query contracts, submit transactions, stream updates |
| Scan API | Public network data | Block explorers, analytics apps | Canton Coin data, ANS, validator info, mining rounds |
| Validator API | Validator & wallet operations | Validator operators, wallet apps | User management, traffic purchase, ANS operations |
| Admin API | Node management | Validator operators | Party creation, topology transactions, synchronizer connection |
| dApp API | Wallet to dApp bridge | dApp developers | Wallet connection, transaction signing, Token Standard |
Learn → Development → DevNet → Testnet → MainNet Guide
Understand about Canton: Validators with state, Parties as identity, Synchronizers for coordination, and Daml for smart contracts. Join the community.
Install Digital Asset Package Manager (DPM) for Canton 3.4+ or Daml Assistant for older versions. Set up VS Code with Daml highlighting.
# Install DPM (recommended for Canton 3.4+)
curl -sSL https://get.daml.com | sh
# Create new project
dpm new my-canton-app --template daml-intro
The Canton Network Quickstart provides a complete local development environment. Clone the repo and run your app locally before deploying to DevNet. Requires Docker with 8GB+ RAM.
# Clone the quickstart repository
git clone https://github.com/digital-asset/cn-quickstart.git
cd cn-quickstart/quickstart
# Setup your environment (choose standard/test mode, OAuth options)
make setup
# Build the application
make build
# Start Canton services + your app (first time runs setup assistant)
make start
# In separate terminals:
make canton-console # Canton admin console
make shell # Daml shell for testing
make clean all then delete Docker images/volumesQuickstart runs multiple Canton services in Docker containers. Key modules: splice onboarding (initialization), keycloak (OAuth2), pqs (query service), observability, and daml shell. Built on Splice LocalNet.
Write Daml templates for your use case. Use Vite hot reload for frontend dev (make vite dev).
Debug backend with JVM remote debugging on port 5005. Use lnav for log analysis.
make restart frontend or make start vite dev for hot reloadexport DEBUG_ENABLED=true && make restart backendApply for DevNet Whitelisting.
Write Daml templates for your use case. Implement business logic in choices.
Once stable on DevNet, request TestNet access via sponsor. Formal approval required. Finally, request MainNet whitelisting for production deployment.
| Aspect | Public Blockchains | Canton Network |
|---|---|---|
| Data Distribution | All state replicated to all nodes | Selective distribution only to parties with stake |
| Privacy | All transactions visible to all (or ZK proofs) | Privacy by design at protocol level |
| Scaling | Network-wide throughput limits | Independent scaling busy apps don't throttle others |
| Composability | Within same contract or via bridges | Atomic cross-app transactions with privacy, Managed by Global Synchronizer |
| Account Model | Address-based (account or UTXO) | Party-based identity with hosted validators |
| Smart Contracts | Solidity, Rust, Move, etc. Model | DAML Model |
| Transaction Model | State transitions on shared state | Immutable contracts with choice-based transformations |