Abstract

The Crosschain Interoperability Specification is a set of documents that define the implementation requirements for Enterprise Ethereum clients that do cross-blockchain communications. It defines the architectures, protocols and interfaces that facilitate discovery and enable scaleable crosschain communications.

This document describes the Crosschain Messaging interfaces that can be used to provide the underlying trust needed for Crosschain Function Call protocols and Crosschain Applications.

This is a working document. It is inappropriate to cite this document other than as a work in progress.

Please send any comments to the editors of this document.

Github Issues are preferred for discussion of this document.

This document is available under the terms of the Apache License 2.0.

When referencing this document, the following citation format should be used:

[eeaciw-messaging-v1.0] EEA CIW - Technical Specification Messaging Interface Draft Version 1.0. Edited by Weijia Zhang, Peter Robinson and Aiman Baharna. 28 February 2022. EEA CIW. https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec_messaging.html . Latest stage: https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec_messaging.html .

Introduction

The Crosschain Protocol Stack defines a way for enterprises to create interoperable components for crosschain communications. As shown in the diagram below, Crosschain Applications use Crosschain Function calls to allow business logic to be executed across blockchains. Components in the Crosschain Function Call layer rely on components in the Crosschain Messaging layer to deliver information from one blockchain to another such that the information can be trusted. This specification defines the interface that components in the Crosschain Function Call layer can use to verify information from other blockchains.

Crosschain Protocol Stack

Crosschain messaging ensures participants of a target blockchain can trust that information from a source blockchain did in fact come from the source blokchain. For example, crosschain messaging mechanisms could rely on transactions on one blockchain emitting events, and the events being trusted on a target blockchain.

The specification is currently targetted at Ethereum Virtual Machine (EVM) compatible blockchains. It defines interfaces using the Solidity programming language. It is expected that the interfaces should be able to be written in other programming languages to offer the same functionality on other blockchains.

Crosschain Message Relay Methods [Decribe various message crosschain methods and comparisons]

Multisig message relay is a mechanism for multiple relayers to participate in the messaging crossing from one chain to another. The message generated in the source chain is signed by independent relayers and the signatures are aggregated and sent to the target chain’s smart contract. The smart contract holds a whitelist of trusted relay nodes and verifies that the relayers that sign the message are trusted.

MPC (Multi-Party Computing) relay differs from multisig as there is only one address that is affiliated with the relayer. The relayer address does not have a private key. A set of MPC nodes each has a share of the private key and governs the signing of messaging sent from the relayer address.

Zero Knowledge Proof message relay can have Snark or Stark methods that computes the proof of message authenticity and sends it to a smart contract on the target chain for verification. The Snark (Succinct Non-Interactive Argument of Knowledge) relies on external parameters computed among the ZKP systems and therefore needs secure setup. The Stark (Scalable Transparent Argument of Knowledge) method computes the proof without external parameters and therefore does not need an initial trusted setup for the relayer.

Oracle relayer is a service provided by Oracle nodes to bridge different blockchains. Oracle smart contracts are deployed to the target chain and the messages are provided by the Oracle nodes to the smart contract on the target chain and made it available for the other smart contracts. Oracle relayer service is normally governed by trusted Oracle nodes.

Light Client: ?

Hybrid relayer method provides two channels for the messages to be passed to the target chain. This enhances security as the hackers will need to compromise both channels in order to hack the relayer system.
SetupMechanismSecurityDecentralizationEase of useComputationScalability
MultisignGovernanceAggregation of SignaturesHigh. Admin addresses safeguardingDepending on admin nodes.EasyLightHigh
MPCDKGSchnorr SignatureGroup address safeguardingDepending on validator nodes.EasyLightHigh
ZKP SnarkTrusted Ceremony etcSetup dependent proof key and verfication keyDependent on secure setupMedium. More centralized prooferDifficultHeavyLow
ZKP StarkNo trusted setup neededProof and verification independent of external parameterHigh securityMedium. More centralized prooferDifficultHeavyLow
OracleCollaborationSmart Contract callbackTrusted Oracle nodesMediumEasyMediumHigh
Light ClientWeak subjectivityHeader and state verificationHigh securityNo additional trusted actors neededMedium to DifficultMediumHigh
Hybrid methodDual ChannelCross checkingextra securityHighMediumMediumMedium

Representation of message and messaging mechannism

Crosschain Messaging is represented as one of the following.

Note that a message represented as event is stored in a transaction receipt where as one represented as state is stored in the state trie.

Event-based messaging mechanism

Solidity Interfaces

[R1]Crosschain Messaging components MUST support the Solidity interface shown below.


pragma solidity >=0.8;

interface CrosschainVerifier {
  function decodeAndVerifyEvent(uint256 _blockchainId, bytes32 _eventSig,
    bytes calldata _encodedInfo, bytes calldata _signatureOrProof)
    external view;
}

Function decodeAndVerifyEvent: Decode and verify event information. Use require to fail the transaction if any of the information is invalid. For Ethereum Virtual Machine (EVM) based source blockchains, the event information will be an Ethereum event.

Parameters:

State-based messaging mechanism

Refer to Harmonia/Data Chain implementation

Overview and interface

One can use a similar definition to support state-based messaging and verification.
Similarly, we can define function decodeAndVerifyCommitment with argument of _encodedInfo to include state data instead of event data.
For example, _encodedInfo can be a StorageRoot to represent the entire key-value state.
In decodeAndVerifyCommitment, _signatureOrProof is used for the proof of state representation of _encodedInfo.
(Note that _eventSig is not a required field in the state-based messaging.)

Verification

Signature-based verification can be applied for state-based messaging exactly as in event-based attestation.
Alternatively we can also rely on a light client verification as well.
In the latter setting, _signatureOrProof needs to contain information necessary for header verification such as aggregated validators' signatures.

When setting StorageRoot as _encodedInfo in decodeAndVerifyCommitment, we need a mechanism to verify the state using StorageRoot.
For example, one can define verifyMembership(_stateInfo, _proof) to verify the encoded state (_stateInfo) using encoded merkle proof (_proof) with _encodeInfo as StorageRoot.
Unlike events in transaction receipts, the current header includes states in the past. This also contributes to reduce crosschain header transfer.
We can find a similar specification in ICS.

Format of Signatures or Proofs

The sections below detail the format of signatures and proofs supported by this standard. [R2] Complying implementations MUST support at least one of the formats described below.

Multiple ECDSA Signatures

The _signatureOrProof value for a scenario requiring one or more ECDSA signatures has the format described in this section. It contains the abi-encoded Signatures struct as defined below.


pragma solidity >=0.8;
struct Signature {
  uint256 by;
  uint256 sigR;
  uint256 sigS;
  uint256 sigV;
  bytes   meta;
}
struct Signatures {
  uint256 typ;
  bytes proof;
  Signature[] signatures;
}

Where:

  • by: The 160-bit Ethereum address derived from the 257-bit ECDSA public key of the signer.
  • sigR: The ECDSA signature's R value.
  • sigS: The ECDSA signature's S value.
  • sigV: The ECDSA signature's V value.
  • meta: The ECDSA signature's metadata containing optional information on the platform, curve and hash function that was used to create the signature.
  • typ: The type of signature or proof. For multiple ECDSA signatures, this is always 0x0001.
  • proof: Not applicable for this scheme.
  • signatures: An array of signatures.

Note:

  • The signatures array should only contain signatures for unique by values.

Multiple EDDSA Signatures

The _signatureOrProof value for a scenario requiring one or more EDDSA signatures has the format described in this section. It contains the abi-encoded Signatures struct as defined below.


pragma solidity >=0.8;
struct Signature {
  uint256 by;
  uint256 sigR;
  uint256 sigS;
  uint256 sigV;
  bytes   meta;
}
struct Signatures {
  uint256 typ;
  bytes proof;
  Signature[] signatures;
}

Where:

  • by: The 256-bit EDDSA public key of the signer.
  • sigR: The EDDSA signature's R value.
  • sigS: The EDDSA signature's S value.
  • sigV: Not applicable for EDDSA signatures.
  • meta: The EDDSA signature's metadata containing optional information on the platform, curve and hash function that was used to create the signature.
  • typ: The type of signature or proof. For multiple EDDSA signatures, this is always 0x0003.
  • proof: Not applicable for this scheme.
  • signatures: An array of signatures.

Note:

  • The signatures array should only contain signatures for unique by values.

Ethereum Block Header Proofs

The _signatureOrProof value for a scenario, requiring a Merkle Patricia proof and one or more validator signatures, has the format described in this section. It contains the abi-encoded Signatures struct as defined below.


pragma solidity >=0.8;
struct ProofData {
  bytes witnesses;
  bytes32 root;
  bytes32 blockHash;
  bytes blockHeaderMeta;
}
struct Signature {
  uint256 by;
  uint256 sigR;
  uint256 sigS;
  uint256 sigV;
  bytes   meta;
}
struct Signatures {
  uint256 typ;
  bytes proof;
  Signature[] signatures;
}

Where:

  • witnesses: The rlp-encoded sibling nodes as witnesses.
  • root: The block receipt, transaction or state root.
  • blockHash: The block hash.
  • blockHeaderMeta: The rlp-encoded block header metadata.
  • by: The 160-bit Ethereum address of the signer.
  • sigR: The ECDSA signature's R value.
  • sigS: The ECDSA signature's S value.
  • sigV: The ECDSA signature's V value.
  • meta: The ECDSA signature's metadata containing optional information on the platform, curve and hashing function that was used to create the signature.
  • typ: The type of proof as integer code representing Ethereum block header proofs. This is always 0x0005.
  • proof: The data contained in the proof, e.g. sibling nodes, receipt root, block hash and block headers.
  • signatures: The array of Ethereum validator signatures.

Corda Proofs

The _signatureOrProof value for a scenario, requiring a multivalued Merkle proof and one or more heterogeneous participant signatures, has the format described in this section. It contains the abi-encoded Signatures struct as defined below.


pragma solidity >=0.8;
struct ProofData {
  bytes32 root;
  bytes32[] witnesses;
  uint8[] flags;
  bytes32[] values;
}
struct Signature {
  uint256 by;
  uint256 sigR;
  uint256 sigS;
  uint256 sigV;
  bytes   meta;
}
struct Signatures {
  uint256 typ;
  bytes proof;
  Signature[] signatures;
}

Where:

  • root: The Merkle tree root.
  • witnesses: The Merkle multivalued proof's witnesses.
  • flags: The Merkle multivalued proof's flags.
  • values: The multivalued Merkle proof's leaves.
  • by: The 256-bit ECDSA public key coordinate or the 256-bit ED25519 public key of the signer.
  • sigR: The ECDSA/EDDSA signature's R value.
  • sigS: The ECDSA/EDDSA signature's S value.
  • sigV: The ECDSA signature's V value.
  • meta: The ECDSA/EDDSA signature's metadata, containing optional information on the platform, curve and hashing function that was used to create the signature.
  • typ: The type of proof as integer code representing Corda signature-based proofs. This is always 0x0007.
  • proof: The data contained in the proof, e.g. witnesses, flags, values and/or just a root when used for trade verification.
  • signatures: The array of Corda participant signatures.

Alternative implementation direction for state-based messaging

Signature-based verification can be used for state-based messaging as in Event Attestation. Alternatively we can also rely on a light client verification as well. In the latter setting, _signatureOrProof needs to contain information necessary for header verification and state verification such as Merkle proof for a given state in the storage trie.


The Crosschain Messaging process is used to ensure events emitted on a source blockchain are trusted on one or more target blockchains. Cross Function Call protocols may allow for calls across multiple blockchains. In this case, multiple instantiations of the messaging protocol described below are needed to ensure all of the events emitted on various blockchains are trusted on the blockchains on which the events will be consumed.

The general flow for Crosschain Messaging processing is shown below. The processing required for specific protocols is described later in this standard.

  1. The user application does some action that causes a crosschain function call across one or more blockchains.
  2. The Crosschain Function Call contract on the source blockchain emits an event. The circumstances in which an event is emitted and the meaning of the event are Crosschain Function Call protocol dependant.
  3. Relayer nodes (also known as Attestors or Oracles) observe the blockchain for events being emitted by the Crosschain Function Call contract. The action of the Relayer node depends on the Crosschain Messaging protocol.
    • Event Relay: Some Relayers sign events and submit them in transactions to the target blockchain's Crosschain Function Call contract. The Crosschain Function Call contract then processes the event and does some action. In these cases, there is no more processing to be done.
    • Block Header Transfer: Some Relayers forward block headers or some other Merkle Root to target blockchains.
    • Event Attestation: Some Relayers sign events and allow applications to request the signed events.
  4. The Crosschain Function Call SDK code monitors for the event being emitted. The code calls the Crosschain Messaging Layer SDK code to ensure the Crosschain Messaging component knows which target blockchains the event will be needed on. The Crosschain Messaging SDK code creates or obtains verifiable event information and returns it to the Crosschain Function Call SDK code. For example, in the case of an Event Attestation approach, it could request signed event information from an Attestor. Alternatively, in the case of a Block Header Relay approach, it could create a Merkle Proof.
  5. The Crosschain Function Call SDK code submits a transaction to the target blockchain, calling the Crosschain Function Call contract on the target blockchain. It supplies the event and signature or proof information from the Crosschain Messaging Layer SDK code. The Crosschain Function Call contract calls the Crosschain Messaging contract for the source blockchain calling decodeAndVerifyEvent. This call verifies that the event information did come from the source blockchain and can be trusted.

Protocol Specific Processing

The sections below detail the protocol specific processing supported by this standard. [R2] Complying implementations MUST support at least one of the protocols described below.

Event Attestation

The processing for the Event Attestation Crosschain Messaging Protocol is:

  1. The Crosschain Function Call contract on the source blockchain emits an event. The circumstances in which an event is emitted and the meaning of the event are Crosschain Function Call protocol dependant. This event must be able to be verified on one or more target blockchains.
  2. Attestors nodes observe the blockchain for events being emitted by the Crosschain Function Call contract. Attestor nodes sign the event and store the signed event.
  3. The Crosschain Function Call SDK code observe the blockchain for events being emitted by the Crosschain Function Call contract. When an event is emitted that the SDK needs to be verifiable on another blockchain, it calls the Crosschain Messaging Layer SDK code to request it fetch signed events from Attestors and combine the signed events such that there is a single signed event object. The number of signatures that need to be combined will be equivalent to the threshold number of signatures required for the threshold signature scheme for the source blockchain.
  4. The Crosschain Function Call SDK code submits a transaction on the target blockchain, calling the Crosschain Function Call contract. It supplies the event and signature object. The Crosschain Function Call contract calls the Crosschain Messaging contract for the source blockchain calling decodeAndVerifyEvent. This call verifies that the event information did come from the source blockchain and can be trusted.

Considerations

Levels of Finality

Crosschain Messaging implementations should only sign or verify events that were created as a result of transactions that have been included in blocks that are probably final.

It may be desirable to have more than one level of finality within a system. For example, the degree of finality required for low value transaction may be different to that of a high value transaction. The low value transactions might use "fast finality" whereas the high value transactions might use "secure finality". Precise definitions of "fast finality" and "secure finality" are blockchain dependant. Additionally, for PoW blockchains, for the same blockchain, the number of blockchain confirmations that provide a certain amount of security will change over time as the network hashing power changes and the amount of hashing power that can be rented changes.

For Ethereum MainNet, fewer than eight block confirmations should be deemed "fast finality" and 12 block confirmations or more should be deemed "secure finality" (see The merits of using Ethereum MainNet as a Coordination Blockchain for Ethereum Private Sidechains.). Note that block confirmation numbers will change for Ethereum MainNet in 2022 when the Ethereum Beacon Chain is merged with the existing Ethereum MainNet Execution Chain. At this point, the historic blocks will be final at checkpoint blocks, and will have probabalistic finality between checkpoint blocks (see The Beacon Chain Ethereum 2.0 explainer you need to read first).

It is expected that different levels finality will be supported by different Crosschain Messaging components or differently configured Crosschain Messaging components.

Public Key / Address Validation

Some crosschain messaging techniques use signatures to check the validity of information from source blockchains. Typically, these techniques have registration contracts that store the public keys of authorised signers. These registration contracts may also use the public keys as a way of verifying transactions that vote for adding or removing other authorised signers.

For ECDSA signatures, registration contracts use Ethereum Addresses as a proxy for public keys when verifying signatures. Prior to an entity registering a public key, or an Ethereum Address, it needs to be certain of the validity of the address. It needs to be certain that it has the private key associated with the address. This is particularly important if the address is also used for voting. If the address is invalid or does not match the entities private key, then the entity will be unable to vote. Depending on the voting algorithm, this could make it impossible for the incorrect address to be removed and a new address added.

Consideration of ZKP as a messaging mechanism

zk-snark is a special zero knowledge proof whose mechanism has the following characteristics: Succinct: The proof is short and easily verifiable. This is best for onchain verification and the gas costs for the Ethereum and other networks are expensive and many nodes will need to verify the same statement. Non-interactive: Proof generation and verification does not require users’ manual interventions. The offchain applications can programmably generate proofs and onchain smart contracts can verify proofs. Argument of Knowledge: Meaning that the statements can be confirmed or falsified with zero knowledge proof system. The communications parties gain knowledge of the other party without the need to disclose the private information and knowledge. Define the setup process for prove nodes (Call it ZKP relayer??). The trust of ZKP nodes, the generations of prove key and verify key. The generation of smart contract that carry out the work of verifying a proof. Define a reference process of generating a proof for a crosschain message. Define a wrapper interface. This interface will take multiple inputs, a proof, a request type that represends a specific verification task (circuit). Multiple validator(Verifier) smart contracts (Can multiple circuits be supported?) Sample Verification smart contract (The verfication is hard coded already) struct VerifyingKey { Pairing.G1Point alfa1; Pairing.G2Point beta2; Pairing.G2Point gamma2; Pairing.G2Point delta2; Pairing.G1Point[] IC; } struct Proof { Pairing.G1Point A; Pairing.G2Point B; Pairing.G1Point C; } library Pairing { struct G1Point { uint X; uint Y; } // Encoding of field elements is: X[0] * z + X[1] struct G2Point { uint[2] X; uint[2] Y; } } /// @return r bool true if proof is valid function verifyProof( uint[2] memory a, uint[2][2] memory b, uint[2] memory c, uint[11] memory input ) public view returns (bool r) function verify(uint[] memory input, Proof memory proof) internal view returns (uint) (Internal function)

Typographical Conventions

Requirement Ids

A requirement is uniquely identified by a unique ID composed of its requirement level followed by a requirement number, as per convention [RequirementLevelRequirementNumber]. There are four requirement levels that are coded in requirement ids as per below convention:

Note that requirements are uniquely numbered in ascending order within each requirement level.

Example : It should be read that [R1] is an absolute requirement of the specification whereas [D1] is a recommendation and [O1] is truly optional.

Conditional Requirements

Conditional requirements are expressed as per convention [ConditionalRequirementID] < [ControllingRequirementID]. A conditional requirement becomes required if and only if its controlling requirement is implemented.

For instance [CR1] < [D3] means that if recommended requirement [D3] is implemented then it is required to also implement requirement [CR1].

Appendix

Related work

[eeaciw-crosschainspec-v1.0] EEA CIW - osschain Interoperability Specification Draft Version 1.0. Edited by Weijia Zhang, Peter Robinson and Aiman Baharna. 28 February 2022. EEA CIW. https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec.html . Latest stage: https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec.html .

[eeaciw-crosschainidentification-v1.0] EEA CIW - Crosschain Identification Specification Version 1.0. Edited by Weijia Zhang and Peter Robinson. 14 December 2020. EEA CIW. https://entethalliance.github.io/crosschain-interoperability/crosschainid.html . Latest stage: https://entethalliance.github.io/crosschain-interoperability/crosschainid.html .

[eeaciw-crosschainfunctioncall-v1.0] EEA CIW - Crosschain Function Call Interfaces Version 1.0. Edited by Weijia Zhang and Peter Robinson. 28 February 2022. EEA CIW. https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec_function.html . Latest stage: https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec_function.html .

Acknowledgments

The EEA acknowledges and thanks the many people who contributed to the development of this draft version of the specification.

Enterprise Ethereum is built on top of Ethereum, and we grateful to the entire community who develops Ethereum, for their work and their ongoing collaboration to helps us maintain as much compatibility as possible with the Ethereum ecosystem.