Subcurrency
The following contract implements the simplest form of a cryptocurrency. The contract allows the creation of new coins (i.e. minting) as well as sending coins from one address to another.
storage {
    total_supply: int,
    balances: (b256 => int),
}
// Sends an amount of newly created coins to an address
predicate Mint(receiver: b256, amount: int) {
    constraint storage::total_supply := storage::total_supply! + amount;
    constraint storage::balances[receiver] := storage::balances[receiver]! + amount;
}
// Sends an amount of existing coins from address `from` to address `receiver`
predicate Send(from: b256, receiver: b256, amount: int) {
    let from_balance = storage::balances[from]!;
    let receiver_balance = storage::balances[receiver]!;
    constraint amount < from_balance;
    constraint storage::balances[from] := from_balance - amount;
    constraint storage::balances[receiver] := receiver_balance + amount;
}
This contract introduces some new concepts. Let's walk through it line by line.
The contract starts with a storage declaration that contains two storage variables:
- total_supplyis of type- intand represents the total supply of coins available at any given point in time.
- balancesis a map from- b256to- intand stores balances of addresses as integers.- b256is a primitive type that represents a 256-bit hash value and is used here to represent an address.
The contract also declares two predicates: Mint and Send.
The Mint predicate is fairly simple:
- It has two parameters receiver: b256andamount: int. The goal of this predicate to mintamountcoins and send them toreceiver.
- It initializes a local variable called receiver_balanceusing the storage access expressionmut storage::balances[receiver]. This syntax returns the value inbalancesthatreceivermaps to and makes it "mutable". The predicate also initializes another local variable calledtotal_supplytomut storage::total_supply.
- It enforces two constraints:
- The first constraint requires the total supply to be incremented by amount.
- The second constraint requires the balance of receiverto be incremented byamount.
 
- The first constraint requires the total supply to be incremented by 
The Send predicate has the following structure:
- It has three parameters from: b256,receiver: b256, andamount: int. The goal of this predicate to sendamountcoins from addressfromto addressreceiver.
- It initializes a local variable called from_balanceto the balance offromand another variable calledreceiver_balanceto the balance ofreceiver. It also makes both balances "mutable".
- It enforces three constraints
- The first constraint requires from_balanceto be larger thanamount. That is, the addressfrommust currently actually have enough coins to send toreceiver.
- The second constraint effectively decrements the balance of frombyamount, by requiring the next state offrom_balanceto befrom_balance - amount.
- The third constraint effectively increments the balance of receiverbyamount, by requiring the next state ofreceiver_balanceto bereceiver_balance + amount.
 
- The first constraint requires 
Note to make things simpler and easier to understand, this contract has no authentication anywhere in its code. That is, anyone can mint new coins and initiate a transfer from one arbitrary address to another. This, of course, is not the desired behavior for most cryptocurrencies. That being said, examples of authentication can be found in this Github repository.