-
Notifications
You must be signed in to change notification settings - Fork 35
Ethereum to Ethereum Specification
This document details the interface specification for Ethereum to Ethereum interoperability.
Reference implementation: EthereumStore.sol
Block header struct to store relevant trie roots for state proofs.
struct BlockHeader {
bytes32 txRootHash;
bytes32 receiptRootHash;
}
mapping (bytes32 => bool) m_blockhashes
Purpose: Persists blockhashes against a boolean, allowing simple verification that a block is valid
mapping (bytes32 => BlockHeader) m_blockheaders
Purpose: Persists block header information required for state proofs in mapping of block hash to struct
We define a simple contract interface for submitting state as blocks, which will be called by the validation contract as it registers and validates blocks:
Function: addChain
Purpose: Adds a new chain to persist the state of, called when a new chain is registered to the validation contract.
Arguments:
* id (bytes32: unique hash identifying the peer chain on the contract, typically the genesis hash)
Must only be callable via validation contract.
Function: addBlock
Purpose: Accepts a block as an RLP-encoded blob of bytes, decodes it and constructs a `BlockHeader` instance with relevant data. Must be call by a validation contract upon successful validation of incoming block to assure correct submissions.
Arguments:
* chainId (bytes32: unique id identifying the chain that the submitted block originates from)
* blockBlob (bytes: a blob of bytes representing an RLP-encoded block header)
Must only be callable via validation contract.
Function: CheckProofs
Purpose: For a specified block hash of a specific chain, check that tx, receipt and trie root proofs pass proving that a transaction that the proof asserts to exist does exist in the block.
Arguments:
* chainId (bytes32: unique id identifying the chain that the submitted block originates from)
* blockHash (bytes32: hash of the block the transaction that the proof is for is contained in)
* proof (bytes: an array of bytes containing all relevant proof components for a specific transaction in the specified block)
Returns:
* bytes: The receipt object in the proof that represents the transaction receipt of the transaction being proven. This should contain event logs that can be used for consumption.
Can be publicly called. This provides the first of a two-part event consumption process to allow functional use-case contracts use submitted state for interoperability. The second part can be followed in the event verifiers section.
Function: CheckTxProof
Purpose: Checks whether or not a transaction exists in the trie
Arguments:
* param: id (bytes32 Unique id of chain submitting block from)
* param: blockHash (bytes32 Block hash of block being submitted)
* param: value (bytes RLP-encoded transaction object array with fields defined as: )https://github.com/ethereumjs/ethereumjs-tx/blob/0358fad36f6ebc2b8bea441f0187f0ff0d4ef2db/index.js#L50
* param: parentNodes (bytes RLP-encoded array of all relevant nodes from root node to node to prove)
* param: path (bytes Byte array of the path to the node to be proven)
Function: CheckReceiptProof
Purpose: Checks whether or not a receipt exists in the trie
Arguments:
* param: id (bytes32 Unique id of chain submitting block from)
* param: blockHash (bytes32 Block hash of block being submitted)
* param: value (bytes RLP-encoded transaction object array with fields defined as: https://github.com/ethereumjs/ethereumjs-tx/blob/0358fad36f6ebc2b8bea441f0187f0ff0d4ef2db/index.js#L50)
* param: parentNodes (bytes RLP-encoded array of all relevant nodes from root node to node to prove)
* param: path (bytes Byte array of the path to the node to be proven)
Function: CheckRootsProof
Purpose: Checks whether the tries encode to the expected block header
* param: id (bytes32 Unique id of chain submitting block from)
* param: blockHash (bytes32 Block hash of block being submitted)
* param: txNodes (bytes RLP-encoded relevant nodes of the Tx trie)
* param: receiptNodes (bytes RLP-encoded relevant nodes of the Receipt trie)
Block validation is specific to each chain's consensus algorithm. Each should provide an implementation-specific level of finality for the appropriate needs. Our reference implementation is the Clique Proof-of-Authority consensus mechanism, Clique.sol
.
Due to the wild variations each validation contract could manifest itself in depending on the data requirements for the finality level of the block submissions, the validation interface is less prescriptive and as such will only advise to the extent of the necessary functions and/or properties.
Function: register
Purpose: Registers itself to the Ion gateway to ensure that Block submission and chain registrations can be performed from this validation contract.
Must be called immediately after deployment to be usable with the Ion gateway.
Function: RegisterChain
Purpose: Provides knowledge of another chain to interoperate with by unique id. No blocks from another chain can be submitted until they have been registered. This also registers the chain with the block storage contract via the Ion gateway.
Arguments:
* chainId (bytes32: unique id identifying the chain to be registered)
* storageAddress (address: address of the block storage contract that the chain will also be registered to)
* ... (any: implementation choice of further parameters that may be required for the specific validation method. Clique takes a starting validator set as we also store the genesis block of the chain upon registration.)
Function: SubmitBlock
Purpose: Accepts a block from chainId as a blob of bytes, decodes it and checks the blob contents for metadata that can be used to check the correctness of the block. Clique checks validator signatures against the block to ensure that the submitted block was signed by a known validator. Other implementations will be different. Once validated,
Arguments:
* chainId (bytes32: unique id identifying the chain that the submitted block originates from)
* blockBlob (bytes: a blob of bytes representing an encoded block structure)
* storageAddress (address: address of the storage contract that the decoded block will be submitted for storage to)
* ... (any: implementation choice of further parameters that may be required for correct validation of a block or for storage. Clique requires submission of block signed and unsigned block headers. Other implementations will be different.)
Base verifier class to be inherited, EventVerifier.sol
.
bytes32 eventSignature
Purpose: Each event verifier is a verifier of a specific event signature. Thus each verifier must hold knowledge of the event signature through this variable.
Function: verify
Purpose: Takes an RLP-encoded receipt object with expected parameters and verifies that an event in the receipt was emitted from the expected contract with expected event parameters.
Arguments:
* contractEmittedAddress (address: address of the contract expected to have emitted the event)
* rlpReceipt (bytes: byte blob of an RLP-encoded receipt containing the relevant events)
* ... (any: list of expected event parameters.)
Must be called from the functional use-case smart contract as the second part to a two-part condition for execution. The first part is described here.
Clearmatics :D