Contract-Controlled Parties on Canton
Programmable Authority for Canton Network Applications
Abstract: Contract-Controlled Parties are a Canton Network pattern for a party that can hold assets but has no wallet, no submission path, and no way to move those assets except through a governing smart contract. It is, in other words, a party whose actions are constrained by smart contract. This post walks through the mechanism, the trust model, and what this design pattern implies for custody and composability in your Daml application.
One of the benefits of smart contract-based workflows is that the smart contract can delimit what is possible given certain preconditions about the state of the system. However, it can be difficult to reason about how other smart contracts or other party-initiated actions not covered by your smart contract might affect the security model.
For example, in an escrow contract, if a certain party is acting as the custodian of the escrow funds, what prevents that party from logging into their wallet and transferring those escrow funds? Your smart contract governing the escrow relationship might have certain conditions under which those funds can be transferred, but as simple holdings in somebody’s wallet, they can be moved out-of-band (from the perspective of your escrow business logic).
You can, of course, use locking primitives on the token being transacted, but many tokens lack such primitives or are inconsistent in the way those primitives are implemented. Some tokens, for example, include a time-based lock where the token can be locked for a certain period of time, after which it can be reclaimed. Not all smart contract workflows are amenable to such time-based locking, and solutions such as allowing any party to extend the lock at their option are prone to error.
Attacking this problem at the level of the token is difficult, but attacking it at the level of the party is far more tractable. What if the party holding the tokens was itself constrained by the smart contract? That is the key idea behind Contract-Controlled Parties on Canton.
Sealed Authority
The authority of a Contract-Controlled Party (“CCP”)[1] is sealed within a smart contract. In its sealed state, a CCP has no permitted direct submission path. Its usable authority is instead confined to the Daml state machine rooted in its governing smart contract.
One way to think about it is that there can exist a party that is a signatory on a smart contract and only on that smart contract (and contracts created through its authorized state transitions). Further, this party cannot ever submit or initiate a transaction. The only way to access the authority of such a party is to exercise a choice on the governing smart contract, thereby making use of the delegated authority of the CCP through that contract.
This is accomplished by using decentralized parties on the Canton network. A decentralized party is a party that is hosted on multiple participant nodes, with a confirmation threshold specifying how many must confirm actions involving the party. Canton has an interesting mode for such decentralized parties: they can be set to “confirmation only.” In confirmation mode, the decentralized party cannot submit transactions. It can only confirm transactions initiated by others.
For how confirmations work, in brief, consider this example: if party A is the controller of a choice on a smart contract in Daml, and party B is a signatory to the contract that hosts that choice, then when party A exercises the choice, the following happens:
- At the Daml level, B, by signing the contract, has delegated a defined use of its authority to the controllers of the contract’s choices. When A exercises such a choice, that delegated authority is available to authorize the resulting transaction consequences.
- At the Canton-level, the participant nodes hosting B validate the resulting transaction.
For decentralized parties, what this means is that a configured quorum of a decentralized party’s hosting participants must independently validate and confirm the transaction.
So, how do we use decentralized parties as Contract-Controlled Parties? Here’s how it works:
- Create a decentralized party P while its topology still permits P to directly authorize transactions.
- Have P sign exactly one bootstrap contract C₀ as a signatory.
- Reconfigure P so that it has confirming hosts but no permitted submitting host or external signing path, with a confirmation threshold requiring the desired quorum.
- From then on, P's authority survives only inside the contract state machine descending from C₀.
By combining these two Canton features, we get a topology that prevents the party from originating transactions, and a Daml authorization that is captured, preserved, and sealed in a smart contract. We now have a party that can be controlled by our smart contract business logic!
Example: Simple Escrow
Consider a simple escrow contract. Alice deposits token T with a CCP party E. After Alice deposits T, the token is held by E on the ledger. E is governed by the EscrowRules smart contract, which has the following choices:
EscrowRules(signatory E)choice Release(controller Alice): Transfer T to Bobchoice Refund(controller Bob): Transfer T to Alicechoice Resolve(controller Arbitrator): Transfer T according to decision rule
Given the smart contract and CCP structure, E is unable to transfer or otherwise use the deposited token T other than through the choices on the EscrowRules contract. E’s authority is sealed in EscrowRules and E delegates a specific, bounded use of that authority to the controllers of each of the choices.
E cannot use another application (e.g., a wallet) to transfer T to someone else. Likewise, none of the choice controllers can use E’s delegated authority for anything beyond the specific action permitted to them by the EscrowRules smart contract.
Notice that nothing about token T needs to support escrow, locking, or even know that E is contract-controlled. From the token's perspective, E is simply its holder. The restriction has been imposed on the authority of the party holding the asset rather than on the asset itself.
Aside: Solana Program Derived Addresses. Readers familiar with Solana may notice that Contract-Controlled Parties have some similarity to Program Derived Addresses (PDAs). A Solana PDA is an address for which no private signing key exists. Instead, the Solana runtime allows the program that derived the address to exercise its authority. A CCP arrives at a similar useful property by a very different route: it begins as an ordinary Canton party, establishes a governing Daml contract, and is then sealed so that its authority can be exercised only through that contract state machine. In both cases, the result is an identity that can hold assets without exposing a general-purpose wallet authority capable of moving them independently of the program.
CCP Trust Model
A CCP does not eliminate trust, it just ensures that a certain threshold of trust is met. Transaction integrity requires that no adversary control a confirmation quorum, while a second threshold requirement for topology changes means that a quorum of namespace owners must be compromised for a CCP to be “unsealed.”
Transaction Confirmation
For ordinary transaction confirmation, the decentralized party’s configured quorum provides defense against compromised or malicious participants. For a decentralized party with N participants and with a confirmation threshold of Q, transaction integrity is preserved as long as an attacker does not control Q confirming participants. Once confirmations from distinct participants cross the threshold Q, the decentralized party confirms the transaction. So, the safety condition for confirmations is: number of malicious participants < Q.
If the confirmation threshold requires unanimity (i.e., Q equals N), then a single honest participant is enough to prevent a compromised confirmation. The downside to unanimity is that a single offline participant can also prevent transaction confirmation.
Topology Changes
For a CCP, the party should belong to a decentralized namespace, which has its own governance threshold. The specific governance threshold should be set to reflect your application’s desired security model. Changes to the decentralized party topology, which includes changes to the quorum settings or the set of participants, require meeting the threshold. Again, if unanimity is required, a single honest participant can veto any attempt to “unseal” the CCP by, e.g., restoring a submission path or weakening the confirmation threshold.
Smart Contract Upgrades
Daml contracts can be changed via smart contract upgrade (“SCU”), and the CCP pattern is only valuable if it is resilient to malicious upgrade attempts. For example, we would not want a participant to have the ability to use a new DAR package that contains an ExtractAllTokens choice. SCU is powerful enough to allow the addition of new choices or to change the implementation of an existing choice.
Thankfully, the decentralized party at the core of the CCP pattern protects against this if constructed properly. Before an upgraded package can be used to exercise the CCP’s authority, it needs to be vetted by enough of the CCP’s confirming participants to satisfy the confirmation threshold. So long as fewer than a confirmation quorum are willing to vet a malicious upgrade, the malicious code cannot be used to exercise the CCP’s authority.
This is the same threshold-trust model that protects transaction confirmation: an attacker cannot simply propose an invalid transaction, nor can it redefine valid behavior through malicious contract code, without compromising a confirmation quorum.
Authority Delegation
The safety provided by CCP is only as good as the governing Daml state machine, which must actually constrain delegated authority and enforce the appropriate business logic. A CCP prevents parties from bypassing those rules, but it can’t protect against mistakes in the rules themselves.
Implications for Custody, Composability, and Program Design
CCPs have some interesting implications for how we think about custody. In a conventional custodial arrangement, the party holding an asset also has some discretionary technical ability to move it. The custodian might be contractually or legally constrained in how it exercises that authority, but the underlying technical capability is there. CCP separates these concepts: an asset can be held by a party on the ledger even though no individual actor has authority to dispose of it in a general purpose way. The CCP still holds the asset, but its authority has been committed to a particular on-ledger program/smart contract.
What this allows is a kind of custody minimization. Instead of trusting an application operator or an escrow agent or some other intermediary to possess broad authority while exercising it only according to a set of agreed rules, the CCP can make those rules part of the authority model. This doesn’t, of course, answer the separate legal or regulatory question of who is considered a custodian in any particular financial context.[2] But it does change the technical facts underlying that analysis, because now no single operator needs to possess discretionary control over the assets.
CCPs also provide a useful form of asset composability. In the escrow example, above, the token T does not need to implement escrow, understand our EscrowRules contract, or expose any particular locking primitive. It only needs to be capable of being held by a party (in our case, party E). The application-specific restrictions are imposed on E’s authority rather than on the token T. The same CCP can therefore potentially govern many different assets without requiring each issuer to anticipate or implement the business logic of the application that will eventually use them.
More generally, CCPs point toward a different way of approaching smart contract design on Canton. When an application needs to impose restrictions over assets, it might be simpler to ask “who should be allowed to act as the party holding those assets?” rather than “what restrictions must every asset implement?” By making the party itself programmable, the application can define a common authority boundary around otherwise heterogeneous assets.
Escrow is only one example. The same pattern can be useful for protocol treasuries, liquidity-pool vaults, collateral accounts, settlement accounts, jointly governed reserves, or any other application in which assets must be held at a stable Canton identity while their disposition is governed by a smart contract. In each case, the CCP acts as a programmatic asset holder whose authority can only be exercised by predefined smart contract paths that are gated by quorum.
[1] We’ve heard that this acronym is already taken, but we’re going to use it anyway.
[2] Nothing in this article is legal or financial advice.