The Authorization pattern demonstrates how to make sure a controlling party is authorized before they take certain actions.
Authorization is an universal concept in the business world as access to most business resources is a privilege, and not given freely. For example, security trading may seem to be a plain bilateral agreement between the two trading counterparties, but this could not be further from truth. To be able to trade, the trading parties need go through a series of authorization processes and gain permission from a list of service providers such as exchanges, market data streaming services, clearing houses and security registrars etc.
The Authorization pattern shows how to model these authorization checks prior to a business transaction.
Here is an implementation of a Coin transfer without any authorization:
template Coin with owner: Party issuer: Party amount: Decimal delegates : [Party] where signatory issuer, owner observer delegates controller owner can Transfer : ContractId TransferProposal with newOwner: Party do create TransferProposal with coin=this; newOwner Lock : ContractId LockedCoin with maturity: Time; locker: Party do create LockedCoin with coin=this; maturity; locker Disclose : ContractId Coin with p : Party do create this with delegates = p :: delegates --a coin can only be archived by the issuer under the condition that the issuer is the owner of the coin. This ensures the issuer cannot archive coins at will. controller issuer can Archives : () do assert (issuer == owner)
This is may be insufficient since the issuer has no means to ensure the newOwner is an accredited company. The following changes fix this deficiency.
- Authorization contract
The below shows an authorization contract CoinOwnerAuthorization. In this example, the issuer is the only signatory so it can be easily created on the ledger. Owner is an observer on the contract to ensure they can see and use the authorization.
template CoinOwnerAuthorization with owner: Party issuer: Party where signatory issuer observer owner controller issuer can WithdrawAuthorization : () do return ()
Authorization contracts can have much more advanced business logic, but in its simplest form, CoinOwnerAuthorization serves its main purpose, which is to prove the owner is a warranted coin owner.
- TransferProposal contract
In the TransferProposal contract, the Accept choice checks that newOwner has proper authorization. A CoinOwnerAuthorization for the new owner has to be supplied and is checked by the two assert statements in the choice before a coin can be transferred.
controller newOwner can AcceptTransfer : ContractId Coin with token: ContractId CoinOwnerAuthorization do t <- fetch token assert (coin.issuer == t.issuer) assert (newOwner == t.owner) create coin with owner = newOwner