- Project Overview
- Architecture
- Setup & Prerequisites
- Initial Deployment
- Contract Verification
- Python Integration
- Upgrade System
- Version Management
- Testing & Validation
- Troubleshooting
- Production Checklist
- API Reference
DePIN Scanner is an upgradeable smart contract system for tracking and scoring validator nodes in decentralized physical infrastructure networks (DePINs). It provides:
- Scan Summary Storage: Immutable records of validator security scans
- Reputation System: Trust scoring for validator hosts
- Batch Operations: Efficient multi-scan processing
- Analytics Dashboard: Network-wide statistics and insights
- Upgrade Path: Seamless contract upgrades with data preservation
- ✅ Scan Publication: Store scan results with Walrus storage pointers
- ✅ Reputation Tracking: Automatic trust score calculation
- ✅ Access Control: Publisher/moderator role management
- ✅ Rate Limiting: Spam prevention with cooldown periods
- ✅ Emergency Controls: Pause/unpause functionality
- ✅ Batch Operations: Publish up to 50 scans in one transaction
- ✅ Reputation Decay: Time-based reputation degradation for inactive hosts
- ✅ Network Analytics: Daily/weekly scan volume tracking
- ✅ Analyst Role: Specialized permissions for analytics management
- ✅ Enhanced Reporting: Comprehensive network statistics
- Blockchain: zkSync Era (Ethereum L2)
- Framework: Hardhat with OpenZeppelin Upgrades
- Storage: Walrus distributed storage network
- Language: Solidity 0.8.20+
- Integration: Python interface for off-chain systems
graph TB
A[Users/Apps] --> B[Proxy Contract]
B --> C[Implementation V2/V3]
D[Factory Contract] --> B
E[Walrus Storage] --> C
F[Analytics Dashboard] --> B
G[Python Interface] --> B
graph LR
A[Proxy Address<br/>0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da] --> B[Implementation V2<br/>0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE]
A --> C[Implementation V3<br/>0x7ecAeF088A7b5E86c571fE8E6ED2854Ec1bbdA26]
A --> D[Implementation V4<br/>Future]
style A fill:#e1f5fe
style B fill:#f3e5f5
style C fill:#e8f5e8
- Same Address: Users always interact with the same proxy address
- Owner Control: Only contract owner can authorize upgrades
- Gas Efficient: Upgrade logic in implementation, not proxy
- Data Preservation: All state maintained during upgrades
- Node.js: 16+
- npm: 8+
- Git: Latest version
- Wallet: MetaMask or similar with testnet ETH
- RPC URL:
https://sepolia.era.zksync.dev - Chain ID:
300 - Explorer:
https://sepolia.explorer.zksync.io/ - Faucets:
- RPC URL:
https://mainnet.era.zksync.io - Chain ID:
324 - Explorer:
https://explorer.zksync.io/
# 1. Create project directory
mkdir depin-scanner-contracts
cd depin-scanner-contracts
# 2. Initialize npm project
npm init -y
# 3. Install dependencies
npm install --save-dev @nomicfoundation/hardhat-toolbox @openzeppelin/hardhat-upgrades hardhat dotenv
npm install @openzeppelin/contracts @openzeppelin/contracts-upgradeable
# 4. Initialize Hardhat
npx hardhat init
# 5. Create directory structure
mkdir -p contracts/{versions,interfaces}
mkdir -p scripts/{deployment,upgrades,utilities,management}
mkdir -p test/{unit,integration}
mkdir -p deployments/{zkSyncSepolia,zkSyncMainnet,localhost}Create .env file:
# Required
PRIVATE_KEY=0xYourPrivateKeyHere
ZKSYNC_RPC_URL=https://sepolia.era.zksync.dev
# Optional
ETHERSCAN_API_KEY=YourEtherscanApiKey
GAS_LIMIT=2100000
GAS_PRICE_GWEI=0.025
# Walrus Storage
WALRUS_API_URL=https://publisher-devnet.walrus.space
WALRUS_API_KEY=your-walrus-api-key
# Contract Addresses (filled after deployment)
CONTRACT_ADDRESS=
IMPLEMENTATION_ADDRESS=
FACTORY_ADDRESS=depin-scanner-contracts/
├── contracts/
│ ├── DePINScanLedger.sol # V2 Base implementation
│ ├── DePINScanLedgerV3.sol # V3 Enhanced implementation
│ ├── DePINScanLedgerProxy.sol # Proxy contract
│ ├── DePINScanLedgerFactory.sol # Factory for deployments
│ └── interfaces/
│ └── IDePINScanLedger.sol # Interface definition
├── scripts/
│ ├── deployment/
│ │ ├── 01-deploy-implementation.js
│ │ ├── 02-deploy-factory.js
│ │ ├── 03-deploy-proxy.js
│ │ └── 04-verify-contracts.js
│ ├── upgrades/
│ │ ├── upgrade.js # Single upgrade script
│ │ ├── validate-upgrade.js
│ │ └── list-versions.js
│ └── utilities/
│ ├── test-contract.js
│ ├── diagnose-upgrade.js
│ └── initialize-v3.js
├── test/
│ ├── unit/
│ └── integration/
├── deployments/
│ └── zkSyncSepolia/
│ ├── deployment.json # Main deployment info
│ ├── implementation.json # Implementation details
│ ├── factory.json # Factory details
│ └── proxy.json # Proxy details
├── hardhat.config.js
├── package.json
└── .env
# Deploy the main logic contract
npm run deploy:implementation -- zkSyncSepoliaWhat happens:
- Deploys
DePINScanLedger.sol(V2 base version) - Saves deployment info to
deployments/zkSyncSepolia/implementation.json - Attempts automatic verification on block explorer
Example Output:
🚀 Deploying DePINScanLedger implementation...
✅ Implementation deployed at: 0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE
📊 Contract version: 2.0.0
💾 Implementation info saved
# Deploy the factory for creating proxy instances
npm run deploy:factory -- zkSyncSepoliaWhat happens:
- Deploys
DePINScanLedgerFactory.sol - Auto-verifies the implementation in the factory
- Saves factory info to
deployments/zkSyncSepolia/factory.json
Example Output:
🏭 Deploying DePINScanLedgerFactory...
✅ Factory deployed at: 0x8282EDCa09B68c62c0697Af4f0d7AF7d7D8A87BB
✅ Implementation verified in factory
# Deploy proxy via factory (this is what users interact with)
npm run deploy:proxy -- zkSyncSepoliaWhat happens:
- Uses factory to deploy
DePINScanLedgerProxy.sol - Initializes the proxy with testnet settings
- Saves proxy info to
deployments/zkSyncSepolia/deployment.json - Tests proxy functionality
Example Output:
🔗 Deploying DePINScanLedgerProxy via factory...
✅ Proxy deployed at: 0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da
🎯 Users should interact with: 0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da
✅ Proxy is working!
Add to your .env file:
CONTRACT_ADDRESS=0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da
IMPLEMENTATION_ADDRESS=0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE
FACTORY_ADDRESS=0x8282EDCa09B68c62c0697Af4f0d7AF7d7D8A87BB# Deploy everything in sequence
npm run deploy:all -- zkSyncSepolia# Verify all contracts on block explorer
npm run verify -- zkSyncSepoliaIf automatic verification fails:
# Verify implementation
npx hardhat verify --network zkSyncSepolia 0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE
# Verify factory
npx hardhat verify --network zkSyncSepolia 0x8282EDCa09B68c62c0697Af4f0d7AF7d7D8A87BBVisit the block explorer:
- Proxy:
https://sepolia.explorer.zksync.io/address/0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da - Implementation:
https://sepolia.explorer.zksync.io/address/0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE
Expected Results:
- ✅ Source code visible in "Contract" tab
- ✅ "Read Contract" and "Write Contract" tabs functional
- ✅ Green checkmark indicating verification
# Install required dependencies
pip install web3 eth-account python-dotenv requestsfrom depin_ledger_interface import DePINLedgerInterface
# Initialize with environment variables
ledger = DePINLedgerInterface()
# Or manual configuration
ledger = DePINLedgerInterface(
rpc_url="https://sepolia.era.zksync.dev",
contract_address="0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da",
contract_abi=CONTRACT_ABI,
private_key="0xYourPrivateKey"
)# Check contract version
version = await ledger.get_contract_version()
print(f"Contract version: {version}")
# Publish a scan summary
tx_hash = await ledger.publish_scan_summary(
host_uid="validator_001",
scan_time=int(time.time()),
summary_hash="0x1234...",
score=850,
report_pointer="walrus_hash_abc123"
)
# Get scan results
summary = await ledger.get_scan_summary("0x1234...")
reputation = await ledger.get_host_reputation("validator_001")# .env file for Python
ZKSYNC_RPC_URL=https://sepolia.era.zksync.dev
CONTRACT_ADDRESS=0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da
PRIVATE_KEY=0xYourPrivateKey
CONTRACT_ABI=[...] # Full ABI JSONThe upgrade system uses a single script that handles everything automatically:
# Upgrade to V3
TARGET_VERSION=v3 npm run upgrade -- zkSyncSepolia
# Skip validation (faster, not recommended for production)
SKIP_VALIDATION=true TARGET_VERSION=v3 npm run upgrade -- zkSyncSepolia- 📍 Load Current State: Reads existing deployment configuration
- 📊 Capture Pre-State: Records current contract state for validation
- 📥 Register Proxy: Ensures proxy is registered with OpenZeppelin
- ⚡ Validate Safety: Checks storage layout compatibility
- 🔄 Deploy New Implementation: Deploys new contract version
- 🔗 Upgrade Proxy: Points proxy to new implementation
- 📊 Validate Post-State: Ensures data preservation
- 🔧 Initialize Features: Enables new version features
- 🔍 Verify Contract: Verifies new implementation on explorer
- 💾 Update Records: Updates deployment tracking
sequenceDiagram
participant U as User
participant S as Upgrade Script
participant P as Proxy
participant V2 as Implementation V2
participant V3 as Implementation V3
participant E as Explorer
U->>S: TARGET_VERSION=v3 npm run upgrade
S->>P: Load current state
S->>V2: Capture pre-upgrade data
S->>S: Validate upgrade safety
S->>V3: Deploy new implementation
S->>P: Upgrade proxy to V3
S->>V3: Validate post-upgrade data
S->>V3: Initialize V3 features
S->>E: Verify contract
S->>S: Update deployment records
S->>U: Upgrade complete!
# Validate upgrade safety before upgrading
TARGET_VERSION=v3 npm run upgrade:validate -- zkSyncSepolia
# Check current upgrade status
npm run diagnose -- zkSyncSepoliaThe system automatically tracks all upgrades:
{
"version": "3.0.0",
"proxyAddress": "0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da",
"implementationAddress": "0x7ecAeF088A7b5E86c571fE8E6ED2854Ec1bbdA26",
"versionHistory": [
{
"version": "2.0.0",
"implementationAddress": "0xAaFf1D06943E0A2F117b0Ef31447Ac508f0387EE",
"upgradedAt": "2024-01-20T15:45:00Z",
"contractName": "DePINScanLedger"
}
],
"lastUpgrade": "2024-01-25T10:30:00Z"
}# List all available contract versions
npm run versionsExample Output:
📦 Available Versions:
- v2 (base): DePINScanLedger
- v3: DePINScanLedgerV3
🌐 Network Deployments:
📍 ZKSYNCSEPOLIATESTNET:
- Current Version: 3.0.0
- Proxy Address: 0x6e11955C378c406FC2f0BD5eE8aA6e8A92A833da
- Implementation: 0x7ecAeF088A7b5E86c571fE8E6ED2854Ec1bbdA26
- ✅ Scan summary publication and storage
- ✅ Host reputation tracking and scoring
- ✅ Publisher/moderator access control
- ✅ Rate limiting and spam prevention
- ✅ Emergency pause/unpause functionality
- ✅ Batch query operations
- ✅ Event emission for all major actions
- ✅ All V2 features preserved
- ✅ Batch scan publication (up to 50 scans/tx)
- ✅ Reputation decay for inactive hosts
- ✅ Network analytics and statistics
- ✅ Daily/weekly scan volume tracking
- ✅ Analyst role for analytics management
- ✅ Enhanced reporting capabilities
- ✅ Improved gas efficiency
When creating a new version (e.g., V4):
- Create contract file:
contracts/DePINScanLedgerV4.sol - Maintain storage compatibility: Follow OpenZeppelin storage layout rules
- Add to version mapping: Update
getContractNameForVersion()function - Test thoroughly: Unit and integration tests
- Deploy and upgrade:
TARGET_VERSION=v4 npm run upgrade
While not automated, rollbacks can be performed by:
- Deploy previous version: Re-deploy older implementation
- Use upgrade script:
TARGET_VERSION=v2 npm run upgrade - Validate state: Ensure data consistency
# Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Test deployed contract
npm run test-contract -- zkSyncSepolia- Individual function testing
- Access control verification
- Edge case handling
- Gas usage optimization
- Full workflow testing
- Upgrade scenarios
- Multi-contract interaction
- Event emission verification
# Test current deployed contract
npm run test-contract -- zkSyncSepoliaExample Test Output:
🧪 Testing DePIN Scanner Contract...
✅ V2 VERSION(): 3.0.0
✅ V2 functions work - Owner: 0x0D685...
✅ V3 functions work - V3 initialized: true
✅ Scan publication successful
📊 Total summaries: 2
🎉 All Tests Passed!
# Diagnose current contract state
npm run diagnose -- zkSyncSepolia
# Check upgrade status
npm run status -- zkSyncSepolia
# Validate specific upgrade
TARGET_VERSION=v3 npm run upgrade:validate -- zkSyncSepolia- Publish single scan: ~200,000 gas
- Batch publish (10 scans): ~800,000 gas
- Query operations: ~50,000 gas
- Upgrade transaction: ~300,000 gas
- Read operations: <1 second
- Write operations: 2-5 seconds (network dependent)
- Batch operations: 5-10 seconds
Problem: Error: insufficient funds for gas
# Solution: Get testnet ETH
# Visit: https://faucet.quicknode.com/zksync/sepoliaProblem: Network zkSyncSepolia doesn't exist
# Solution: Check hardhat.config.js network configuration
# Ensure zkSyncSepolia network is properly definedProblem: Contract verification failed
# Solution: Manual verification
npx hardhat verify --network zkSyncSepolia CONTRACT_ADDRESS
# Or force verification
npx hardhat verify --network zkSyncSepolia CONTRACT_ADDRESS --forceProblem: Storage layout is incompatible
# Solution: Fix storage layout in new contract version
# Ensure new variables use storage gap slots
# Follow OpenZeppelin upgrade guidelinesProblem: Deployment at address is not registered
# Solution: Force import existing proxy
npx hardhat run scripts/utilities/force-import-proxy.js --network zkSyncSepoliaProblem: V3 features not working after upgrade
# Solution: Initialize V3 features
npx hardhat run scripts/utilities/initialize-v3.js --network zkSyncSepoliaProblem: Not authorized to publish
# Solution: Authorize publisher address
# Call: setPublisherAuthorization(address, true)Problem: Rate limit exceeded
# Solution: Wait for cooldown period or adjust cooldown
# Current cooldown can be checked with getContractInfo()Problem: Host reputation below threshold
# Solution: Increase host reputation or lower threshold
# Check current reputation with getHostReputation()# Get detailed contract status
npm run diagnose -- zkSyncSepolia
# Check transaction on explorer
# https://sepolia.explorer.zksync.io/tx/TRANSACTION_HASH
# Interactive debugging
npx hardhat console --network zkSyncSepolia
# Clear cache and recompile
npm run clean && npx hardhat compile- zkSync Docs: https://docs.zksync.io/
- OpenZeppelin Upgrades: https://docs.openzeppelin.com/upgrades-plugins/
- Hardhat Documentation: https://hardhat.org/docs
- Community Discord: Join zkSync and OpenZeppelin communities
- Smart contract security audit completed
- Upgrade mechanism reviewed
- Access control properly configured
- Rate limiting appropriate for production load
- All unit tests passing
- Integration tests completed
- Upgrade scenarios tested
- Load testing performed
- Gas optimization verified
- Production gas prices configured
- Rate limiting set appropriately
- Access control roles properly assigned
- Emergency procedures documented
- Deploy to Mainnet
# Update .env for mainnet
ZKSYNC_RPC_URL=https://mainnet.era.zksync.io
CONTRACT_ADDRESS=
PRIVATE_KEY=0xMainnetPrivateKey
# Deploy to mainnet
npm run deploy:all -- zkSyncMainnet- Verify Contracts
npm run verify -- zkSyncMainnet- Configure Production Settings
# Set production cooldown (30 minutes)
# Set production reputation threshold (100)
# Configure production moderators
# Set up monitoring- Transaction success rate
- Gas usage trends
- Average response times
- Error rates
- Contract balance
- Upgrade timing
- Weekly contract health check
- Monthly gas usage analysis
- Quarterly security review
- Annual contract audit
- Emergency pause procedure documented
- Upgrade rollback plan ready
- Incident response team identified
- Communication plan established
# Mainnet configuration
ZKSYNC_RPC_URL=https://mainnet.era.zksync.io
CONTRACT_ADDRESS=0xMainnetProxyAddress
IMPLEMENTATION_ADDRESS=0xMainnetImplementationAddress
FACTORY_ADDRESS=0xMainnetFactoryAddress
PRIVATE_KEY=0xMainnetPrivateKey
# Production settings
GAS_LIMIT=3000000
GAS_PRICE_GWEI=1.5
# Monitoring
MONITORING_ENABLED=true
ALERT_WEBHOOK_URL=https://your-monitoring-service.com/webhookfunction publishScanSummary(
string memory hostUid,
uint256 scanTime,
bytes32 summaryHash,
uint16 score,
string memory reportPointer
) external;Parameters:
hostUid: Anonymized host identifierscanTime: UNIX timestamp of scansummaryHash: Hash of JSON summary datascore: Trust score (0-65535)reportPointer: Walrus storage hash
function getScanSummary(bytes32 summaryHash)
external view returns (ScanSummary memory);function getHostSummaries(string memory hostUid)
external view returns (bytes32[] memory);function getHostReputation(string memory hostUid)
external view returns (uint256);function getHostMetrics(string memory hostUid)
external view returns (ReputationMetrics memory);function updateHostReputation(
string memory hostUid,
uint256 newReputation,
string memory reason
) external;function setPublisherAuthorization(address publisher, bool authorized) external;
function setModeratorAuthorization(address moderator, bool authorized) external;function batchPublishScans(BatchScanRequest[] memory scans)
external returns (uint256 batchId);function getNetworkAnalytics()
external view returns (NetworkAnalytics memory);function setHostReputationDecay(
string memory hostUid,
uint256 decayRate,
uint256 minimumReputation,
bool enabled
) external;struct ScanSummary {
string hostUid; // Anonymised host hash
uint256 scanTime; // UNIX timestamp of scan
bytes32 summaryHash; // Hash of JSON summary
uint16 score; // Trust score (0-65535)
string reportPointer; // Walrus hash reference
string status; // "active" or "deleted"
uint256 deletedAt; // Timestamp when marked as deleted
string deletionReason; // Reason for deletion
uint256 reputationAtScan; // Host reputation at time of scan
}struct ReputationMetrics {
uint256 totalScans;
uint256 averageScore;
uint256 lastScanTime;
uint256 consecutiveHighScores;
uint256 flaggedScans;
bool isVerified;
}struct NetworkAnalytics {
uint256 totalHosts;
uint256 activeHosts;
uint256 verifiedHosts;
uint256 averageNetworkScore;
uint256 totalScansToday;
uint256 totalScansThisWeek;
uint256 lastAnalyticsUpdate;
}event ScanPublished(
string indexed hostUid,
bytes32 indexed summaryHash,
uint16 score,
string reportPointer,
address indexed publisher,
uint256 reputationAtScan
);
event ScanDeleted(
bytes32 indexed summaryHash,
uint256 deletedAt,
string reason,
address indexed moderator
);
event ReputationUpdated(
string indexed hostUid,
uint256 oldReputation,
uint256 newReputation,
string reason
);
// V3 Events
event BatchScansPublished(
uint256 indexed batchId,
uint256 scanCount,
address indexed publisher
);
event ReputationDecayed(
string indexed hostUid,
uint256 oldReputation,
uint256 newReputation,
uint256 daysSinceActivity
);class DePINLedgerInterface:
def __init__(self, rpc_url=None, contract_address=None, contract_abi=None, private_key=None)
async def publish_scan_summary(self, host_uid, scan_time, summary_hash, score, report_pointer)
async def get_scan_summary(self, summary_hash)
async def get_host_summaries(self, host_uid)
async def get_host_reputation(self, host_uid)
async def delete_scan_summary(self, summary_hash, reason)
# V3 Methods
async def batch_publish_scans(self, scans)
async def get_network_analytics(self)
async def apply_reputation_decay(self, host_uid)| Error | Description | Solution |
|---|---|---|
Not authorized to publish |
Caller not authorized | Use setPublisherAuthorization() |
Rate limit exceeded |
Too many requests | Wait for cooldown period |
Host reputation below threshold |
Reputation too low | Increase reputation or lower threshold |
Summary already exists |
Duplicate summary hash | Use unique summary hash |
V3 not initialized |
V3 features not enabled | Call initializeV3() |
This comprehensive documentation covers all aspects of the DePIN Scanner project from initial setup through production deployment. Each section provides practical examples, troubleshooting tips, and best practices for successful implementation.
For additional support or questions, refer to the community resources and documentation links provided throughout this guide.