# Polyhedra Network

Bringing interoperability, scalability, and privacy to Web3 with cutting-edge zero-knowledge proof systems.

{% content-ref url="/pages/ug2Q1FUzM3hqHtWnumAB" %}
[zkBridge: Trustless Cross-chain Bridges Made Practical](/zkbridge-trustless-cross-chain-bridges-made-practical/introducing-zkbridge-protocol)
{% endcontent-ref %}

{% content-ref url="/pages/iju8TZ3DHCA5fwfXplk3" %}
[zkLightClient Overview](/zklightclient-overview/introduction)
{% endcontent-ref %}

{% content-ref url="/pages/gapv2PEVWsbzIu8dxLjp" %}
[LayerZero zkLightClient Configurations](/layerzero-zklightclient-configurations/layerzero-v1-zklightclient-oracle-addresses)
{% endcontent-ref %}

{% content-ref url="/pages/8bxKQ4TfV6TJn0GtF2ta" %}
[Proving Ethereum Full PoS Consensus in ZK](/proving-ethereum-full-pos-consensus-in-zk/overview)
{% endcontent-ref %}

{% content-ref url="/pages/aY57D5rddBaHvuqdr5hJ" %}
[Application Use Cases](/application-use-cases/nft-transfer)
{% endcontent-ref %}

{% content-ref url="/pages/q8G76MIPp5JJ0t9rYnd1" %}
[Tutorial](/tutorial/import-and-transfer-nfts)
{% endcontent-ref %}

{% content-ref url="/pages/iaOrgNFxQ26NMNq7qRyQ" %}
[Code Examples](/code-examples/deploying-cross-chain-nfts)
{% endcontent-ref %}


# Introducing zkBridge protocol

zkBridge uses zkSNARKs to enable a prover to efficiently convince the receiver chain that a certain state transition happened on the sender chain. zkBridge consists of a block header relay network and an updater contract.

The block header relay network retrieves the block headers from the sender chain, generates proofs of the validity of the block headers, and sends the headers along with the proofs to the updater contract (set up on the receiver chain).

The updater contract maintains a light-client state. It automatically adds block headers of the sender chain once the associated proofs are verified, and updates the current main chain of the sender chain.

<figure><img src="/files/JUCp6TF4vtdfwFd3xRLn" alt=""><figcaption></figcaption></figure>


# Block header relay network

We present the formal protocol of block header relay network in the following protocol:

<figure><img src="/files/2qUWK9QNJtZz9vpskEqZ" alt=""><figcaption></figcaption></figure>

Nodes in the block header relay network run RelayNextHeader with the current state of the updater contract (LCS𝑟−1,blkH𝑟−1) as input. The exact definition of LCS𝑟−1 is specific to light client protocols. The relay node then connects to full nodes in 𝒞1 and gets the block header blkH𝑟 following blkH𝑟−1. The relay node generates a ZKP 𝜋 showing the correctness of blkH𝑟 , by essentially proving that blkH𝑟 is accepted by a light client of 𝒞1 after block blkH𝑟−1. It then sends (𝜋,blkH𝑟 ) to the updater contract on 𝒞 . To avoid the wasted proof time due to collision (note that 2 when multiple relay nodes send at the same time, only one proof can be accepted), relay nodes can coordinate using standard techniques (e.g., to send in a round robin fashion).

To incentivize block header relay nodes, provers may be re-warded with fees after validating their proofs. We leave incentive design for future work. A prerequisite of any incentive scheme is installability, i.e., the guarantee that malicious nodes cannot steal others’ proofs. To this end, provers will embed their identifiers(public keys) in proofs, e.g., as input to the hash function in the Fiat-Shamir heuristic. We note that this design relies on the security of the light client verifier of the sender chain. For example, the light client verifier must reject a valid block header that may eventually become or- orphaned and not part of the sender chain.


# Updater contract

The protocol for the updater contract is specified as:

<figure><img src="/files/jd1sKhDdYDNhQ8pfqYKG" alt=""><figcaption></figcaption></figure>

The updater contract maintains the light client’s internal state including a list of block headers of 𝒞1 in headerDAG. It has two publicly exposed functions. The HeaderUpdate function can be invoked by any block header relay node, providing supposedly the next block header and a proof as input. If the proof verifies against the current light client state LCS and blkH𝑟−1, the contract will do further light-client checks, and then the state will be updated accordingly. Since the caller of this function must pay a fee, DoS attacks are naturally prevented.

The GetHeader function can be called by receiver contracts to get the block header at height 𝑡. Receiver contracts can use the obtained block header to finish application-specific verification, potentially with the help of a user or some third party.


# Proof systems of zkBridge

Libra, Virgo and deVirgo are powerful ZKP algorithms that have revolutionized cross-chain interoperability by enabling secure, private, and efficient communication between different blockchain networks. The deVirgo proof system combines Libra, Virgo with a unique distributed computing technique specifically designed for them, making zkBridge an innovative solution for seamless and secure cross-chain communication.

### Libra

The [Libra](https://eprint.iacr.org/2019/317) algorithm is an advanced zero-knowledge proof system that enables extremely fast proof generation and verifications. It allows a prover to demonstrate the validity of some statements without revealing private information. The algorithm proposed a linear time sumcheck protocol for general circuits, where it enables more than 10 times faster than prior works.&#x20;

### Virgo

The [Virgo](https://eprint.iacr.org/2019/1482) algorithm is a follow-up algorithm built upon Libra and it removes the universal trusted setup from Libra with several optimizations to enable custom gates. Virgo is especially suited for scalable and efficient ZKP applications due to its rapid proving time, succinct proof size, and low verification complexity. Notable features of the Virgo algorithm include:

1. Transparent setup: Virgo does not need any trusted setup.
2. Fast prover time: Virgo is one of the fastest ZKP systems, especially for large-scale functions.

### deVirgo

[deVirgo](https://dl.acm.org/doi/10.1145/3548606.3560652) is a groundbreaking distributed proof system derived from the Libra and Virgo algorithm, designed to significantly accelerate proof generation. By incorporating distributed sumcheck and distributed polynomial commitment, deVirgo achieves optimal parallelism. Leveraging a distributed computing network consisting of 𝑀 machines, deVirgo reduces proof generation time by a factor of 𝑀. To enable distributed polynomial commitment with on-chain verification, we used a modified version of Libra’s polynomial commitment.

<br>

Communication across the distributed computing network in deVirgo is minimized during the main computation phase, referred to as the GKR part in Virgo. Consequently, zkBridge utilizing deVirgo can be 100x faster than a single-thread Virgo prover, even though Virgo is already among the fastest ZKP protocols available. The exceptional performance of deVirgo makes it a crucial component for zkBridge's efficient cross-chain communication.

Some key features of the deVirgo algorithm include:

1. Optimal Parallelism: deVirgo employs a distributed computing network to significantly speed up proof generation by integrating distributed sumcheck and distributed polynomial commitment, deVirgo achieves the best possible parallelism.
2. Enhanced Performance: The deVirgo algorithm enables zkBridge to operate much faster compared to a single-thread Virgo prover, providing unparalleled performance.
3. Recursive Composition: deVirgo can be used in proof composition to reduce the proof size and verifier cost for on-chain verification

\ <br>


# zkBridge Research Paper

For more details of the zkBridge protocol and its proof system, please refer to the zkBridge research paper published at the ACM CCS 2022:

zkBridge: Trustless Cross-chain Bridges Made Practical

<https://dl.acm.org/doi/10.1145/3548606.3560652>


# Introduction

Integration of zero-knowledge proof technology will enhance security, performance, and cost-efficiency for cross-chain interoperability on all chains supported by LayerZero

[Polyhedra Network](https://polyhedra.network/) is building the next generation of infrastructure for Web3 interoperability by leveraging advanced zero-knowledge proof (ZKP) technology, a fundamental cryptographic primitive that guarantees the validity of data and computations while maintaining data confidentiality. The Polyhedra Network team designed and developed Polyhedra zkLightClient technology, a cutting-edge solution built on LayerZero Protocol, providing secure and efficient cross-chain infrastructures for Layer-1 and Layer-2 interoperability.


# zkLightClient on LayerZero ​

Integrating Polyhedra zkLightClient technology into LayerZero

LayerZero is an omnichain interoperability protocol that enables cross-chain messaging. Applications built using blockchain technology (decentralized applications) can use the LayerZero protocol to connect to 30+ supported blockchains seamlessly. This allows dApp users to interact securely and efficiently with assets across chains.&#x20;

\
Polyhedra's zkLightClient technology is fully integrated with LayerZero's messaging protocol, so application developers can use zero-knowledge-proof technology without barriers. Developers can easily build cross-chain applications on top of LayerZero through its extensive developer tooling and community support.

<figure><img src="/files/JhQk6WalcBfJpzK8nmzm" alt=""><figcaption></figcaption></figure>

Figure: Incorporating Polyhedra zkLightClient technology into Layerzero Network

LayerZero's ULNv2 validation library relies on two parties, the Oracle and Relayer, to transfer messages between on-chain endpoints. When LayerZero sends a message from chain A to chain B, the message is routed through the endpoint on chain A to the ULNv2 validation library. The ULNv2 library notifies the Oracle and Relayer of the message and its destination chain. The Oracle forwards the packet hash to the endpoint on chain B, and the Relayer submits the packet to be verified on-chain against the hash and delivers the message.

On-chain light clients allow for the source chain's validator set to attest to something that occurred on their chain to a destination chain. Light clients, in conjunction with other libraries, add a layer of security on top of the LayerZero messaging protocol. On-chain transaction verification has been cost-prohibitive to the tune of  $50m-$100m/day per pair-wise chain connected to Ethereum due to the presence of extensive transaction logs, which are necessary for the proof but not for the application itself. &#x20;

Polyhedra's zkLightClient technology, built on LayerZero, harnesses the compression of ZKP technology and reduces the on-chain verification tremendously with lower latency by using efficient ZKP protocols. In addition, multiple transaction verifications can be batched into a single zero-knowledge proof.&#x20;


# LayerZero V1 zkLightClient Oracle Addresses

{% hint style="info" %}
To use the Polyhedra zkLightClient with your LayerZero UserApplication, configure your app with the oracle addresses below.&#x20;
{% endhint %}

## LayerZero V1 zkLightClient Oracle Addresses (Mainnets)

* Ethereum：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* BNB Chain：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* opBNB: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC
* Polygon：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Arbitrum One：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Arbitrum Nova：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Optimism：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Base: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Mantle: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Linea: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC
* Scroll: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC
* Celo: 0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Core Dao：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Avalanche：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Fantom：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Moonbeam：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Metis：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC&#x20;
* Gnosis：0xE014fe8c4d5C23EDB7AC4011F226e869ac7Ef5CC

## LayerZero V1 zkLightClient Oracle Addresses (Testnets)

* BNB Smart Chain Testnet: 0x8718Ef0b818e23bd8A7400a4565A9bc717D2ddBf
* Ethereum Sepolia Testnet: 0x8718Ef0b818e23bd8A7400a4565A9bc717D2ddBf


# LayerZero V2 zkLightClient DVN Addresses

## LayerZero V2 zkLightClient DVN Addresses (Mainnets)

* Arbitrum Nova: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Arbitrum One: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Avalanche: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Base: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* BNB Chain: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Blast: 0x0ff4cc28826356503BB79c00637bec0eE006f237
* Celo: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Core Dao: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Cyber: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Ethereum: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Fantom: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Gnosis: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Klaytn: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Linea: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Manta Pacific: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Mantle: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Metis: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Mode: 0x8ddf05f9a5c488b4973897e278b58895bf87cb24
* Moonbeam: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* opBNB: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Optimism: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Polygon: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* Scroll: 0x8ddF05F9A5c488b4973897E278B58895bF87Cb24
* X Layer: 0x8ddf05f9a5c488b4973897e278b58895bf87cb24
* Flare: 0x8ddf05f9a5c488b4973897e278b58895bf87cb24
* Merlin: 0x8ddf05f9a5c488b4973897e278b58895bf87cb24
* Sei: 0x8ddf05f9a5c488b4973897e278b58895bf87cb24

## LayerZero V2 zkLightClient DVN Addresses (Testnets)

* BNB Smart Chain Testnet: 0x2dDf08e397541721acD82E5b8a1D0775454a180B
* Ethereum Sepolia Testnet: 0x2dDf08e397541721acD82E5b8a1D0775454a180B


# LayerZero UA Configuration

To configure zkLightClient as the oracle using LayerZero UA, your application needs to modify the default oracle of the L0 Endpoint.&#x20;

You can use the following code in `ILayerZeroEndpoint` to set the zkLightClient oracle. &#x20;

<pre class="language-solidity"><code class="lang-solidity">// Remember to call this piece of code in ILayerZeroEndpoint on both the sender chain and receiver chain to set up zkLightClient as the oracle.
/**

* @param dstChainId - the destination chain identifier

* @param zkLightClient - the ZkLightClient address

*/

function setOracle(uint16 dstChainId, address zkLightClient) external {

    uint256 TYPE_ORACLE = 6;

    ILayerZeroEndpoint(lzEndpointAddress).setConfig(

        ILayerZeroEndpoint(lzEndpointAddress).getSendVersion(address(this)),

<strong>        dstChainId,
</strong>
        TYPE_ORACLE,

        abi.encode(zkLightClient)

    );

}
</code></pre>

{% hint style="info" %}
Important: Please remember to set it in both the application of the sender chain and the application of the receiver chain to make sure the message is correctly delivered.
{% endhint %}

For more information, check out the tutorial here.

{% embed url="<https://layerzero.gitbook.io/docs/evm-guides/interfaces/evm-solidity-interfaces/ilayerzerouserapplicationconfig>" %}


# Overview

* Proving the full node of Ethereum PoS is essential for building zkBridge and any interoperability protocols on Ethereum. Sync committee is insufficient for these purposes because the crypto-economic security of the sync committee is also far from ideal. Any cross-chain infrastructures, oracles, and data processing services relying on the sync committee on Ethereum would be insecure.&#x20;
* Polyhedra Network has designed and implemented the [zkBridge](https://zkbridge.com/) system to prove the full nodes for Ethereum PoS. zkBridge uses its novel and efficient proof system, deVirgo, to prove the full nodes of Ethereum PoS. The prover time is as fast as 10 seconds for each Ethereum block, which may contain more than 32768 BLS signatures, on two AMD EPYC™ 7763 CPUs. GPU acceleration is planned in the near future, which can lower the up-front cost for better decentralization. The proof system is efficient enough to catch up with the block time of Ethereum.
* The implementation of proving Ethereum full nodes in ZK will enable fully trustless, efficient, and secure interoperability using zkBridge, to connect Ethereum ecosystems (both Ethereum L1 and L2s) with other networks. zkBridge also allows transmission of all the current and historical Ethereum data to be accessible by any other blockchain networks and any on-chain or off-chain applications. This will enable any smart contract on any blockchain to trustlessly access Ethereum data to make any kind of computing logic on top of it, and the security is all guaranteed by Ethereum PoS full nodes.


# Why Proving Ethereum full consensus?

Compared to Ethereum light clients, the approach of proving Ethereum full nodes has much higher security guarantee. Ethereum light clients operate on a distinct algorithm, and their security relies entirely on a committee known as the “sync committee.” However, the sync committee’s size is merely 512, rotating roughly daily (i.e., about 27.3 hours). The total staked assets amount to as few as 16384 ETH (calculated as 512 \* 32), a figure quite negligible (\~only 32 million USD ETH staked currently) in comparison to the daily transactions volume (more than 300 million USD) on cross-chain bridges connecting Ethereum ecosystem with other networks.

Another issue is that the sync committee does not always sign the block. (e.g., block [17239413](https://beaconcha.in/block/17239413) and block [17239414](https://beaconcha.in/block/17239414)). Statistics show that 1.6% blocks are not signed by the supermajority of the sync committee, and the issue may happen every 12 minutes on average.


# System design for proving Ethereum full consensus

In order to rectify these issues, we have decided to get rid of the sync committee and utilize the full PoS consensus of the Ethereum blockchain, which has been deployed since the merge. This will incorporate more than 20,000 signatures (a 40-fold increase from the 512 sync committee) within a single block on Ethereum mainnet.

To manage the 40-times increase in workload, we have employed our unique proof system — [deVirgo](https://dl.acm.org/doi/10.1145/3548606.3560652). This system boasts unrivaled processing capabilities, thanks to its theoretical enhancements and significant engineering advancements. deVirgo protocol theoretically eliminates the need for very large FFT or MSM, making the proof generation linear time to the number of signatures. The protocol has been deployed on zkBridge and supports parallel and distributed computation.

Experiments on the proof system with a billion-size circuit revealed a proof generation time of less than 10 seconds, which matches the pace of Ethereum block generation, without increasing the proof size or verification time.


# Efficient proof system for proving Ethereum full consensus

To enable fast prover time for proving Ethereum full nodes, we use our efficient proof system, deVirgo. deVirgo is the distributed version of the [Virgo](https://eprint.iacr.org/2019/1482.pdf) protocol, and is designed to parallelize the GKR protocol by distributing the computation across multiple machines. With deVirgo, zkBridge can support swift and flexible interoperability between different blockchains without relying on external trust assumptions. zkBridge also uses recursive proof to prove that the previously generated proof by deVirgo proves the corresponding block headers. The proof recursion reduces the on-chain verification cost to about 220K gas on any EVM-compatible blockchain network.

The key insight of deVirgo is to explore the nature that the verification of Ethereum full consensus can be represented as a data-parallel circuit. Suppose there is a data-parallel arithmetic circuit 𝐶 as well as N machines. The deVirgo proof system can divide the data-parallel circuit into N sub-circuits, with each machine computing only one sub-circuit. Verification of Ethereum full consensus is such a data-parallel circuit, and it can contain more than 30k of identical signature verification algorithms and hashes.

Central to deVirgo is a technique to distribute the sumcheck. In deVirgo, the sumcheck protocol is divided into two phases. In Phase 1, each machine processes their own sub-circuit and collectively generates one aggregated proof. The remaining work will be small enough for a single machine, which executes Phase 2 that concludes the distributed sumcheck.


# Performance evaluation

To evaluate the implementation on BLS signature aggregation, we measured the running time of the deVirgo prover and recursive verifier using two AMD EPYC™ 7763 CPUs. The result is summarized as follows:

<figure><img src="https://miro.medium.com/v2/resize:fit:1400/1*jR_E1FM5BuA2jFiy-uki1g.png" alt="" height="151" width="700"><figcaption></figcaption></figure>

We have deployed the Ethereum full-node proof system on zkBridge. zkBridge sets Ethereum as the sender chain, and other networks such as BNB Chain and Avalanche as the receiver chain. The result shows that zkBridge can generate the Ethereum full-node proofs and verify the block header on BNB Chain and other networks within 12 seconds including the delays of all the components.

We will continue optimizing the implementation. GPU acceleration is planned in the near future, which can lower the up-front cost for better decentralization. Nevertheless the current zkBridge proof system is efficient enough to catch up with the block time of Ethereum.


# Concluding remarks

Through the implementation of proving the Ethereum full nodes, Polyhedra Network enables fully trustless, efficient, and secure interoperability using zkBridge, to connect Ethereum ecosystems (both L1 and L2s) with other networks.

zkBridge is the first trustless, efficient, secure, and universal cross-chain bridge with advanced zero-knowledge proof technology.  zkBridge uses zero-knowledge proofs to efficiently convince the receiver chain that a certain state transition happened on the sender chain. With zero-knowledge proofs, zkBridge offers both strong security and a significant reduction in on-chain verification cost, without relying on external assumptions.

Furthermore,  zkBridge also allows transmission of current and historical Ethereum data, including the blockheader and transaction data, to be accessible by any other blockchain ecosystems and applications. This will enable any smart contract on any blockchain to trustlessly access Ethereum data and compute on top of the Ethereum data. All the security will be guaranteed by proving Ethereum PoS full nodes by using the efficient proof system of zkBridge.


# NFT transfer

Cross-chain NFT transfer is a powerful feature implemented in zkBridge, enabling the secure and efficient transfer of Non-Fungible Tokens (NFTs) between different blockchain networks. This functionality allows users to seamlessly move their unique digital assets from one chain to another, taking advantage of the unique features and benefits provided by various blockchain ecosystems.

To achieve cross-chain NFT transfers, zkBridge leverages its zero-knowledge proof (ZKP) technology, SendAPI and ReceiveAPI interfaces, and the block header relay network. These components work together to ensure the security and efficiency of NFT transfers across different chains.

The cross-chain NFT transfer functionality provided by zkBridge paves the way for a more interconnected and interoperable blockchain landscape, allowing users to freely move their unique digital assets across various networks and opening up new opportunities for creators, collectors, and traders.

You may try out our [NFT Transfer](https://zkbridge.com/nft) on zkBridge.

### Cross-Chain NFT Transfer Process

The following steps outline the process of transferring NFTs across chains using zkBridge:

#### 1. Prepare the NFT transfer details

On the sender chain, gather the necessary information for the NFT transfer, including the NFT's token address, token chain, token ID, recipient's address, and destination chain.

#### 2. Send the NFT transfer details using zkBridge entrypoint

Utilize the zkBridge entrypoint interface to initiate the NFT transfer. Package the NFT transfer details into a custom payload using the `abi.encode` function. Then, call the `send` function and provide the payload as an argument.

#### 3. Generate and verify zkProof

The block header relay network generates a zkProof for the sender chain's block header, which is then verified by the updater contract on the receiver chain. This process ensures the integrity and security of the cross-chain NFT transfer.

#### 4. Receive and process the NFT transfer using zkBridge receiver API

On the destination chain, use the zkBridge receiver interface to receive and process the NFT transfer. Call the `zkReceive` function, providing the source chain ID, source block hash, and zkProof as arguments. The function returns the decoded payload, allowing you to process the NFT transfer.

#### 5. Complete the NFT transfer

With the NFT transfer details obtained from the decoded payload, perform any necessary actions to finalize the transfer, such as minting or transferring the NFT on the destination chain.

By following the above cross-chain NFT transfer process with zkBridge, users can seamlessly move their unique digital assets between various blockchain networks, unlocking new opportunities and interactions within the decentralized ecosystem.


# Message passing

zkBridge enables secure and efficient cross-chain message passing between different blockchain networks, leveraging zero-knowledge proof (ZKP) technology and a set of APIs designed to facilitate interoperable communication. This document provides an overview of the cross-chain message passing process using zkBridge. You can try out our [cross-chain messaging](https://zkbridge.com/messenger) function on zkBridge.

### Overview

To pass messages across different chains, zkBridge uses the SendAPI and ReceiveAPI interfaces, along with the block header relay network. These components ensure secure and efficient cross-chain communication.

### Cross-Chain Message Passing Process

The following steps outline the process of passing messages across chains using zkBridge:

#### 1. Prepare the message payload

On the sender chain, prepare the message payload, which typically contains information such as the destination address, destination chain, and any other custom data that needs to be transmitted.

#### 2. Send the message using zkBridge entrypoint

Utilize the zkBridge entrypoint interface to send the message to the destination chain. Call the `send` function, providing the necessary parameters such as the destination chain ID, destination address, and message payload.

#### 3. Generate and verify zkProof

The block header relay network generates a zkProof for the sender chain's block header, which is then verified by the updater contract on the receiver chain. This process ensures the integrity and security of the cross-chain communication.

#### 4. Receive and process the message using zkBridge receiver API

On the destination chain, use the zkBridge receiver  interface to receive and process the message. Call the`zkReceive` function, providing the source chain ID, source block hash, and zkProof. These functions return the decoded payload, allowing you to process the cross-chain message according to your application's requirements.


# Import and transfer NFTs

Cross-chain transfer an NFT with zkBridge at https\://zkbridge.com/zknft

## 1. Import an NFT into zkBridge

### 1.1 Import with URI

parameters for zkBridge auto-import URI:

1. source chain ID（e.g., BNB Smart Chain: 56）
2. NFT contract address
3. NFT Token ID

zkBridge NFT auto-import URI format: <https://zkbridge.com/nft?contractAddress=\\[NFT> Contract Address]\&tokenId=\[Token ID]\&chainId=\[source chain ID]

For example:\
<https://zkbridge.com/zknft?contractAddress=0x87a218Ae43C136B3148A45EA1A282517794002c8&tokenId=1146910&chainId=56>[<br>](<https://zkbridge.com/nft?contractAddress=0x9e8C1e7B35f646A606644a5532C6103C647938cf\&tokenId=11\&chainId=56&#xA;>)Imports the NFT on BNB Chain whose contract address is 0x87a218Ae43C136B3148A45EA1A282517794002c8 and token ID is 1146910

**\*Note: You may only import the NFT owned by your wallet address**

### 1.2 Import using "My NFT"

1. Select the sender chain
2. Click on the "Import my NFT" button
3. Choose form the list that pops up.

<figure><img src="/files/peQT33Q6RnHJaW3UwHmV" alt=""><figcaption><p>Step 1: Import an NFT</p></figcaption></figure>

## 2. Select Receiver Blockchain

1. From the drop-down list choose the desired receiver chain.
2. Input the desired receiver address

<figure><img src="/files/YH3I7LLwdTYWj21DMF5S" alt=""><figcaption><p>Step 2: Select Receiver Blockchain</p></figcaption></figure>

## 3. Transfer

1. Approve token&#x20;
2. Trigger Cross-chain Transfer

<figure><img src="/files/TsITJdhMgD1fijZw9zK8" alt=""><figcaption><p>Step 3.1: Approve</p></figcaption></figure>

<figure><img src="/files/icFgKTT02DhG6DSD1oO1" alt=""><figcaption><p>Step 3.2: Transfer</p></figcaption></figure>

## 4. Complete

<figure><img src="/files/P59ucolqtjmzs18DmJ8v" alt=""><figcaption></figcaption></figure>


# Deploying Cross-chain NFTs

{% content-ref url="/pages/fv9tPSdo5VEo3yDivREr" %}
[Cross-chain ERC-721](/code-examples/deploying-cross-chain-nfts/cross-chain-erc-721)
{% endcontent-ref %}

{% content-ref url="/pages/6Oa1TgJ8UQhUzFcR9V8O" %}
[Cross-chain ERC-1155](/code-examples/deploying-cross-chain-nfts/cross-chain-erc-1155)
{% endcontent-ref %}


# Cross-chain ERC-721

## Deploying the ERC721 NFT Contract on the Sender Chain

Below is an example of a standard ERC721 contract. You can use the [Remix - Ethereum IDE](https://remix.ethereum.org/) to deploy this contract on an EVM-compatible blockchain.

```solidity
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SampleERC721 is ERC721 ,Ownable{
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    string private _baseTokenURI;

    constructor(string memory name, string memory symbol) ERC721(name, symbol) {}

    function mint() public {
        _safeMint(msg.sender, _tokenIds.current());
        _tokenIds.increment();
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }

    function setBaseURI(string calldata baseURI) external onlyOwner{
        _baseTokenURI = baseURI;
    }
}
```

Once the contract is deployed, you can mint an NFT and conduct a cross-chain transfer via the [zkBridge official website](https://zkbridge.com/zknft). If this is the first time you are transferring this NFT, zkBridge will automatically create a mapping contract on the receiver chain. If you wish to deploy the mapping contract for the NFT on the receiver chain by yourself, please refer to the tutorial below.

## Deploying the Mapping Contract on the Receiver Chain

For ERC721, you need to implement the `IZKBridgeErc721` interface and grant minting and burning permissions to the NFT bridge contract on the receiver chain.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

interface IZKBridgeErc721 {

    function mint(address _to, uint256 _tokenId, string memory tokenURI_) external;

    function burn(uint256 _tokenId) external;

    function chainId() external view returns (uint16);

    function nativeContract() external view returns (bytes32);
}

contract ONFT is Ownable, IZKBridgeErc721, ERC721 {

    address public bridge;

    string private _baseTokenURI;

    uint16 _chainId;

    bytes32 _nativeContract;

    modifier onlyBridge() {
        require(msg.sender == bridge, "caller is not the bridge");
        _;
    }

    constructor(
        string memory _name,
        string memory _symbol,
        uint16 chainId_,
        bytes32 nativeContract_,
        address _bridge
    ) ERC721(_name, _symbol) {
        _chainId = chainId_;
        _nativeContract = nativeContract_;
        bridge = _bridge;
    }

    function mint(
        address _to,
        uint256 _tokenId,
        string memory tokenURI_
    ) external override onlyBridge {
        _mint(_to, _tokenId);
    }

    function burn(uint256 _tokenId) external override onlyBridge {
        require(_exists(_tokenId), "Burn of nonexistent token");
        _burn(_tokenId);
    }

    function chainId() external view returns (uint16) {
        return _chainId;
    }

    function nativeContract() external view returns (bytes32) {
        return _nativeContract;
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return _baseTokenURI;
    }

    function setBaseURI(string calldata baseURI) external onlyOwner{
        _baseTokenURI = baseURI;
    }
}
```

After deploying the contract on the receiver chain, please notify us and provide both the sender chain's and receiver chain's contract addresses, so we can add the mapping relationship for you.

To get in touch, you may either:

1. Send an email to <support@zkBridge.com>
2. Reach out to our community moderators on our [Discord Server](https://discord.gg/polyhedra-network)
3. Fill out the [from for Ecosystem Partnership](https://forms.gle/Rd4k28K86xqD9dBY6)

#### Example:

* BscTestnet-NFT: [0xF6e466E4580F80Cb96bFD5D352d574a734E1f349](https://testnet.bscscan.com/address/0xF6e466E4580F80Cb96bFD5D352d574a734E1f349)
* OpbnbTestnet-NFT: [0xC8D3ffa9eFC55C43f598Af801A925Fd5F18bd7f4](https://opbnbscan.com/address/0xC8D3ffa9eFC55C43f598Af801A925Fd5F18bd7f4)
* **Send Transaction Hash:** [View on BscScan](https://testnet.bscscan.com/tx/0x8c81a19c2a4cc428a2465bf1347eb67be8fbd2067ede9952c415c87d2b7c9449)
* **Receive Transaction Hash:** [View on OpbnbScan](https://opbnbscan.com/tx/0x7044e6ea99975c14bc97e5af89194f2058e7086c799382f2aa989f46c640c2cf)

<br>


# Cross-chain ERC-1155

## Deploying the ERC1155 NFT Contract on the Sender Chain

Below is an example of a standard ERC1155 contract. You can use the [Remix - Ethereum IDE](https://remix.ethereum.org/) to deploy this contract on an EVM-compatible blockchain.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract SimpleErc1155 is ERC1155URIStorage, Ownable {

    constructor(string memory baseUri) ERC1155(baseUri) {}

    function mint(address to, uint256 tokenId, uint256 amount) external {
        _mint(to, tokenId, amount, "");
    }

    function setURI(uint256 tokenId, string calldata tokenURI) external onlyOwner {
        _setURI(tokenId, tokenURI);
    }
}
```

Once the contract is deployed, you can mint an NFT and conduct a cross-chain transfer via the [zkBridge official website](https://zkbridge.com/zknft). If this is the first time you are transferring this NFT, zkBridge will automatically create a mapping contract on the receiver chain. If you wish to deploy the mapping contract for the NFT on the receiver chain by yourself, please refer to the tutorial below.

## Deploying the Mapping Contract on the Receiver Chain

For ERC1155, you need to implement the `IZKBridgeErc1155` interface and grant minting and burning permissions to the NFT bridge contract on the receiver chain.

```solidity
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

interface IZKBridgeErc1155 {
    function zkBridgeMint(address _to, uint256 _id, uint256 _amount, string calldata _uri) external;

    function zkBridgeBurn(address _from, uint256 _id, uint256 _amount) external;
}

contract ONFT1155 is IZKBridgeErc1155, ERC1155URIStorage, Ownable {
    address public bridge;

    modifier onlyBridge() {
        require(msg.sender == bridge, "caller is not the bridge");
        _;
    }

    constructor(address _bridge, string memory _baseUri) ERC1155(_baseUri) {
        bridge = _bridge;
    }

    function zkBridgeMint(address _to, uint256 _id, uint256 _amount, string calldata _uri) external onlyBridge {
        _mint(_to, _id, _amount, "");
        // can cover uri
        // _setURI(_id, _uri);
    }

    function zkBridgeBurn(address _from, uint256 _id, uint256 _amount) external onlyBridge {
        _burn(_from, _id, _amount);
    }

    function setURI(uint256 tokenId, string calldata tokenURI) external onlyOwner {
        _setURI(tokenId, tokenURI);
    }

}
```

After deploying the contract on the receiver chain, please notify us and provide both the sender chain's and receiver chain's contract addresses, so we can add the mapping relationship for you.

To get in touch, you may either:

1. Send an email to <support@zkBridge.com>
2. Reach out to our community moderators on our [Discord Server](https://discord.gg/polyhedra-network)
3. Fill out the [from for Ecosystem Partnership](https://forms.gle/Rd4k28K86xqD9dBY6)

#### Example： <a href="#example" id="example"></a>

BscTestnet-NFT: [0x55D7680998778e2C8df1255a8b2FE57e56623126](https://testnet.bscscan.com/address/0x55D7680998778e2C8df1255a8b2FE57e56623126)

OpbnbTestnet-NFT: [0x106d3cD51e1Af35F7328aab6e8C070500f9d517d](https://opbnbscan.com/address/0x106d3cD51e1Af35F7328aab6e8C070500f9d517d)

<br>


