ZenIP: 42200
Title: Cross-Chain Transfer Protocol
Owners: Alberto Garoffolo, <[email protected]>
Status: Final
Type: Consensus
Created: 2021-08-12
License: MIT
The terms below are to be interpreted as follows:
- "Mainchain"
- The original Horizen blockchain, the only one allowed to mint new ZEN ("coinbase")
- "Sidechain"
- A blockchain that supports the Zendoo Cross-Chain Transfer Protocol, i.e. it can receive ZEN from Mainchain, and send back ZEN to Mainchain
- "Forward Transfer"
- A Mainchain transaction output that sends an amount of ZEN to an address on a sidechain
- "Backward Transfer"
- A Sidechain Certificate output that sends an amount of ZEN from a sidechain to a Mainchain address
- "Certificate"
- A Mainchain transaction that includes the backward transfers of the last epoch of a sidechain and other custom data
- "Backward Transfer Request"
- A Mainchain transaction output that asks a sidechain to send, with the next certificate, an amount of ZEN to a Mainchain address
- "Ceased Sidechain"
- A sidechain that failed to publish in Mainchain a certificate for the last epoch. A ceased sidechain cannot post new certificates and is not considered active anymore
- "Ceased Sidechain Withdrawal"
- A Mainchain transaction input withdrawing ZEN coins from an address of a ceased sidechain
This document is a proposal to modify the Horizen Mainchain core consensus protocol to enable cross-chain transfers of ZEN, according to the model proposed in [1] and [2] ("Zendoo").
The publication of the "Sidechains: Decoupled Consensus Between Chains" Horizen whitepaper in October 2018, suggested the choice of supporting a system of Sidechains as a strategic direction to scale the Horizen ecosystem, both in terms of functionalities, and of overall throughput. The core idea is that new functionalities can be hosted by new, dedicated sidechains, with no impact on the Mainchain code base, and extremely limited impact in terms of added Mainchain transactions. The document triggered a vibrant discussion in the Horizen community, that confirmed a strong support for this evolution. The general consensus collected by such vision prompted for more research work, focused on the security of the model while preserving the possibility of real, full decentralization. The result of the effort was published in January 2020, in the "Zendoo: a zk-SNARK Verifiable Cross-Chain Transfer Protocol Enabling Decoupled and Decentralized Sidechains" white paper, that was enthusiastically welcomed by the Horizen community. Enabling Zendoo requires a major upgrade to the Mainchain node software, to make it able to support the transfer protocol. This document describes the changes needed to the Mainchain node software to support the Zendoo transfer protocol and the Latus construction. This upgrade would enable the expansion of the Horizen ecosystem through an unrestricted creation of applications.
On the protocol side, we need to provide a way to "create" sidechains, i.e. a way to make Mainchain aware that a new sidechain exists. Sidechain creation is done by submitting a specific Mainchain transaction output, declaring various sidechain parameters including a SNARK Verification Key needed to validate the sidechain certificates and the corresponding backward transfers. To support the full protocol and be able to allow the withdrawal from a ceased sidechain, sidechain creation must also declare a SNARK Verification Key that would allow Mainchain to validate such withdrawals. This last parameter should be optional. In addition to the creation, we need to introduce the possibility for users to transfer ZEN to sidechains and also send ZEN back to mainchain. To allow this, Mainchain transactions must be modified in order to support the above defined Forward Transfers and introduce a new kind of transaction for managing Certificates and the corresponding backward transfers. Moreover, Mainchain transactions must be modified in order to manage backward transfer requests and ceased sidechain withdrawals.
As a security measure for protecting the ZEN supply from being artificially increased by misfunctioning or malicious sidechains, Mainchain needs to keep track of the ZEN balance of each sidechain, and never accept backward transfers that would lead to a negative balance.
On the cryptographic side, we need to select a SNARK proving system that would not require a trusted setup to facilitate sidechain customizability. Moreover, considering that sidechains constructions like Latus will provide full proof of valid history for validating the backward transfers, the proving system will need to efficiently support recursive proof composition. It will be instantiated on two elliptic curves configured in a "cycle", and with all the good properties needed for security and performance. Once the system is fully designed, one of the two curves should be selected as the one for the final proof to be sent to Mainchain; that determines the verifier that needs to be made available to Mainchain to verify SNARK proofs.
As mentioned above, the support of the Zendoo protocol requires some important modification to the current zend code. In particular, we need to introduce new transactions outputs, to model the declaration of new sidechains, forward transfers, Backward Transfer requests and a new transaction type for certificates. We also need to introduce a new transaction input, to model ceased sidechain withdrawals. Finally, we need to modify the block object to include the certificates and the new transaction outputs, and increase its maximum size, to be able to accommodate a large number of certificates.
-
Introduction of a new abstract base class that is inherited from both transactions and certificates:
-
Introduction of new outputs in the Transaction class to include a list of CTxScCreationOut, CTxForwardTransferOut and CBwtRequestOut. Where:
CTxScCreationOut:
It's the output of a transaction that creates a new sidechain. It should specify a "SC creation parameters list", which includes the Verifying Keys, a "SC creation amount" and a "SC Address", that define a first forward transfer sent to an address of the new sidechain (it could be used to start the incentivisation process in sidechain).CTxForwardTransferOut:
It's the output of a transaction that sends ZEN to an address in a specified sidechain. It should specify a "SC ID", that is the ID of the sidechain that will receive the amount, a "Forward Transfer amount", i.e. the amount to be sent by this forward transfer, and a "SC Address", the sidechain address that will receive the transfer.CBwtRequestOut:
It's the output of a Mainchain transaction that contains the data needed to request the withdrawal of ZEN from a specified sidechain. The request is posted in Mainchain and processed by the sidechain, which will verify its legitimacy and, if valid, will include the corresponding backward transfer in the next certificate. For example, Latus sidechains are specifically designed to force the processing of such requests in order to allow users to withdraw even from a completely maliciously controlled sidechain. The output should specify a "SC ID" (the ID of the sidechain that holds the ZEN to be withdrawn), a "SC Fee" (the fee required by the specified sidechain to process backward transfer requests), a "MC public key hash" (the address that is receiving the backward transfer), and "SC Request Data" (sidechain specific data like a sidechain address and a signature). -
Introduction of a new input in the transaction class to include a list of CTxCeasedSidechainWithdrawalInput vcsw_ccin. Where:
CTxCeasedSidechainWithdrawalInput:
A ceased sidechain is a sidechain that failed to send a certificate for an epoch. If that happens, certificates for that sidechain cannot be published in Mainchain anymore; Mainchain considers that sidechain as "ceased". Users can create transactions with Ceased Sidechain Withdrawal inputs to recover their ZEN that were held in that ceased sidechain. As an example, the Latus construction relies on a "succinct state" (e.g. the Merkle root of sidechains UTXOs) and a "bit vector" (a data structure representing which sidechain UTXOs were spent in an epoch), both published in Mainchain together with each sidechain certificate. In such a way, the Ceased Sidechain Withdrawal corresponding circuit will be able to enforce that a certain UTXO existed at some point in the history and that was left unspent for all the subsequent epochs.
The input should specify the withdrawal amount, the "SC ID", a nullifier that must uniquely identify the withdrawn sidechain coins (e.g. the sidechain UTXO hash), the public key hash that will be used during the transaction signature (to avoid replaying the CSW in another transaction specifying a different destination address), a proof and the related inputs necessary for proving withdrawal legitimacy.
A certificate is the object that collects all the backward transfers of a specific sidechain for the last epoch:
class CScCertificate : public CTransactionBase
{
private:
const uint256 scId;
public:
const int32_t epochNumber;
const int64_t quality;
const CFieldElement endEpochCumScTxCommTreeRoot;
const CScProof scProof;
std::vector<FieldElementCertificateField> vFieldElementCertificateField;
std::vector<BitVectorCertificateField> vBitVectorCertificateField;
const CAmount forwardTransferScFee;
const CAmount MainchainBackwardTransferRequestScFee;
// memory only
const int nFirstBwtPos;
A certificate collects all the backward transfers related to withdrawals posted in a sidechain during an epoch and a proof necessary to validate them. In addition to the backward transfer list, the certificate also specifies other fields that could be enforced by the proof. Such fields can be represented in two categories: system inputs and optional custom inputs. System inputs include quality (a number representing the priority of a certificate when compared to others of the same epoch, e.g. the number of blocks processed to build that certificate), epochNumber, endEpochCumScTxCommTreeRoot (the cumulative hash of all the Sidechain transaction commitment tree roots, which is useful to enforce in sidechain the processing of all the sidechain related outputs that happened in Mainchain during that epoch and also to make sure the certificate was created for the current active chain in Mainchain), forwardTransfer and Mainchain Backward Transfer Request fees (useful to guarantee the proper reward for processing the relevant operations on the sidechain side). The optional custom inputs are sidechain specific fields that can be passed along the certificate and validated against the proof. These fields are usually designed to be used by the Ceased sidechain withdrawal procedure (eg. the above mentioned succinct state and bit vector for the Latus sidechain construction scheme).
- Block must be modified to include a vector of certificates and the meaning of the now unused ‘hashReserved’ data member must be modified to hold the ‘hashScTxsCommitment’ tree root of the block. In addition to that the maximum block size has to be increased to 4MB allocating the new additional 2MB to host only certificates.
Horizen reference cryptographic library is Ginger-lib, originally a Zexe/arkwork fork, then modified and extended to support Zendoo and Latus. In particular, Ginger-lib is offering a Marlin proving system that was modified to rely on a polynomial commitment scheme that does not require pairing ("dlog poly commitment"), and to support practical recursion with the use of Halo-inspired accumulators.
The Ginger-lib components that need to be made available to zend are:
- The two selected fields and curve (tweedledee & tweedledum)
- Poseidon Hash for the two base fields
- Merkle Tree
- dlog Marlin verifier, dlog Marlin batch verifier, with and without accumulators
[1] Sidechains: Decoupled Consensus Between Chains - https://www.horizen.io/assets/files/Horizen-Sidechains-Decoupled-Consensus-Between-Chains.pdf
[2] Zendoo: a zk-SNARK Verifiable Cross-Chain Transfer Protocol Enabling Decoupled and Decentralized Sidechains - https://www.horizen.io/assets/files/Horizen-Sidechain-Zendoo-A_zk-SNARK-Verifiable-Cross-Chain-Transfer-Protocol.pdf