feat: add marketplace metrics, privacy features, and service registry endpoints
- Add Prometheus metrics for marketplace API throughput and error rates with new dashboard panels - Implement confidential transaction models with encryption support and access control - Add key management system with registration, rotation, and audit logging - Create services and registry routers for service discovery and management - Integrate ZK proof generation for privacy-preserving receipts - Add metrics instru
This commit is contained in:
239
contracts/ZKReceiptVerifier.sol
Normal file
239
contracts/ZKReceiptVerifier.sol
Normal file
@ -0,0 +1,239 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import "./Groth16Verifier.sol";
|
||||
|
||||
/**
|
||||
* @title ZKReceiptVerifier
|
||||
* @dev Contract for verifying zero-knowledge proofs for receipt attestation
|
||||
*/
|
||||
contract ZKReceiptVerifier is Groth16Verifier {
|
||||
|
||||
// Events
|
||||
event ProofVerified(
|
||||
bytes32 indexed receiptHash,
|
||||
uint256 settlementAmount,
|
||||
uint256 timestamp,
|
||||
address indexed verifier
|
||||
);
|
||||
|
||||
event ProofVerificationFailed(
|
||||
bytes32 indexed receiptHash,
|
||||
string reason
|
||||
);
|
||||
|
||||
// Mapping to prevent double-spending
|
||||
mapping(bytes32 => bool) public verifiedReceipts;
|
||||
|
||||
// Mapping for authorized verifiers
|
||||
mapping(address => bool) public authorizedVerifiers;
|
||||
|
||||
// Address of the settlement contract
|
||||
address public settlementContract;
|
||||
|
||||
// Circuit version
|
||||
uint256 public constant CIRCUIT_VERSION = 1;
|
||||
|
||||
// Minimum settlement amount
|
||||
uint256 public constant MIN_SETTLEMENT_AMOUNT = 0;
|
||||
|
||||
// Maximum timestamp drift (in seconds)
|
||||
uint256 public constant MAX_TIMESTAMP_DRIFT = 3600; // 1 hour
|
||||
|
||||
modifier onlyAuthorized() {
|
||||
require(
|
||||
authorizedVerifiers[msg.sender] ||
|
||||
msg.sender == settlementContract,
|
||||
"ZKReceiptVerifier: Unauthorized"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlySettlementContract() {
|
||||
require(
|
||||
msg.sender == settlementContract,
|
||||
"ZKReceiptVerifier: Only settlement contract"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
// Deployer is initially authorized
|
||||
authorizedVerifiers[msg.sender] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Verify a ZK proof for receipt attestation
|
||||
* @param a Proof parameter a
|
||||
* @param b Proof parameter b
|
||||
* @param c Proof parameter c
|
||||
* @param publicSignals Public signals from the proof
|
||||
* @return valid Whether the proof is valid
|
||||
*/
|
||||
function verifyProof(
|
||||
uint[2] calldata a,
|
||||
uint[2][2] calldata b,
|
||||
uint[2] calldata c,
|
||||
uint[2] calldata publicSignals
|
||||
) external view returns (bool valid) {
|
||||
// Extract public signals
|
||||
bytes32 receiptHash = bytes32(publicSignals[0]);
|
||||
uint256 settlementAmount = publicSignals[1];
|
||||
uint256 timestamp = publicSignals[2];
|
||||
|
||||
// Validate public signals
|
||||
if (!_validatePublicSignals(receiptHash, settlementAmount, timestamp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the proof using Groth16
|
||||
return this.verifyProof(a, b, c, publicSignals);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Verify and record a proof for settlement
|
||||
* @param a Proof parameter a
|
||||
* @param b Proof parameter b
|
||||
* @param c Proof parameter c
|
||||
* @param publicSignals Public signals from the proof
|
||||
* @return success Whether verification succeeded
|
||||
*/
|
||||
function verifyAndRecord(
|
||||
uint[2] calldata a,
|
||||
uint[2][2] calldata b,
|
||||
uint[2] calldata c,
|
||||
uint[2] calldata publicSignals
|
||||
) external onlyAuthorized returns (bool success) {
|
||||
// Extract public signals
|
||||
bytes32 receiptHash = bytes32(publicSignals[0]);
|
||||
uint256 settlementAmount = publicSignals[1];
|
||||
uint256 timestamp = publicSignals[2];
|
||||
|
||||
// Check if receipt already verified
|
||||
if (verifiedReceipts[receiptHash]) {
|
||||
emit ProofVerificationFailed(receiptHash, "Receipt already verified");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate public signals
|
||||
if (!_validatePublicSignals(receiptHash, settlementAmount, timestamp)) {
|
||||
emit ProofVerificationFailed(receiptHash, "Invalid public signals");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify the proof
|
||||
bool valid = this.verifyProof(a, b, c, publicSignals);
|
||||
|
||||
if (valid) {
|
||||
// Mark as verified
|
||||
verifiedReceipts[receiptHash] = true;
|
||||
|
||||
// Emit event
|
||||
emit ProofVerified(receiptHash, settlementAmount, timestamp, msg.sender);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
emit ProofVerificationFailed(receiptHash, "Invalid proof");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validate public signals
|
||||
* @param receiptHash Hash of the receipt
|
||||
* @param settlementAmount Amount to settle
|
||||
* @param timestamp Receipt timestamp
|
||||
* @return valid Whether the signals are valid
|
||||
*/
|
||||
function _validatePublicSignals(
|
||||
bytes32 receiptHash,
|
||||
uint256 settlementAmount,
|
||||
uint256 timestamp
|
||||
) internal view returns (bool valid) {
|
||||
// Check minimum amount
|
||||
if (settlementAmount < MIN_SETTLEMENT_AMOUNT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check timestamp is not too far in the future
|
||||
if (timestamp > block.timestamp + MAX_TIMESTAMP_DRIFT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check timestamp is not too old (optional)
|
||||
if (timestamp < block.timestamp - 86400) { // 24 hours ago
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check receipt hash is not zero
|
||||
if (receiptHash == bytes32(0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Set the settlement contract address
|
||||
* @param _settlementContract Address of the settlement contract
|
||||
*/
|
||||
function setSettlementContract(address _settlementContract) external {
|
||||
require(msg.sender == authorizedVerifiers[msg.sender], "ZKReceiptVerifier: Unauthorized");
|
||||
settlementContract = _settlementContract;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Add an authorized verifier
|
||||
* @param verifier Address to authorize
|
||||
*/
|
||||
function addAuthorizedVerifier(address verifier) external {
|
||||
require(msg.sender == authorizedVerifiers[msg.sender], "ZKReceiptVerifier: Unauthorized");
|
||||
authorizedVerifiers[verifier] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Remove an authorized verifier
|
||||
* @param verifier Address to remove
|
||||
*/
|
||||
function removeAuthorizedVerifier(address verifier) external {
|
||||
require(msg.sender == authorizedVerifiers[msg.sender], "ZKReceiptVerifier: Unauthorized");
|
||||
authorizedVerifiers[verifier] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Check if a receipt has been verified
|
||||
* @param receiptHash Hash of the receipt
|
||||
* @return verified Whether the receipt has been verified
|
||||
*/
|
||||
function isReceiptVerified(bytes32 receiptHash) external view returns (bool verified) {
|
||||
return verifiedReceipts[receiptHash];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Batch verify multiple proofs
|
||||
* @param proofs Array of proof data
|
||||
* @return results Array of verification results
|
||||
*/
|
||||
function batchVerify(
|
||||
BatchProof[] calldata proofs
|
||||
) external view returns (bool[] memory results) {
|
||||
results = new bool[](proofs.length);
|
||||
|
||||
for (uint256 i = 0; i < proofs.length; i++) {
|
||||
results[i] = this.verifyProof(
|
||||
proofs[i].a,
|
||||
proofs[i].b,
|
||||
proofs[i].c,
|
||||
proofs[i].publicSignals
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Struct for batch verification
|
||||
struct BatchProof {
|
||||
uint[2] a;
|
||||
uint[2][2] b;
|
||||
uint[2] c;
|
||||
uint[2] publicSignals;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user