A proof-of-concept implementation of institutional stablecoin payments with transaction-level privacy while maintaining regulatory compliance. See SPEC.md for the full protocol specification.
cd pocs/private-payment/shielded-pool
# Install Solidity dependencies
forge soldeer install# Copy the example environment file
cp .env.example .envEdit .env and fill in the required values:
PRIVATE_KEY: Your deployer private keySEPOLIA_RPC_URL: RPC endpoint for Sepolia testnet (if deploying to testnet)VERIFIER_ADDRESS: Set to0x0000000000000000000000000000000000000000for fresh deploymentATTESTATION_REGISTRY_ADDRESS: Set to0x0000000000000000000000000000000000000000for fresh deploymentETHERSCAN_API_KEY: For contract verification (optional)DEPOSIT_VERIFIER_ADDRESS: Set to0x0000000000000000000000000000000000000000for fresh deploymentTRANSFER_VERIFIER_ADDRESS: Set to0x0000000000000000000000000000000000000000for fresh deploymentWITHDRAW_VERIFIER_ADDRESS: Set to0x0000000000000000000000000000000000000000for fresh deployment
If you make changes to the circuits, you have to regenerate the solidity verifiers:
chmod +x scripts/generate-verifiers.sh
./scripts/generate-verifiers.shThe Solidity contracts are located in contracts/src/ and use the forge-std Config pattern for deployment configuration.
Deployment addresses are managed via deployments.toml. The file uses chain IDs as top-level keys with typed sub-tables:
[31337] # Chain ID (Anvil local)
endpoint_url = "http://localhost:8545"
[31337.bool]
use_mock_verifier = "${USE_MOCK_VERIFIER}"
[31337.address]
verifier_address = "0x..."
attestation_registry_address = "0x..."
shielded_pool_address = "0x..."
...Local deployment (Anvil) with mock verifiers:
- Ensure that the
USE_MOCK_VERIFIERin your .env is set totrue
# Start local node in a separate terminal
anvil
# Deploy contracts
source .env
forge script contracts/script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast --private-key "${PRIVATE_KEY}"Local deployment (Anvil) with Barretenberg generated verifiers:
- Ensure that the
USE_MOCK_VERIFIERin your .env is set tofalse
# Start local node in a separate terminal
anvil
# Deploy contracts
source .env
forge script contracts/script/DeployVerifiers.s.sol --rpc-url http://localhost:8545 --broadcast --private-key "${PRIVATE_KEY}"
forge script contracts/script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast --private-key "${PRIVATE_KEY}"To redeploy contracts to a network where they were previously deployed, remove the existing address entries from deployments.toml:
[31337.address]
# Delete these lines to allow redeployment:
# verifier_address = "0x..."
# attestation_registry_address = "0x..."
# shielded_pool_address = "0x..."Then run the deploy script again. The script will deploy new contracts and update deployments.toml with the new addresses.
# Build contracts
forge build
# Run tests
forge test# Build Circuits
nargo compile --workspace
# Run tests
nargo test --workspace# Run unit tests
cargo test --libThe E2E test executes the following flow:
- Alice deposits 1000 tokens
- Bob deposits 500 tokens
- Alice transfers 700 to Bob (keeping 300 as change)
- Bob withdraws 700
This test uses the BBProver, and generated on-chain verifiers.
- Ensure that the
USE_MOCK_VERIFIERin your .env is set tofalse
# Start local node in a separate terminal
anvil
# Deploy contracts
source .env
forge script contracts/script/DeployVerifiers.s.sol --rpc-url http://localhost:8545 --broadcast --private-key "${PRIVATE_KEY}"
forge script contracts/script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast --private-key "${PRIVATE_KEY}"
cargo test --test integration -- --nocaptureThe PoC is set up to be quite modular, so to iterate on it, you can do the following quite easily -
- Use a different proving backend: swap out the bb_prover.rs adapter
- Use a secure channel i.e Mixnet / SWIFT for institutions: swap out the channel.rs adapter
- Use a different smart contract language: swap out the contracts