Skip to content

Poly-pay/zkVerify-PrivateTransfer-Noir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Private ETH Transfer using zkVerify

A privacy-preserving Ethereum transfer system that uses zero-knowledge proofs to enable anonymous ETH transfers through a pool-based mechanism.

How It Works

Overview

This system allows users to transfer ETH privately by breaking the on-chain link between sender and recipient through a pool-based approach combined with zero-knowledge proofs.

High Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    1. Generate ZK Proof     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     β”‚ ──────────────────────────▢ β”‚                     β”‚
β”‚   User Application  β”‚                             β”‚     zkVerify        β”‚
β”‚   (Privacy Client)  β”‚                             β”‚   (Proof Verifier)  β”‚
β”‚                     β”‚ ◀────────── 4. Get ──────── β”‚                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    Aggregation ID           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚                                                   β”‚
           β”‚                                                   β”‚
           β”‚ 5. Call via Relayer Wallet                        β”‚ 2. Aggregate &
           β–Ό                                                   β”‚    Store Proofs
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                        β”‚
β”‚                     β”‚                                        β–Ό
β”‚   Relayer Wallet    β”‚                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  (Anonymous Proxy)  β”‚                              β”‚                     β”‚
β”‚                     β”‚                              β”‚   zkVerify Chain    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β”‚  (Proof Registry)   β”‚
           β”‚                                         β”‚                     β”‚
           β”‚ 6. Submit Transaction                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β–Ό                                                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    8. Query Proof Status               β”‚
β”‚                     β”‚ ◀───────────────────────────────────── β”‚
β”‚   Smart Contract    β”‚                                        β”‚
β”‚   (Privacy Pool)    β”‚    7. Verify Aggregated Proof          β”‚
β”‚                     β”‚ ──────────────────────────────────────▢│
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                        β”‚
           β”‚                                                   β”‚
           β”‚ 9. Transfer ETH                                   β”‚
           β–Ό                                                   β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                        β”‚
β”‚                     β”‚                                        β”‚
β”‚    Recipient        β”‚                                        β”‚
β”‚                     β”‚                                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                        β”‚
                                                               β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    3. Submit & Wait                    β”‚
β”‚                     β”‚ β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚   Ethereum Chain    β”‚
β”‚  (Settlement Layer) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Architecture Components

1. Smart Contract (Pool)

  • Acts as an ETH pool that holds deposited funds
  • Tracks commitments and their associated amounts
  • Verifies zero-knowledge proofs via zkVerify integration
  • Executes transfers from pool to recipients

2. Zero-Knowledge Circuit

  • Proves ownership of a commitment without revealing the private key
  • Validates that the user knows the secret behind a specific commitment
  • Generates proofs that are verified on-chain through zkVerify

3. Relayer Wallet System

  • Submits transactions on behalf of users to hide the actual sender
  • Pays gas fees for transaction execution
  • Ensures the transaction caller is not the original depositor

Privacy Flow

Step 1: Deposit

User A deposits ETH β†’ Smart Contract Pool

  • Generates commitment = hash(privateKey, nonce)
  • Contract stores: commitmentAmounts[commitment] = depositAmount
  • Public info: Someone deposited X ETH with commitment Y

Step 2: Private Transfer

User A (or someone with A's private key) initiates transfer:

  1. Generate ZK proof proving ownership of commitment
  2. Submit proof to zkVerify for verification
  3. Relayer Wallet calls privateTransfer() with verified proof
  4. Contract transfers ETH from pool β†’ Recipient

Step 3: Privacy Achievement

On-chain observers see:

  • Transaction 1: User A β†’ Contract (deposit)
  • Transaction 2: Relayer Wallet β†’ Contract β†’ Recipient (transfer)
  • No direct link between User A and Recipient

Folder Structure

The repository is organized into three main directories:

  • app/: Node.js application that serves as the frontend interface and handles zero-knowledge proof generation
  • generate_proof/: Noir circuits for generating proofs of commitment ownership
  • contracts/: Solidity smart contracts for the privacy pool, managed with Foundry framework

Prerequisites

Before you begin, ensure you have the following tools installed:

  • Node.js: JavaScript runtime environment

  • Foundry: Ethereum development toolkit for smart contracts

  • Noirup: Noir toolchain installer

    Important: You must use version 1.0.0-beta.12 specifically:

    noirup -v 1.0.0-beta.12

    Newer versions will not work with the current circuit implementation.

Development Setup

Step-by-Step Setup

1. Clone and Install Dependencies

git clone git@github.com:Poly-pay/polypay_noir.git
cd polypay_noir

# Install Node.js dependencies
cd app
npm install
cd ..

2. Compile the Circuit

cd generate_proof/
nargo compile

This will generate target/generate_proof.json, which the application uses during proof generation.

3. Environment Configuration

Navigate to the app/ directory and set up your environment:

cd app
cp .env.template .env

Edit the .env file and configure the following variables:

4. Register Verification Key Hash

From the app/ directory, register the verification key:

npm run registerVK

Note: This step requires your .env file to be properly configured. The command will register the verification key and output a vkHash value.

5. Update Contract Environment

Copy the generated vkHash to the .env file in the contracts/ directory.

6. Deploy Smart Contract

Navigate to the contracts directory and deploy the smart contract:

cd contracts
forge script script/PrivateTransferContract.s.sol:ZkvVerifierContractScript \
  --rpc-url wss://ethereum-sepolia-rpc.publicnode.com \
  --private-key=YOUR_PRIVATE_KEY \
  --broadcast

Important: Replace YOUR_PRIVATE_KEY with your actual private key.

7. Update App Configuration

Complete the configuration by updating these values:

  • Save the deployed contract address to the .env file in the app/ directory
  • Update the relayer wallet private key in app.js:
this.relayerWallet = new ethers.Wallet(
  "YOUR_PRIVATE_KEY", // Replace with your relayer wallet private key
  provider
);

8. Run the Application

Start the application:

cd app
npm run start

End-to-End User Workflow

  1. Generate a Proof: The user interacts with the app, which uses the compiled Noir circuit and proving artifacts to generate a zero-knowledge proof.
  2. Submit Proof to zkVerify: The DApp sends the generated proof and public inputs to zkVerify for verification
  3. Receive Proof ID: zkVerify verifies the proof and returns proof
  4. Execute Private Transfer: The relayer wallet calls the smart contract with the proof, enabling anonymous transfer from pool to recipient
  5. On-Chain Attestation: The smart contract verifies the proof through zkVerify's attestation contract

Next Steps

Check out zkVerify documentation for additional info and tutorials:

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors