Design Patterns of Blockchain Applications
General Patterns
Token 1
This pattern is used to distribute some fungible goods (represented by tokens) to users.
Tokens can represent a wide variety of goods, like e.g. coins, shares, outcomes or tickets, or everything else which is transferable and countable. The implications of owning a token depend on the protocol and the use case for which the token has been issued.
- Tokens can be used to track the ownership of physical properties (e.g., gold [3]), or digital ones (e.g., cryptocurrency).
- Some crowdfunding systems issue tokens in exchange for donations (e.g., the Congress contract).
- Tokens are also used to regulate user authorizations and identities.
Authorization 1
This pattern is used to restrict the execution of code according to the caller address.
- The majority of the analysed contracts check if the caller address is that of the contract owner, before performing critical opera- tions (e.g., sending ether, invoking suicide or selfdestruct).
- Corporation checks addresses to ensure that every user can vote only once per poll.
- CharlyLifeLog uses a white-list of addresses to decide who can withdraw funds.
Oracle 1
Some contracts may need to acquire data from outside the blockchain, e.g. from a website, to determine the winner of a bet.
Oracles are the interface between contracts and the outside. Technically, they are just contracts, and as such their state can be updated by sending them transactions. In practice, instead of querying an external service, a contract queries an oracle; and when the external service needs to update its data, it sends a suitable transaction to the oracle.
Randomness 1
Dealing with randomness is not a trivial task in Ethereum. Since contract execution must be deterministic, all the nodes must obtain the same value when asking for a random number: this struggles with the randomness requirements wished.
To address this issue, several contracts (e.g., Slot) query oracles that generate these values off-chain.
Others (e.g., Lottery) try to generate the numbers locally, by using values not predictable a priori, as the hash of a block not yet created. However, these techniques are not generally considered secure [18].
Poll 1
Polls allows users to vote on some question. Often this is a side feature in a more complex scenario.
Time Constraint 1
Many contracts implement time constraints, e.g. to specify when an action is permitted.
For instance, BirthdayGift allows users to collect funds, which will be redeemable only after their birthday. In notary contracts, time constraints are used to prove that a document is owned from a certain date. In game contracts, e.g. Lottery, time constraints mark the stages of the game.
Termination 1
Since the blockchain is immutable, a contract cannot be deleted when its use has come to an end. Hence, developers must forethink a way to disable it, so that it is still present but unresponsive.
This can be done manually, by inserting ad-hoc code in the contract, or automatically, calling selfdestruct or suicide.
Math 1
Contracts using this pattern encode the logic which guards the execution of some critical operations.
For instance, Badge implements a method named subtractSafely to avoid subtracting a value from a balance when there are not enough funds in an account.
Fork Check 1
The Ethereum blockchain has been forked four times, starting from July 20th, 2016, when a fork was performed to contrast the effect of the DAO attack [4].
To know whether or not the fork took place, some contracts inspect the final balance of the DAO. Other contracts use this check to detect whether they are running on the main chain or on the fork, performing different actions in the two cases.
AmIOnTheFork is a library contract that can be used to distinguish the main chain from the forked one.
Off-chaining patterns
Challenges that motivate off-chain strategies: 2
- We need to find a way to perform heavy computation, such as end-game check, off-chain on the client side, without impacting the blockchain's trustlessness property
- Computations come with a fee, thus heavy computation such as end-game checks, should be performed as rarely as possible. Thus, we should move this part of the control flow to the client side.
- We have to expect to reach scalability limits of blockchains when creating applications.
- We need to find a way to store data off the chain without giving up its manipulation-resistance
- As all on-chain data is publicly visible, techniques for trustless by privacy-preserving off-chain storage should be developed
- Off-chain computations on private data which can be verified on-chain without revealing said data would augment the set of possible use cases.
As a direct consequence of this public visibility, there is no way to perform computations on private data on-chain without revealing it.
Assume a consumer wants to prove to a provider that he has access to another provider’s API. That second provider could publicly provide the hashes of all tokes that give access to his service. Then, the consumer could simply hash his private access token and show the hash to the first provider, which could in turn verify it by comparing it to the published hashes.
However, for this to be trustless, the consumer would need to perform the hash operation on-chain and with that reveal his private token. Simply computing the hash off-chain would not proof anything to the provider.
Challenge Response Pattern
Context:
State transitions are cheap to compute, but checking whether a given state is a final state is expensive.
Solution:
Instead of checking whether a state is final or not in a smart contract on a blockchain, the same check is performed off-chain on the client side.
A client can notify a smart contract when a final state has been reached.
Other clients can prove claims wrong by providing a valid state transition.
Using this pattern, the computation never has to be performed on-chain.
Example:
The end game condition for chess is too expensive to check on-chain.
The players, however, can easily check the condition off-chain. Hence, instead of checking the end game condition in a smart contract, a player simply claims check mate.
If the claim was false, his opponent can simply prove him wrong by submitting a valid move. If the claim was true and the opponent cannot submit a valid move, the winner is paid out.
TBA
Sources: