In this series of DevNews articles, we’ll be publishing some behind the scenes details on Unification’s projects and repos. We hope these articles will give the developer community some insight into our progress, and encourage devs to get involved!
At Unification, we view WRKChains as entities which will “grow” from Mainchain. Since a WRKChain is a blockchain (which can be deployed by any developer, and runs independently from Mainchain), it generates block hashes, and these hashes are what need to be timestamped and sealed on Mainchain for integration into the network.
The WRKChain Root (as the name suggests!) is the root system which integrates a WRKChain, and its block hashes into the Mainchain. The WRKChain Root is effectively a smart contract that is embedded into Mainchain’s Genesis block. It is where WRKChains are registered, and their block hashes submitted. Registration and hash submission can be done automatically using our WRKOracle software, or — should a developer wish — manually or via their own custom software. The WRKOracle will be covered in a future article — in this article, we’re going to give brief introduction to the WRKChain Root smart contract and a couple of its main functions.
For anyone interested in the code, the active development can be followed here: https://github.com/unification-com/mainchain/tree/master/contracts/wrkchainroot.
The latest version will be deployed on our upcoming DSG-enabled testnet, and will supersede the version deployed on the current testnet. The functions and events covered below are correct at the time of publishing.
Each WRKChain is assigned its own
structupon registration, which holds some basic metadata such as registration date, owner, and the addresses authorised to submit hashes on behalf of the WRKChain. The
structalso allows a WRKChain to seal its Genesis hash. In addition to the metadata, the latest WRKChain block hashes are stored, and updated with each new block submission. A WRKChain’s
structcan be queried and its respective metadata retrieved.
registerWrkChainfunction is the initial entry point for every WRKChain. There is a fixed charge for registering a WRKChain, and WRKChains won’t be able to submit hashes without prior registration. Three parameters are required to be submitted with every registration:
_chainId: The unique identifier for the WRKChain within Mainchain. This is a 32 byte value, and can be derived from any string or integer value. By default, the WRKOracle attempts to use the WRKChain’s Network ID (if it’s a
gethbased WRKChain), but any arbitrary 32 byte value is valid. The
chainIdis used for all future hash submissions and event/log queries.
_authAddresses: An array of valid wallet addresses which can be used to write hashes on behalf of the WRKChain. The WRKChain Root will only accept hashes submitted by an address in this list, which can only be modified by the WRKChain owner (the wallet address that registered)
_genesisHash: A 32 byte hash of the WRKChain’s genesis block. For
gethbased WRKChains, this can currently automatically be calculated by the WRKOracle when a
genesis.jsonis supplied upon registration. Otherwise, any 32 byte hash (e.g. a sha256 hash of the entire JSON file) is valid — as long as it is reproducible.
registerWrkChainfunction validates the input, initialises the WRKChain
struct, and finally emits a
recordHeaderfunction allows WRKChains to submit block hashes at a frequency defined by the WRKChain developer/operator. They can be submitted for every WRKChain block, or once per minute/hour/day/per 100 blocks etc. Submissions have a fixed price of 1 UND per submission (a forthcoming article will outline how this fixed price is achieved). The function accepts the following parameters:
_chainId: The unique identifier for the WRKChain within Mainchain. This must match the ID supplied when registering the WRKChain.
_height: an integer value representing the block height/block number (we’re not strict on terms, so whatever floats your boat) of the current submission.
_hash: a 32 byte value representing the block header hash.
_parentHash: a 32 byte value representing the block’s parent hash. This is optional, but recommended.
_receiptRoot: an optional 32 byte hash representing the block’s Receipt Merkle root. For non-geth based WRKChains, this can be re-purposed for any arbitrary hash value the WRKChain operator wishes to seal.
_txRoot: an optional 32 byte hash representing the block’s Tx Merkle root. For non-geth based WRKChains, this can be re-purposed for any arbitrary hash value the WRKChain operator wishes to seal.
_stateRoot: an optional 32 byte hash representing the block’s State DB Merkle root. For non-geth based WRKChains, this can be re-purposed for any arbitrary hash value the WRKChain operator wishes to seal.
Once accepted, the function updates the WRKChain’s internal
struct, and emits an event.
Whilst the function has been primarily designed to accept WRKChain hashes sequentially (the current submission should have a higher block number than the previous submission, therefore representing the progression of the WRKChain’s blocks), we have taken into account that it may be desirable to submit historical data, and have recently added support for that. A WRKChain may have, for example, initially submitted daily hashes, but would like to increase the frequency to hourly. By allowing a WRKChain to submit historical data, developers can “fill in” past blocks should they wish. Historical data emits a special
RecordHeaderHistoricalevent, and sequentially submitted hashes which emit the
RecordHeaderevent will always take precedence (if, for example, the same block number is submitted twice).
Putting it together
Anyone who knows a WRKChain’s Chain ID can easily validate the WRKChain’s blocks by querying the WRKChain itself to obtain a block’s hashes, and the WRKChain Root’s event logging history for the Chain ID and corresponding block. If the WRKChain has submitted hashes for the requested block, they should match!
We have a skeleton Validation UI which can easily be extended, adapted and deployed by WRKChain developers for their users, and we will be integrating WRKChain validation into our upcoming Block Explorer.
Feel free to track progress — all of our public repos are available at https://github.com/unification-com
Unification Gitter: https://gitter.im/unification-com