A zero-knowledge multi-signature wallet that preserves owner privacy while maintaining the security guarantees of traditional multisig wallets. The wallet uses zk-SNARKs (Groth16) to prove ownership without revealing the actual owners' addresses.
This implementation combines:
- Zero-knowledge proofs for owner privacy
- Multi-signature functionality for enhanced security
- On-chain transaction management
- Replay attack prevention through attestations
- Privacy: Owner addresses are never revealed on-chain
- Security: Requires M-of-N signatures to execute transactions
- Flexibility: Supports arbitrary ETH transfers and contract interactions
- Replay Protection: Uses unique attestations for each signature
-
MultiSigWallet.sol
- Manages transaction lifecycle
- Stores hashed owner identities
- Verifies zk-proofs for ownership
- Handles transaction execution
-
Groth16Verifier.sol
- Verifies zero-knowledge proofs
- Integrated with the main wallet contract
The zero-knowledge circuit (multisig.circom
) proves:
- Ownership: The prover knows a private key corresponding to one of the registered owner hashes
- Message Attestation: The prover has signed the transaction data
npm install hardhat ethers snarkjs circomlib
- Compile Circuits
# Compile the circuit
circom multisig.circom --r1cs --wasm --sym
# Generate and contribute to the trusted setup
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
# Generate the final zkey
snarkjs groth16 setup multisig.r1cs pot12_0001.ptau multisig_0000.zkey
snarkjs zkey contribute multisig_0000.zkey multisig_0001.zkey --name="1st Contributor" -v
- Deploy Contracts
npx hardhat run scripts/deploy.js --network <your-network>
- Generate a proof of ownership:
const proof = await createProof(
ownerPrivateKey, // Private key chunks
messageHash, // Transaction data hash
ownerHash1, // Registered owner hashes
ownerHash2,
ownerHash3
);
- Submit the transaction:
await multisig.submitTransaction(
to, // Destination address
value, // ETH amount
data, // Transaction data
proof.a, // Proof components
proof.b,
proof.c,
proof.publicSignals
);
await multisig.confirmTransaction(
txIndex, // Transaction index
proof.a, // New proof components
proof.b,
proof.c,
proof.publicSignals
);
Once enough confirmations are collected:
await multisig.executeTransaction(txIndex);
-
Private Key Management
- Never share private keys
- Use secure key generation and storage
-
Proof Generation
- Generate proofs locally
- Verify proofs before submission
-
Smart Contract Security
- Contract is non-upgradeable
- Uses replay protection for signatures
- Implements proper access controls
Run the test suite:
npx hardhat test
The test suite includes:
- Contract deployment
- Transaction submission
- Confirmation flow
- Execution verification
- Invalid proof rejection
- Clone the repository:
git clone https://github.com/CleanPegasus/dragonfly-multisig
cd dragonfly-multisig
- Install dependencies:
npm install
- Run local node:
npx hardhat node
- Deploy contracts:
npx hardhat run scripts/deploy.js --network localhost