Beyond the EVM: A Developer’s Guide to Building on the Canton Network

As Web3 matures, the demand for institutional-grade DeFi and tokenized Real World Assets (RWAs) is growing. However, public EVM chains often struggle with a fundamental trilemma when dealing with enterprise requirements: balancing composabilityprivacy, and scalability.

Enter the Canton Network. Designed as a “network of networks” and officially launched by a consortium of major financial institutions, Canton provides a fundamentally different architecture that allows for synchronized composability across different applications without sacrificing sub-transaction privacy.

If you are a smart contract developer used to Solidity or Rust, taking the leap into Canton requires a paradigm shift. In this post, we’ll explore what makes Canton unique, how to write smart contracts using Daml, and how to integrate this ecosystem with web applications and wallets.


1. The Canton Approach

In traditional public blockchains, every node processes every transaction to maintain a shared state. This inherently compromises privacy. If you want privacy (using ZKPs or private subnets), you usually lose atomic composability with the broader network. As highlighted in the Canton Network Whitepaper, overcoming this fragmentation is essential for capital markets.

Canton solves this via an architecture centered around Participant Nodes and Domains:

  • Participant Nodes: Host user wallets and execute smart contracts. They only see the data they are entitled to view.
  • Domains: Act as synchronization channels.
  • Synchronized Composability: You can execute a single atomic transaction that spans multiple domains and participant nodes, securely and privately.

For RWA platforms, this means you can have a private cap table for a tokenized treasury bill that can be atomically swapped for a stablecoin on a completely different Canton subnet—no bridging risk involved.


2. Enter Daml: The Language of Canton

Smart contracts on Canton are written in Daml (Digital Asset Markup Language). Unlike general-purpose Turing-complete languages (like Solidity), Daml is highly specialized for defining multi-party workflows, rights, and obligations.

In Daml, you don’t think in terms of global storage mappings. You think in terms of TemplatesParties, and Choices.

Here is a simplified example of how you might model a Tokenized RWA in Daml:

module TokenizedAsset where

-- An RWA Template
template RealWorldAsset
  with
    issuer : Party
    owner : Party
    assetId : Text
    amount : Decimal
  where
    -- The issuer's authorization is required to create this asset
    signatory issuer
    
    -- The owner has visibility into this contract
    observer owner

    -- A choice allowing the owner to transfer the asset
    choice Transfer : ContractId RealWorldAsset
      with
        newOwner : Party
      controller owner
      do
        create this with owner = newOwner

Key Takeaways:

  1. Signatories & Observers: Privacy is built-in. Only the issuer and the owner know this specific contract exists.
  2. Controllers: Only the owner can exercise the Transfer choice. No need for complex require(msg.sender == owner) checks—authorization is natively enforced.

3. Practical Example: Sweeping RWAs

Let’s assume we are building a “Wallet Sweep” application that consolidates RWA tokens securely. In a standard EVM environment, you’d iterate over an array of ERC-20 addresses and send multiple transactions or use a custom router contract.

On Canton, we can handle dynamic asset pooling atomically. We simply create a Daml template that consumes multiple RealWorldAsset contracts and outputs a single, consolidated contract.

template AssetSweeper
  with
    owner : Party
    issuer : Party
  where
    signatory owner

    choice SweepAssets : ContractId RealWorldAsset
      with
        assetCids : [ContractId RealWorldAsset]
      controller owner
      do
        -- Fetch all asset contracts
        assets <- mapA fetch assetCids
        
        -- Validate all assets belong to the same issuer (for simplicity)
        let totalAmount = sum (map (\a -> a.amount) assets)
        
        -- Archive the old contracts
        mapA_ (\cid -> archive cid) assetCids
        
        -- Create the new consolidated RWA
        create RealWorldAsset with
          issuer = issuer
          owner = owner
          assetId = "Swept-Portfolio"
          amount = totalAmount

Because of Canton’s synchronized execution, this SweepAssets choice executes atomically. If any single archive fails, the entire transaction reverts.


4. Frontend & Wallet Integration

Daml provides a robust set of off-ledger tooling. Instead of parsing ABI files and raw RPC calls, Canton nodes expose a Ledger API (gRPC and HTTP JSON).

To build a React frontend for our Sweep Wallet, we can leverage the @daml/react library, which provides out-of-the-box hooks for querying ledgers and submitting transactions.

import { useParty, useLedger, useStreamQueries } from '@daml/react';
import { RealWorldAsset, AssetSweeper } from '@daml.js/sweep-app/lib/Main';

export const WalletDashboard = () => {
  const party = useParty();
  const ledger = useLedger();
  
  // Real-time stream of all RWAs owned by this party
  const { contracts: assets } = useStreamQueries(RealWorldAsset);

  const handleSweep = async () => {
    // Collect the contract IDs to sweep
    const assetCids = assets.map(a => a.contractId);
    
    // Exercise the SweepAssets choice
    // Note: We need a contract ID for the AssetSweeper template to exercise this
    // Assuming sweeperCid is fetched from state
    await ledger.exercise(AssetSweeper.SweepAssets, sweeperCid, { assetCids });
    alert("Assets successfully swept!");
  };

  return (
    <div className="p-4">
      <h2>Your Assets ({assets.length})</h2>
      <button onClick={handleSweep} className="btn-primary">
        Sweep Assests
      </button>
    </div>
  );
};

Identity and Keys

In the Canton ecosystem, “Wallets” don’t just hold private keys; they interact with Participant Nodes that map public keys to Parties. Integration usually relies on OAuth2/OIDC flows combined with Ledger API tokens, abstracting a lot of the standard ECDSA signature complexities away from end users while retaining high security.


5. Conclusion & Next Steps

The Canton Network and Daml fundamentally re-imagine how enterprise and institutional tokenization should work. By baking authorization directly into the language and separating state synchronization from participant data, developers can build RWA platforms that are inherently private but globally composable.


6. References & Further Reading

  • Canton Network Official Sitecanton.network
  • Canton Network Whitepapercanton.network/whitepaper – A deep dive into the protocol’s architecture, privacy guarantees, and synchronized composability.
  • Daml Documentationdocs.daml.com – The official language guide, SDK, and tutorials for writing multi-party smart contracts.
  • Canton Network News & Announcementscanton.network/news – The latest updates, press releases, and context on the institutional backing and real-world trials of Canton.

Ready to get started?

  1. Check out the Canton Documentation.
  2. Download the Daml SDK.
  3. Spin up a local Canton node and try writing your first multi-party asset transfer.

Have you built anything on Canton? Drop a comment below or reach out on Twitter/X—I’d love to hear about your architecture!