Introduction

Executive Summary

Purpose

The Enterprise Ethereum Alliance (EEA) Distributed Ledger Technology Interoperability Specification aims to establish a secure and efficient framework for interoperability between different blockchain networks, focusing on enterprise applications. This specification addresses the need for various blockchain platforms to interact and transact seamlessly, especially in complex and regulated sectors like financial services and supply chain management. The specification includes architectural guidelines, protocol stack, and interfaces definitions, which are crucial for asset and data exchange across different blockchain systems, thereby enhancing their functionality and utility.

It is designed to support enterprise blockchain networks using diverse underlying technologies (for example EVM and non-EVM networks), facilitating complex multi-chain ecosystem deployments involving assets, payments, and securities transactions. The open standard prevents fragmentation across different vendor implementations. Use cases include currency exchanges between blockchains with different tokens, coordinating securities transfers with payment transfers on different chains, and atomic swaps/transfers of assets. The specification aims to support regulated enterprise use cases that require interoperability between multiple blockchains with secure guarantees.

This document is produced and maintained by the EEA Inc.'s Crosschain Interoperability Working Group. This version is a Public Exposure Draft for comment, and we welcome feedback to help improve it, and to help the Working Group understand how it has been useful in specific cases.

Intended Audience

This specification is relevant to three primary stakeholder groups:
  • Developers, Architects, Integrators: The specification provides interfaces to accelerate the development of interchangeable components for connecting heterogeneous distributed ledger technologies and blockchain networks. It is relevant to professionals seeking to implement interoperability solutions across various DLT platforms, building or looking to incorporate interoperability solutions into their solutions and applications.
  • Decision-makers and IT executives: Executives and decision-makers in regulated industries such as finance, healthcare, and supply chain will find this specification crucial for unlocking new business models and value streams through interoperable blockchain solutions. Executive in corporations that are exploring or already using DLT technologies in their operations are key beneficiaries of this specification.
  • Regulators and Standards Development Organizations (SDOs): By setting a precedent for interoperability standards, this document aids regulators and SDOs in understanding the technical complexities and potential regulatory considerations of crosschain communications. It aims to foster a collaborative environment where regulatory frameworks can evolve in tandem with technological advancements, ensuring a balanced approach to innovation and regulations.

Structure of this document

The core content of this document is (currently) structured in several sections: - : An overview of the Crosschain Interoperability stack and description of its layered architecture. - : The requirements and interfaces to enable trusted exchange of data and events between chains, ensuring integrity and validity of information passing between networks. - : The requirements and interfaces to enable execution of operations across chains, allowing crosschain applications to trigger and coordinate activities on multiple networks. - : The requirements and interfaces to implement business logic and use case-specific functionality. Definitions are generally provided the first time a term is used in the content, and then other uses of the defined term link to that definition. There are appendices that collect and revise useful information such as terms defined, or good practice recommendations.

Status of this document

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.

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-crosschainspec-v1.0] EEA CIW - Distributed Ledger Technology Interoperability Specification Draft Version 1.0. Edited by Weijia Zhang, Marelize Kriel, Anais Ofranc. 28 February 2022. EEA CIW. https://entethalliance.github.io/crosschain-interoperability/draft_crosschain_techspec.html .

Github Issues are preferred for discussion of this document.

Architecture of the Crosschain Protocol Stack

The architecture of the crosschain interoperability stack provides a standardized framework to enable secure and seamless communication across diverse blockchain and/or DLT networks. It consists of a modular, plug-and-play architecture spanning three layers - Crosschain Applications, Crosschain Function Calls, and Crosschain Messaging. The layered architecture allows for the integration of components from different vendors, serving as a robust infrastructure for an array of crosschain applications.

Crosschain Protocol Stack

Figure 1: Crosschain Protocol - Layered Architecture

Together, these three layers form a protocol stack that is robust, versatile, and capable of addressing the complex needs of modern enterprises. By adhering to the Distributed Ledger Technology Interoperability Specification defined by the Enterprise Ethereum Alliance (EEA), the protocol stack ensures that the components are not only interoperable but also scalable and secure. The EEA’s specification is a formal definition of the implementation requirements for Enterprise Ethereum clients to achieve secure and scalable crosschain communications.

The primary focus of the current specification is on Ethereum Virtual Machine (EVM) compatible blockchains, reflecting the widespread adoption and development within the Ethereum ecosystem. The specification is however implementable and compatible with other architectures, such as ZKP compatible networks and R3 Corda, where network state updates can be verified with an EEA-compliant proof. This broad-minded approach indicates a commitment to future-proofing interoperability standards and catering to an evolving digital ecosystem.

Crosschain Messaging Layer

The Crosschain Messaging layer establishes the critical information infrastructure to enable trusted interoperation between blockchain or DLT networks.

This section describes the required protocols, message formats, and mechanisms for one network to prove the integrity and authenticity of data to another. This includes specifics around event-based, state-based, and transaction-based messaging to cater to diverse crosschain information exchange requirements. Additionally, the section covers format standards for crosschain proofs and considerations for secure transmission of verified data between networks.

Crosschain message relays

This section describes various mechanisms through which messages are relayed from one blockchain to another, ensuring that the information can be trusted. This is fundamental to the operation of crosschain functions because the reliability and security of crosschain operations depend on the integrity of the message relay methods.

Understanding the strengths and weaknesses of various approaches is setting an important context for later understanding the technical requirements around event-based, state-based, and transaction-based messaging.

| Setup | Mechanism | Security | Decentralization | Ease of use | Computation | Scalability | | -------- | ------- | ------- | ------- | ------- | ------- | ------- | | Multisig | Governance | Aggregation of Signatures | High. Admin addresses safeguarding | Depending on admin nodes. | Easy | Light | High | | MPC | DKG | Schnorr Signature | Group address safeguarding | Depending on validator nodes. | Easy | Light | High | | ZKP Snark | Trusted Ceremony | Setup dependent proof key and verfication key | Dependent on secure setup | Medium. More centralized proofer | Difficult | Heavy | Low | | ZKP Stark | No trusted setup needed | Proof and verification independent of external parameter | High security | Medium. More centralized proofer | Difficult | Heavy | Low | | Oracle | Collaboration | Smart Contract callback | Trusted Oracle nodes | Medium | Easy | Medium | High | | Light Client | Weak subjectivity | Header and state verification | High security | No additional trusted actors needed | Medium to Difficult | Medium | High | | Hybrid method | Dual Channel | Cross checking | Extra security | High | Medium | Medium | Medium |

Crosschain message definition

A crosschain message can be categorized, based on the underlying network characteristic, as listed below:

Crosschain verifier interface

Message verification is done by the Crosschain Messaging layer by implementing the following interface and function.

Messaging components MUST support the Solidity ICrosschainVerifier interface described in section 3.3 Crosschain verifier interface.

        
pragma solidity >=0.8; interface ICrosschainVerifier { function decodeAndVerify( uint256 networkId, bytes calldata encodedInfo, bytes calldata encodedProof ) external view returns ( bytes memory decodedInfo ); }

The function decodeAndVerify is used to decode and verify message information originating from different networks.

Parameters:

Returns:

The function (optionally) returns decoded information for practical purposes. To improve efficiency and to avoid another smart contract call to a verifier contract implementation that performs scheme specific decoding of event data.

If the verification fails for any reason, the verification failure must prevent any state changes from occurring.

The transaction MUST fail if the verification fails.

Some example failure cases requiring a transaction revert are:

By reverting on failed verification, the system ensures data integrity and prevents invalid data from being processed.

Solidity's require() or revert() functions SHOULD be used to revert when verification fails.

Custom error codes and messages are RECOMMENDED to provide details on the failure reason.

Event-based messaging mechanism

In an EVM-based environment, event attestation is a process that utilizes the block header's receipt root to prove that events occurred within that particular block. This receipt root is a cryptographic commitment to the list of transaction receipts, which in turn contain the smart contract event logs. The event data would typically contain information to trigger an action on the destination network.

Event-based Verification

Whenever a smart contract emits an event on the source network, the associated log data is written and recorded in a transaction receipt. Receipts are hashed and represented as leaves in a Merkle tree of which root is called the receipt root. This receipt root is included in each block header and used when verifying Merkle tree membership of a specific receipt containing a specific event log. This serves as a reliable way to prove that an event has indeed been emitted on the source network.

A verifying smart contract, designed to handle crosschain messages, deployed on the destination network can use this event data to execute a corresponding operation after verifying the authenticity of the event. The verifying contract will perform a validation check, by means of a Merkle inclusion proof, to verify that the event data is part of a transaction receipt that corresponds to a receipt root in a block header that the destination network recognizes as valid. This process ensures that only verified events from the source network can trigger actions on the destination network.

Event-based Interface

For event-based implementations, the decodeAndVerify function of the Solidity ICrosschainVerifier interface described in section 3.3 Crosschain verifier interface MUST be used to decode and verify event information.

Parameters:

Returns:

Event Attestation

The process for using event attestation in the Crosschain Messaging Protocol can be summarised as follows.

  1. The Crosschain Function Call contract on the source network 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 can then be verified on one or more target networks.
  2. Relayer nodes observe the network, for events being emitted by the Crosschain Function Call contract. Once an event is observed, they can either sign the event and store it locally, or wrap the event with a block header Merkle proof before sending it to the target network for verification.
  3. The Crosschain Function Call SDK can be used to observe the network for events being emitted by the Crosschain Function Call contract. When an event is observed, it needs to be wrapped up with a proof so that it can be verified on another network. It can call the Crosschain Messaging Layer SDK to fetch signed events from relayers and combine them as a single, signed object. The number of signatures that need to be combined will depend on the threshold signature scheme for the source network. It can alternatively call the Crosschain Messaging Layer SDK to construct a block header proof around the event making use of validator signatures on the source network.
  4. The Crosschain Function Call SDK can be used to submit a transaction to the target network, calling the Crosschain Function Call contract, supplying the event and proof that it occurred. The Crosschain Function Call contract calls the Crosschain Messaging contract, for the given source network, invoking decodeAndVerify. This call verifies that the event information did come from the source network and that the event data can be trusted. Actions taken after decoding and verifying the message are Crosschain Function Call protocol dependant.

State-based messaging mechanism

For EVM-based networks, state-based messaging relies on the state root in block headers to prove the current state of the source network. By conveying state roots for particular blocks alongside expected state data encodings, the destination network can verify specific account balances, contract variables, or other on-chain data stored in the source network's state tree.

For networks using ZKPs, state updates can be attested through computationally verifiable proofs validating changes to the network state. The ZKP prover can succinctly demonstrate a particular account balance or contract storage value transitioned to an expected amount from a previously verified state, while keeping state data opaque.

State-based Verification

Block header proofs for state-based messaging can be used in exactly the same manner as in event-based messaging but unlike events in transaction receipts, the current header includes states in the past. ZKP circuit specific contracts can be used for verification of state changes for ZKP capable source networks.

State-based Interface

For state-based implementations, the decodeAndVerify function of the Solidity ICrosschainVerifier interface described in section 3.3 Crosschain verifier interface MUST be used to decode and verify storage root information.

Parameters:

Returns:

Transaction-based messaging mechanism

Transaction-based crosschain messaging relies on conveying transaction information that can be used to prove that a transaction was executed on the source network. For EVM-based networks, the transaction root in block headers provides a cryptographic hash structure encapsulating all transactions included within the block. By transmitting block headers containing a desired transaction hash alongside a Merkle proof tying the transaction hash to the overall transaction root, the destination network can reliably verify the occurrence of the specific transaction on the source network.

More broadly, any network that utilizes Merkle trees or similar structures to efficiently store and verify transactions, can be used in the crosschain messaging protocol to attest that transactions having been executed in the network.

Transaction-based Verification

Block header proofs for transaction-based messaging can be used in exactly the same manner as in event-based messaging by making use of the transaction root. Moreover, a transaction executed in a source network, that is not EVM-based, can be wrapped in the same way with a Merkle inclusion proof or a ZKP depending on the capabilities of the source network.

Transaction-based Interface

For transaction-based implementations, the decodeAndVerify function of the Solidity ICrosschainVerifier interface described in section 3.3 Crosschain verifier interface MUST be used to decode and verify event information.

Parameters:

Returns:

Transaction and State Attestation

The process for using transaction or state attestation in the Crosschain Messaging Protocol can be applied in a similar way as event attestation for EVM compatible networks. It is also possible to construct proofs to be used for transaction or state attestation from non-EVM networks. It can be summarised as follows.

  1. A transaction was executed or global state was updated on the source network. This transaction or state change can then be verified on one or more target networks.
  2. Relayer nodes observe the network, for transactions being executed or storage roots being updated. Once a transaction or state change is observed, they can either sign it and store it locally, or wrap it with a Merkle proof or ZKP before sending it to the target network for verification.
  3. The Crosschain Function Call SDK can be used to observe the network for transactions or state changes. Once observed, it needs to be wrapped up with a proof so that it can be verified on another network. It can call the Crosschain Messaging Layer SDK to fetch signed transactions or state changes from relayers and combine them as a single, signed object. The number of signatures that need to be combined will depend on the threshold signature scheme for the source network. It can alternatively also call the Crosschain Messaging Layer SDK to construct a block header proof around the transaction or state roots, making use of validator signatures on the source network, or more generally, construct a Merkle inclusion proof making use of the consensus participants of the source network. For ZKP capable networks, the Crosschain Messaging Layer SDK can also be called to produce a ZKP to computationally verify that the transaction or state change is valid.
  4. The Crosschain Function Call SDK can be used to submit a transaction to the target network, calling the Crosschain Function Call contract, supplying the transaction or state update along with a proof that it occurred. The Crosschain Function Call contract calls the Crosschain Messaging contract, for the given source network, invoking decodeAndVerify. This call verifies that the information did come from the source network and its contents can be trusted. Actions taken after decoding and verifying the message are Crosschain Function Call protocol dependant.

Formats of Proofs

The sections below detail the requirements for formats of proofs.

Transaction-based messaging components MUST support at least one of the formats of proofs:

Multiple ECDSA Signatures

For implementations supporting multiple ECDSA signatures, encodedProof MUST contain an array of ECDSA signatures with metadata, with each signature tied to a unique signer address. The encodedProof value for a scenario requiring one or more ECDSA signatures has the format described in section 3.7.1. It contains the ABI-encoded Proof struct as defined in that section.

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

Where:

Note:

Multiple EDDSA Signatures

For implementations supporting multiple EDDSA signatures, encodedProof MUST contain an array of EDDSA signatures with metadata, with each signature tied to a unique signer public key. The encodedProof value for a scenario requiring one or more EDDSA signatures has the format described in this section. It contains the ABI-encoded Proof struct as defined below.

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

Where:

Note:

Multiple Schnorr Signatures

For implementations supporting multiple Schnorr signatures, encodedProof MUST contain an array of Schnorr signatures with metadata, with each signature tied to a unique signer public key. The encodedProof value for a scenario requiring one or more Schnorr signatures has the format described in this section. It contains the ABI-encoded Proof struct as defined below.

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

Where:

Note:

Multiple BLS Signatures

For implementations supporting multiple BLS signatures, encodedProof MUST contain an array of BLS signatures with metadata, with each signature tied to a unique signer public key. The encodedProof value for a scenario requiring one or more EDDSA signatures has the format described in this section. It contains the ABI-encoded Proof struct as defined below.

      
pragma solidity >=0.8; struct Signature { uint512 by; uint256 sigR; uint256 sigS; uint256 sigV; bytes32 meta; } struct Proof { uint256 typ; bytes proofData; Signature[] signatures; }

Where:

Note:

Ethereum Block Header Proofs

For implementations supporting Ethereum block header proofs, encodedProof MUST contain Merkle Patricia proof data and an array of Ethereum validator signatures. The encodedProof 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 Proof 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; bytes32 meta; } struct Proof { uint256 typ; bytes proofData; Signature[] signatures; }

Where:

Multivalued Merkle Inclusion Proofs

For implementations supporting multivalued Merkle inclusion proofs, encodedProof MUST contain a multivalued Merkle proof and an array of heterogeneous participant signatures. The encodedProof 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 Proof 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; bytes32 meta; } struct Proof { uint256 typ; bytes proofData; Signature[] signatures; }

Where:

Zero-knowledge Proofs

For implementations supporting zero-knowledge proofs, encodedProof MUST contain the data points required for the zero-knowledge circuit being used. The encodedProof value for a scenario requiring a zero-knowledge proof has the format described in section 3.7.5. It contains the ABI-encoded Proof struct as defined in that section, including elliptic curve pairing points required for the particular zero-knowledge circuit implementation.

        
pragma solidity >=0.8; struct G1 { uint x; uint y; } struct G2 { uint[2] x; uint[2] y; } struct ProofData { G1 a; G2 b; G1 c; bytes32 meta } struct Proof { uint256 typ; bytes proofData; Signature[] signatures; }

Where:

Crosschain transaction fees

When messages are relayed across networks, certain crosschain messaging models entail associated fees. In event-based transfers validated by third-party relayers, the relayers may charge a service fee plus cover gas costs for submitting proofs on destination chains. To enable transparency, a EstimateFee function can be exposed to return expected messaging fees based on payload details. It can accept parameters like the target network ID and estimated gas limit for proof verification. Using these inputs, it can calculate total fees comprising:

The estimated fees returned can inform source network applications on complete crosschain messaging costs denominated in the payload asset. Upon successful relaying, fees are paid to the relaying contract and distributed to participating relayers minus gas expenses. For non-relayed state-based transfers where users directly submit proofs, the function can return just the target network gas estimation required for proof verification. Enabling fee transparency and estimation guides rational messaging behavior across networks.

For messaging models requiring fees, components MUST support the IEstimateGas interface.

  
pragma solidity >=0.8; interface IEstimateGas { function estimateGas( uint256 networkId, uint256 gasLimit, bytes data ) external returns (uint256 gas); }

Where:

Crosschain messaging considerations

Levels of Finality

Settlement Finality: Settlement finality refers to the point at which a transaction is considered complete and irreversible by the system. Once a transaction achieves finality, it cannot be altered, undone, or disputed. This is a critical requirement for many financial and legal applications where certainty about the status of a transaction is necessary.

Probabilistic Finality: Probabilistic finality means that transactions become increasingly irreversible as more blocks are added to the chain after the block containing the transaction. The security of a transaction is based on the probability that it would be too computationally expensive for an attacker to change the transaction, as they would need to redo the work of the block containing the transaction and all subsequent blocks. Probabilistic finality usually occurs in DLTs that use consensus mechanisms with potential forks, like proof-of-work blockchains.

In industries heavily regulated and requiring clear audit trails (like finance and law), settlement finality is often a legal requirement. Systems operating in these domains must ensure their technology can meet these regulatory standards, making probabilistic finality unsuitable.

In addition, for DLT systems that interact with traditional banking systems or other blockchains, having clear settlement finality can simplify the process of reconciling transactions across different systems, which might have different rules regarding transaction finality.

Level of finality for public permissionless networks.

Implementations must carefully navigate the unique characteristics of the DLT networks on which they operate, ensuring that messages and transactions maintain their integrity and legal standing as they traverse across different ledger systems, and must account for the potential variations in the time to finality and the economic implications of the consensus mechanisms. For instance, in the context of public permissionless networks utilizing Proof of Stake (PoS) for consensus, such as Ethereum post-Merge, the network offers a form of deterministic finality through mechanisms like the Casper Finality Gadget, where transactions are considered final and irreversible after a certain number of confirmations, backed by economic stakes of validators. This ensures that transactions cannot be reversed without significant financial penalties, providing a stronger assurance of finality compared to probabilistic finality seen in proof-of-work systems.

Level of finality for permissioned networks.

In permissioned networks with consensus mechanisms like proof of authority, immediate deterministic finality can be assumed for chain transactions with sufficient validator signatures. Byzantine fault tolerance provides strong cryptographic guarantees against block reversions. Thus, messaging finality can directly track on-chain settlement without probabilistic relaxations on permissioned environments using consensus algorithms with instant finality. Deferred effects should only be needed in cases of detected validation failures, not due to probabilistic uncertainties.

Public Key / Address Validation

Some crosschain messaging techniques rely on cryptographic signatures to attest to the validity of data sourced from external networks. Destination networks will typically maintain a list of authorized public keys alongside verification rules in their verifier contracts. These contracts will also govern permissions to add or remove trusted keys from the whitelist based on the sender's address.

For ECDSA signatures, verifier contracts may opt to rather store Ethereum addresses, serving as proxies for actual public keys, to be used later in verifying signed payloads. Before registering their signing address, participants must validate possession of the associated private key for signing messages, usually via an eth_sign or EIP-191 personal_sign operation. Failing to properly validate the signing identity can bind an invalid address incapable of producing signatures to manage the registrant’s listing. This prevents erroneously registered entities from later participating in their own removal or updating their registered signing keys. Careful key management ensures signature-based messaging can flexibly propagate while preventing spam and manipulation.

Consideration of ZKP as a messaging mechanism

ZK-SNARKs are succinct non-interactive arguments of knowledge that enable privacy-preserving proofs of computation and integrity. They are well-suited for crosschain messaging due to their short, efficiently verifiable proofs. ZKP relayers are operators that generate proofs to attest to the validity of messages without revealing the content. They undergo upfront ceremonies to securely generate proving and verification keys to facilitating subsequent proof generation workflows. The verification keys are published or configured in smart contracts on the destination network in order to verify computational proofs attesting to the authenticity of ZKP-encoded messages coming from the source network.

For crosschain messaging, ZKP relayers follow bi-directional multi-party computation protocols to jointly compute proofs of events, transactions or state transitions on source networks without leaking raw data. Source network integrity assertions are encoded into the generated proofs and transmitted to ZK verifier contracts on destination networks for verification against the published verification keys.

Destination networks can host ZK verifier contracts supporting different proof circuits for multiple types of ZKP-attested crosschain messages such as asset transfers, trade settlements, identity credentials, etc. By configuring circuit-specific verifier contracts and relayers with aligned circuits, advanced ZKP-based messaging flows between networks can be supported without compromising privacy.

Crosschain Function Call Layer

The Crosschain Function Calls layer enables execution of operations across networks, allowing crosschain applications to trigger and coordinate activities on multiple networks. This is the operational core of the stack, enabling functions to be executed remotely on another network. This capability is crucial for allowing synchronous workflows across networks in scenarios where actions on one network depend on the state or outcomes on another. It is this layer that orchestrates the remote execution of smart contract functions, ensuring that transactions are not only executed but done so in a manner that aligns with the overarching business logic defined in the applications layer.

Crosschain function call protocols can be atomic or non-atomic. Non-atomic protocols do not ensure consistency across networks. That is, a segment of the overall crosschain flow may occur on a source network, with associated updates, but the segment on the destination network may fail, and hence the updates would not be applied on the destination network. A crosschain flow segment could fail for any of the reasons described below. Non-atomic protocols must provide a mechanism to resolve failures such that consistency is restored.

Interfaces and Helper Functions

This section defines Solidity interfaces for the Crosschain Function Call layer as used by the Crosschain Application layer.

Remote Function Call Interface

The Remote Function Call interface allows applications to call functions remotely on other networks.

Non-atomic implementations MUST support the IRemoteFunctionCall Solidity interface described in this section.

      
pragma solidity >=0.8; interface IRemoteFunctionCall { function outboundCall( uint256 networkId, address contractAddress, bytes calldata functionCallData ) external payable; function inboundCall( uint256 networkId, bytes calldata encodedInfo, bytes calldata encodedProof, ) external payable; event RemoteFunctionCall( uint256 indexed networkId, address indexed contractAddress, bytes functionCallData ); }

Where IRemoteFunctionCall functions are defined as:

Where outboundCall parameters are defined as:

And inboundCall parameters are defined as:

Proofs should always be generated for a specific source and destination network as a remote function call is always intended for a particular target network. It is recommended to include the networkId in the source network encodedInfo that will be attested to on another network so that it cannot be tampered with and that the remote function call is executed in the intended network.

Task Manager Interface

When a task is dispatched from the source network, by calling outboundCall, a remote function call is triggered on the target network. This process should be made idempotent in the sense that if identical remote function call requests are made, with the same source network information and attestation proof, then it should only be executed once. There are various approaches to implementing this. One solution would be to store hashes of the given encodedInfo on the target network, to ensure it is used only once to facilitate a successful remote function call execution. Another solution would be to make use of a task identifier, generated to be unique to the source network information, and to persist the identifiers of successfully executed tasks on the target network.

Non-atomic implementations MAY choose to support the ITaskManager Solidity interface described in this section.

    
pragma solidity >=0.8; interface ITaskManager { event OutboundTaskExecuted( bytes32 indexed taskId, uint256 indexed networkId, address indexed contractAddress, bytes functionCallData ); event InboundTaskExecuted( bytes32 indexed taskId, uint256 indexed networkId, address indexed contractAddress, bytes functionCallData ); function genTaskId(bytes calldata data) external pure returns (bytes32 taskId); }

Where ITaskManager events are defined as:

Where OutboundTaskExecuted parameters are defined as:

And InboundTaskExecuted parameters are defined as:

Application Authentication Parameters

Remote function call components need to determine the source network and contract address that initiated the remote function call. Functions in contracts on destination networks use this information to determine if the caller is authorised to execute the function remotely. The authentication parameters are provided as hidden parameters, that exist outside the scope of the declared function parameters. The parameters are appended to the call data of a function by the function call component and extracted by the application layer.

Non-atomic implementations MUST append the hidden authentication parameters to the function call data before emitting the event.

The helper function encodeNonAtomicAuthParams appends authentication parameters to the function selector and parameter data, and the function decodeNonAtomicAuthParams can be used to extract the authentication parameters from the call data again.

      
pragma solidity >=0.8; abstract contract NonAtomicHiddenAuthParams { function encodeNonAtomicAuthParams( uint256 networkId, address contractAddress, bytes memory functionCallData ) internal pure returns (bytes memory) { return bytes.concat(functionCallData, abi.encodePacked(networkId, contractAddress)); } function decodeNonAtomicAuthParams() internal pure returns ( uint256 networkId, address contractAddress ) { bytes calldata allParams = msg.data; uint256 len = allParams.length; assembly { calldatacopy(0x0, sub(len, 52), 32) networkId := mload(0) calldatacopy(12, sub(len, 20), 20) contractAddress := mload(0) } } }
Application Authentication

Similar to existing single network applications, the type of application authentication is application specific. Applications that checked msg.sender in a single network context should use the decodeNonAtomicAuthParams and decodeAtomicAuthParams to check that the source network and source contract are authorised to call the function. In the case of atomic crosschain function calls, the application should also check that the root network of the call execution tree is authorised. Applications should limit which networks can be root networks to those networks that they have access to.

Crosschain Application Layer

The Crosschain Application Layer orchestrates complex interactions across multiple blockchain networks, enabling business processes to seamlessly operate over distinct ledgers. This layer empowers applications to access and manipulate data across different chains, unlocking new possibilities for crosschain interoperability and collaboration. It utilizes either atomic or non-atomic crosschain function calls to facilitate remote function executions and state updates across networks.

The Crosschain Application layer is a user-interfacing layer compromising the following components:

The Crosschain Application Layer enables a wide range of use cases, such as crosschain asset transfers, multi-chain decentralized applications (dApps), and interoperable decentralized finance (DeFi) protocols. By facilitating seamless interaction between different DLT networks, this layer plays a crucial role in driving the adoption and scalability of this technology.

Leveraging Crosschain Messaging only

For the Crosschain Application layer to leverage the Crosschain Messaging layer defined in this specification, a Crosschain Messaging framework or SDK should be deployed alongside the source and target networks and the protocols defined in this specification should be implemented.

By leveraging the Crosschain Messaging layer, the Crosschain Application layer enables secure and reliable communication between different DLT networks. This communication is essential for executing complex, multi-chain business processes and facilitating interoperability across diverse DLT ecosystems.

Leveraging Crosschain Function Call

For the Crosschain Application layer to leverage the Crosschain Functional Call layer defined in this specification, a Crosschain Function Call Framework or SDK should be deployed, alongside the source and target networks, and the protocols defined in this specification should be implemented.

By leveraging the Crosschain Function Call layer, the Crosschain Application layer can support a wide range of complex, multi-chain use cases. This includes scenarios such as crosschain asset swaps, multi-chain lending and borrowing, and interoperable decentralized exchanges.

Crosschain Protocol Flow

Figure 2: Crosschain Protocol - Flow Overview

Considerations:

Key considerations for the Crosschain Application layer include:

Adaptability for Non-EVM Ecosystems

To ensure broad applicability and compatibility with non-EVM ecosystems, implementations of this specification in environments such as WebAssembly (WASM) or other smart contract platforms MUST provide equivalent interfaces and functions that adhere to the described behavior and semantics.

While the exact syntax may differ depending on the specific programming language and runtime environment, the core functionality, input parameters, and return values SHOULD be analogous to those defined in the Solidity interfaces within this specification.

This requirement allows developers to implement the crosschain interoperability protocols consistently across diverse DLT ecosystems, promoting seamless integration and interaction between different networks. By providing clear mappings and adaptations of the interfaces to their respective environments, non-EVM platforms can ensure that the crosschain communication mechanisms operate predictably and reliably, regardless of the underlying technology stack.

Considerations

Smart Contract Upgradability

Smart contract upgradability a critical aspect to consider in the development of a DLT interoperability implementation, particularly for long-term viability and compliance with evolving regulatory standards. Smart contracts, once deployed, are immutable on the ledger. However, financial regulations and business logic may evolve, necessitating updates to the contracts. Implementing upgradable smart contracts through proxy patterns or versioning systems allows for the modification of contract logic without changing the contract's address or deployed bytecode. This approach must be carefully designed to maintain the integrity and security of the contracts, especially in a regulated financial context. Upgradability mechanisms should include strong governance processes to control updates and prevent unauthorized changes. Additionally, considering the crosschain interoperability, the upgradability strategy should ensure consistency and compatibility across different DLT platforms, enabling seamless interaction and compliance with regulatory changes over time.

Data Type Convertibility and Compatibility

In the context of this specification, certain data types such as uint256 and bytes32 are used to define interfaces and data structures. It is important to note that these data types, while distinct, are convertible and can be transformed from one to another through simple data format conversions. Smart contracts and off-chain relays are recommended to accommodate both data types to enhance interoperability and flexibility in data handling across different DLT platforms. This approach facilitates seamless crosschain communication and operations, ensuring broader compatibility and ease of implementation within diverse DTL ecosystems. Developers should ensure that their implementations incorporate mechanisms for the straightforward conversion between these data types, where necessary, to maintain the integrity and fidelity of data as it moves across network boundaries.

Appendix

Related work

[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 .

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.