An Introduction to Webb’s Systems 1: v0.1 Privacy-Preserving Cross-Chain Asset Transfers
Welcome to Part 1 of a three-part introduction series to Webb’s systems. In this article, we'll explore Webb’s system for cross-chain asset transfers.
The Webb UTXO System:
A Privacy-Preserving Cross-Chain Asset Transfer System
Welcome to Part 1 of a three-part introduction series to Webb’s systems. In this article, we'll explore Webb’s system for cross-chain asset transfers. Part 2 will delve into Webb’s cross-chain identity systems, and Part 3 will combine the knowledge from the previous parts to describe an identity-based cross-chain asset transfer system.
To understand Webb’s UTXO system, you should be familiar with Merkle trees and the UTXO model. A 'transaction' refers to depositing into, withdrawing out of, and transferring funds within the Webb system. The UTXO model is employed to track user balances. The invariant that any transaction must maintain is:
sum of input UTXO amounts + public amount = sum of output UTXO amounts
The public amount
is positive when a deposit occurs and negative when a withdrawal occurs. When the public amount
is zero, the total funds locked in the Webb system remain unchanged, although the funds may change owners.
Unpacking the Webb UTXO Data Structure
A UTXO typically consists of a pair (public key, amount)
, indicating that the person possessing the private key
corresponding to the public key
has the right to spend the specified number of coins amount
. In the Webb system, a destination chain Id
is added to the UTXO data structure, representing the chain Id
where the UTXO will be spent. For added security, a randomly generated secret blinding
value is included in the UTXO. The Webb UTXO looks like this:
webb_utxo = {public key, amount, destination chain Id, blinding}
Privacy-Preserving Cross-Chain Asset Transfers via Sets of Linked Merkle Trees and Zero-Knowledge Proofs
Webb’s systems function through sets of linked Merkle trees. A set of linked Merkle trees is a collection of Merkle trees, each maintaining a list of the Merkle roots of the other trees in the set.
Suppose we have a set of three linked Merkle trees, each located on a separate blockchain (say blockchains A, B, C, and D). We will demonstrate how to use these linked Merkle trees to perform privacy-preserving cross-chain asset transfers. If a user wants to transfer assets from chain A to chain B, they will:
- Conduct a deposit transaction on chain A. This locks the deposited funds in chain A and creates a corresponding
webb_utxo
. To preserve privacy, only a commitmentPoseidon(webb_utxo)
is publicly revealed, wherePoseidon
is a zero-knowledge friendly hash function. The commitment is added to the linked Merkle tree on chain A. - The user then proves in zero-knowledge on chain B that they know a
webb_utxo
and a Merkle proof, such thatPoseidon(webb_utxo)
is a commitment in one of a set of linked Merkle trees. Upon verification of this proof, chain B releases funds to the user and generates the correspondingwebb_utxos
. Importantly, the zero-knowledge proof does NOT reveal: - The
webb_utxo
. - The exact Merkle tree/root/path corresponding to the commitment.
- Whether the deposit occurred on chain A, B, C, or D.
Preventing Double Spending via Nullifiers
What prevents a user from spending the same webb_utxo
twice? The answer is nullifiers. Each UTXO has a nullifier
associated with it, given by:
Poseidon(commitment, merklePath, Poseidon(privKey, commitment, merklePath))
When a webb_utxo
is spent, the user has to provide this nullifier, which is then publicly stored on-chain. The chain where the withdrawal is occurring also verifies in zero-knowledge that the nullifier truly is what it’s supposed to be and not some bogus value. If a user tries to spend the same webb_utxo
, they will have to submit the same nullifier
. Since the chain publicly stores used nullifiers, it will easily detect that the user is trying to double spend.
Relaying Merkle Root Information and Decentralizing Trust
One question the curious reader may be wondering about is how Merkle trees on different blockchains maintain Merkle root information about each other. Currently, this is done via a system of relayers that listen for Merkle root updates and relay them across chains. However, the major flaw in the current system is that malicious relayers can submit and approve invalid Merkle roots. This is a problem because it may allow people to withdraw money that they never deposited.
To decentralize trust away from the relayers, a light client system is currently being implemented for validating block headers and verifying storage/account/receipt proofs about updated Merkle roots against these block headers. This is more trustless than the previous system and follows from the security of light clients.
Building Applications on Top of Webb’s Cross-Chain Asset Transfer System
Webb’s work is open source and permissionless, so anyone can build on top of it. Developers can create powerful applications that enhance privacy and security by building on top of Webb's cross-chain asset transfer system. Relevant links for their repos are:
- Solidity Protocol for Cross-Chain Asset Transfers: https://github.com/webb-tools/protocol-solidity
- Substrate Protocol for Cross-Chain Asset Transfers: https://github.com/webb-tools/protocol-substrate
- Relayer: https://github.com/webb-tools/relayer
Conclusion
In this article, we introduced Webb's system for privacy-preserving cross-chain asset transfers. This system uses sets of linked Merkle trees and zero-knowledge proofs to enable users to conduct cross-chain asset transfers while preserving their privacy. We also discussed how nullifiers prevent double spending and how the system relays Merkle root information across blockchains. Webb's vision is to enable trustless, decentralized, and private cross-chain communication. In the next part of this series, we will discuss Webb's system for cross-chain identity systems, and in part 3, we will combine parts 1 and 2 to describe an identity-based cross-chain asset transfer system.