3. Core Technical Architecture
3.1 Smart Contract Design
3.1.1 Core Data Structures
solidity
struct DepositInfo {
uint256 amount; // Deposit amount
address owner; // Depositor address
bool used; // Whether used
}
mapping(uint256 => DepositInfo) public deposits; // Deposit records
mapping(bytes32 => bool) public usedProofs; // Used proofs
mapping(bytes32 => bool) public validCommitments; // Valid commitments
uint256 public nextDepositId; // Next deposit ID3.1.2 Core Functions
Deposit Function:
solidity
function deposit() external payable returns (uint256) {
uint256 depositId = nextDepositId++;
deposits[depositId] = DepositInfo({
amount: msg.value,
owner: msg.sender,
used: false
});
return depositId;
}Commitment Submission Function:
solidity
function submitCommitment(
bytes32 commitment,
uint256 depositId,
uint256 totalAmount,
bytes calldata sp1Proof
) external {
// Verify deposit validity and ownership
require(deposits[depositId].owner == msg.sender, "Not owner");
require(!deposits[depositId].used, "Already used");
// Verify zero-knowledge proof
require(sp1Verifier.verifyProof(...), "Invalid proof");
// Verify amount constraint
require(totalAmount <= deposits[depositId].amount, "Amount exceeds");
// Update state
deposits[depositId].used = true;
validCommitments[commitment] = true;
// Update hash tree
_updateMerkleTree(commitment);
}Withdrawal Function:
solidity
function withdraw(
address recipient,
uint256 amount,
bytes calldata finalProof
) external {
// Anti-replay check
bytes32 proofHash = keccak256(finalProof);
require(!usedProofs[proofHash], "Proof used");
// Verify zero-knowledge proof
require(sp1Verifier.verifyProof(...), "Invalid proof");
// Mark proof as used
usedProofs[proofHash] = true;
// Execute transfer
payable(recipient).transfer(amount);
}3.2 Zero-Knowledge Proof Circuit Design
3.2.1 SP1 Circuit Implementation
EnclaveProtocol uses SP1 zkVM as the zero-knowledge proof system, mainly including two types of proofs:
Commitment Submission Proof Circuit:
rust
fn prove_commitment_submission() {
// Private inputs
let allocations = sp1_zkvm::io::read::<Vec<Allocation>>();
let secret = sp1_zkvm::io::read::<[u8; 32]>();
// Public inputs
let commitment = sp1_zkvm::io::read::<[u8; 32]>();
let deposit_id = sp1_zkvm::io::read::<u64>();
let total_amount = sp1_zkvm::io::read::<u64>();
// Constraint verification
let computed_commitment = hash_commitment(&allocations, &secret, &deposit_id);
assert_eq!(commitment, computed_commitment);
let total_allocated: u64 = allocations.iter().map(|a| a.amount).sum();
assert!(total_allocated <= total_amount);
// Output public values
sp1_zkvm::io::commit(&commitment);
sp1_zkvm::io::commit(&deposit_id);
sp1_zkvm::io::commit(&total_amount);
}Withdrawal Proof Circuit:
rust
fn prove_individual_withdrawal() {
// Private inputs
let allocations = sp1_zkvm::io::read::<Vec<Allocation>>();
let secret = sp1_zkvm::io::read::<[u8; 32]>();
let deposit_id = sp1_zkvm::io::read::<u64>();
// Public inputs
let recipient = sp1_zkvm::io::read::<[u8; 20]>();
let amount = sp1_zkvm::io::read::<u64>();
// Verify user is in allocation
let user_found = allocations.iter()
.any(|a| a.address == recipient && a.amount == amount);
assert!(user_found, "User not found in allocations");
// Verify commitment
let commitment = hash_commitment(&allocations, &secret, &deposit_id);
// Output verification result
sp1_zkvm::io::commit(&recipient);
sp1_zkvm::io::commit(&amount);
}3.3 Triple Anti-Double-Spending Mechanism
EnclaveProtocol implements three-layer anti-double-spending protection:
Withdrawal Request Input
│
▼
┌─────────────────────────┐
│ Layer 1 Check │
│ Deposit ID │
│ deposits[id].used │
│ == false ? │
└───────────┬─────────────┘
│ Pass
▼
┌─────────────────────────┐
│ Layer 2 Check │
│ Proof Hash │
│ usedProofs[hash] │
│ == false ? │
└───────────┬─────────────┘
│ Pass
▼
┌─────────────────────────┐
│ Layer 3 Check │
│ Commitment │
│ validCommitments[c] │
│ == true ? │
└───────────┬─────────────┘
│ Pass
▼
Execute TransferThree-Layer Protection Explanation:
- Deposit ID Layer: Ensures each deposit can only be used once, preventing fund source duplication
- Proof Layer: Ensures each zero-knowledge proof can only be used once, preventing proof replay attacks
- Commitment Layer: Ensures only valid commitments can be withdrawn, preventing forgery attacks
3.4 Distributed Prover Network
3.4.1 Network Architecture
EnclaveProtocol supports a distributed prover network, anyone can become a proof generator:
User Layer (Users)
↓
Load Balancer
↓
Prover Pool
↓
Quality Monitor3.4.2 Incentive Mechanism
Fee Distribution Model:
Total Fee = Base Fee + Prover Fee + Network Fee
- Base Fee: 50% (Protocol maintenance)
- Prover Fee: 40% (Proof generation incentive)
- Network Fee: 10% (Gas fees)Prover Admission Mechanism:
- Minimum staking requirement: 1000 tokens
- Hardware requirements: 4-core CPU + 8GB RAM
- Network requirements: Stable internet connection
- Reputation requirements: No malicious behavior records
Quality Assurance Mechanism:
- Proof correctness verification: Incorrect proofs will deduct staking
- Response time requirements: Timeouts will affect reputation scores
- Availability monitoring: Extended offline time will reduce delegation weight
[← Previous: EnclaveProtocol: Adding Privacy Capabilities to Blockchain](./02-adding-privacy-capabilities) | [Next: Technical Innovation Points →](./04-technical-innovation)