Disclaimer: This is a summary of patterns we have observed during our research and should not be considered any form of technical or investment advice. Also, the given “known examples” do not imply they are the best implementations of the said pattern or any superior to any other implementation of the pattern not listed.
Store data in a separate smart contract.
A smart contract may need to be eventually upgraded to fix bugs, overcome security weaknesses, or add new functionality. In general, logic and data change at different times and with different frequencies.
Smart contract data are maintained in the ledger as part of the smart contract’s state bound to its address. When a new version of the smart contract is deployed it gets a new address. Hence, it cannot manipulate data embedded in the previous version of the contract. Even if we can build functions into the old smart contract to export/extract all its data and use that to initialise the new version, it could be a costly (on public blockchains) and nontrivial process to transfer a large set of data using a set of transactions. For example, porting data to a new version might require multiple transactions when the block gas limit on Ethereum prevents an overly complex data migration transaction.
- Coupling – Data are embedded in a smart contract. A smart contract can live forever on the blockchain if not explicitly terminated. If a smart contract is deactivated in this way, the data stored in the smart contract cannot be accessed through the smart contract functions anymore – although it can still be accessed with some effort for provenance or audit purposes.
- Upgradability – The need to upgrade the application and the smart contracts supporting the application over time is ultimately necessary for many applications.
- Cost – If a public blockchain is used, storing data on blockchain costs money. Thus, copying data from an old version of a smart contract to a new version should be avoided or minimised.
The standard practice of separating data from business logic can be applied to solve this problem. We can maintain the data and business logic in two separate smart contracts. The former contract stores and exposes basic data read and write functions with relevant access control much like a simple database. The latter contract read and write the required data by calling the data contract.
Data contract pattern
To avoid moving data during upgrades of smart contracts, the data store is isolated from the rest of the code. The data contract could try to abstract away from much of the application-specific data representations and manipulations. For example, rather than supporting specific data types, a data contract could use loosely typed flat data structures. The more generic and flexible the data structure, it could be used by all the other logic smart contracts and is unlikely to require changes in the future. One example of a generic data structure is a hash map or key-value store.
- Upgradability – By separating data from the rest of the code, the logic of the application is able to be upgraded without affecting the data contract.
- Cost – Because the data is separated from the rest of the code, there is no cost for migrating data when the application is upgraded.
- Generality – If the data can be cleanly separated and generalised, there would be an additional benefit: the generic data contract can be used by all related logic smart contracts.
- Cost – If a public blockchain is used, storing a piece of data in a generic data structure costs more money than a strictly defined data structure. For example, as mentioned earlier, a generic data structure maintains a mapping between key and value pairs, but a more strictly defined data structure can be of smaller size and not require the key to be stored. Querying the data is also less straightforward. This is the cost of a generalised solution. Also, it is costly to call one smart contract from another.
- Contract registry and this pattern can work together to further improve the upgradability of smart contracts.
- Chronobank is a blockchain project that tokenises labour and provides a market for professionals to trade their labour time with businesses. It uses a smart contract with a generic data structure as the data store used by all the other logic smart contracts.
- Colony is a platform for open organisations running on Ethereum. Similar to Chronobank, Colony has a data contract with a generic data structure.