|
| 1 | +# 智能合约 |
| 2 | + |
| 3 | +ISNAD 部署在 Base 网络上,采用模块化合约架构。 |
| 4 | + |
| 5 | +## 合约地址 |
| 6 | + |
| 7 | +### Base Sepolia(测试网) |
| 8 | + |
| 9 | +| 合约 | 地址 | |
| 10 | +|------|------| |
| 11 | +| ISNADToken | `0xc41c1006A1AaC093C758A2f09de16fee2561651A` | |
| 12 | +| ISNADRegistry | `0x5A06453257874Fd000738F28C462d17BFf8e1EA3` | |
| 13 | +| ISNADStaking | `0x58983D142A388A96B7d9F970005483AA044CCAD9` | |
| 14 | +| ISNADOracle | `0x418EbF8F206fA6efF3318647d8c4Ac137dDf3aC7` | |
| 15 | +| ISNADRewardPool | `0x474cB2441C0Af053DAe052302a6829a218Aa656F` | |
| 16 | +| TimelockController | `0x2c99dB618a6dBFf0F0e74f7949fcC9A23ffB4A69` | |
| 17 | +| ISNADGovernor | `0xf08269e04029eB0eeAfcE10Ed3aa9Fb2bAbB61Cd` | |
| 18 | + |
| 19 | +### Base 主网 |
| 20 | + |
| 21 | +测试网验证完成后即将上线。 |
| 22 | + |
| 23 | +## 架构概览 |
| 24 | + |
| 25 | +``` |
| 26 | +┌─────────────────────────────────────────────────────────────┐ |
| 27 | +│ ISNAD 协议 │ |
| 28 | +├──────────────┬──────────────┬──────────────┬───────────────┤ |
| 29 | +│ ISNADToken │ ISNADRegistry│ ISNADStaking │ ISNADOracle │ |
| 30 | +│ (ERC20 + │ (铭刻 + │ (质押 + │ (标记 + │ |
| 31 | +│ 投票) │ 元数据) │ 认证) │ 陪审团) │ |
| 32 | +├──────────────┴──────────────┴──────────────┴───────────────┤ |
| 33 | +│ ISNADRewardPool │ ISNADGovernor │ |
| 34 | +│ (收益分配) │ (DAO + 时间锁) │ |
| 35 | +└─────────────────────────┴──────────────────────────────────┘ |
| 36 | +``` |
| 37 | + |
| 38 | +## 合约说明 |
| 39 | + |
| 40 | +### ISNADToken |
| 41 | + |
| 42 | +具备治理功能的 ERC20 代币。 |
| 43 | + |
| 44 | +**特性:** |
| 45 | +- ERC20 标准功能 |
| 46 | +- ERC20Votes 扩展,支持治理投票 |
| 47 | +- 固定最大供应量:10 亿枚 |
| 48 | +- MINTER_ROLE:奖励池可铸造 |
| 49 | +- BURNER_ROLE:质押合约可销毁(惩罚机制) |
| 50 | + |
| 51 | +**核心函数:** |
| 52 | +```solidity |
| 53 | +function mint(address to, uint256 amount) external; |
| 54 | +function burn(address from, uint256 amount) external; |
| 55 | +function delegate(address delegatee) external; |
| 56 | +``` |
| 57 | + |
| 58 | +### ISNADRegistry |
| 59 | + |
| 60 | +将资源铭刻永久存储在链上。 |
| 61 | + |
| 62 | +**特性:** |
| 63 | +- 资源通过 SHA-256 内容哈希标识 |
| 64 | +- 元数据存储在 calldata 中(铭刻方式) |
| 65 | +- 支持大文件分块上传 |
| 66 | +- 铭刻后不可篡改 |
| 67 | + |
| 68 | +**核心函数:** |
| 69 | +```solidity |
| 70 | +function inscribe( |
| 71 | + bytes32 contentHash, |
| 72 | + uint8 resourceType, |
| 73 | + bytes calldata metadata, |
| 74 | + bytes calldata content |
| 75 | +) external returns (bytes32); |
| 76 | +
|
| 77 | +function getResource(bytes32 contentHash) external view returns ( |
| 78 | + bool inscribed, |
| 79 | + address author, |
| 80 | + uint256 blockNumber, |
| 81 | + string memory metadataUri |
| 82 | +); |
| 83 | +``` |
| 84 | + |
| 85 | +### ISNADStaking |
| 86 | + |
| 87 | +核心认证机制。 |
| 88 | + |
| 89 | +**特性:** |
| 90 | +- 审计者对资源进行质押 |
| 91 | +- 可配置锁定期(7-90 天) |
| 92 | +- 带乘数的信任分数计算 |
| 93 | +- Oracle 裁决后执行惩罚 |
| 94 | + |
| 95 | +**核心函数:** |
| 96 | +```solidity |
| 97 | +function stake( |
| 98 | + bytes32 resourceHash, |
| 99 | + uint256 amount, |
| 100 | + uint256 lockDuration |
| 101 | +) external returns (bytes32 attestationId); |
| 102 | +
|
| 103 | +function unstake(bytes32 attestationId) external; |
| 104 | +
|
| 105 | +function getTrustScore(bytes32 resourceHash) external view returns (uint256); |
| 106 | +
|
| 107 | +function getTrustTier(bytes32 resourceHash) external view returns (uint8); |
| 108 | +
|
| 109 | +function getAttestation(bytes32 attestationId) external view returns ( |
| 110 | + address auditor, |
| 111 | + bytes32 resourceHash, |
| 112 | + uint256 amount, |
| 113 | + uint256 lockUntil, |
| 114 | + uint256 lockDuration, |
| 115 | + bool slashed |
| 116 | +); |
| 117 | +``` |
| 118 | + |
| 119 | +### ISNADOracle |
| 120 | + |
| 121 | +检测与陪审团系统。 |
| 122 | + |
| 123 | +**特性:** |
| 124 | +- 标记恶意资源 |
| 125 | +- 随机选择陪审团(5 名成员) |
| 126 | +- 67% 绝对多数通过裁决 |
| 127 | +- 支持申诉(需 2 倍保证金) |
| 128 | + |
| 129 | +**核心函数:** |
| 130 | +```solidity |
| 131 | +function flag( |
| 132 | + bytes32 resourceHash, |
| 133 | + string calldata evidence |
| 134 | +) external; |
| 135 | +
|
| 136 | +function vote(bytes32 flagId, uint8 verdict) external; |
| 137 | +
|
| 138 | +function executeVerdict(bytes32 flagId) external; |
| 139 | +
|
| 140 | +function appeal(bytes32 flagId) external; |
| 141 | +``` |
| 142 | + |
| 143 | +### ISNADRewardPool |
| 144 | + |
| 145 | +向审计者分配收益。 |
| 146 | + |
| 147 | +**特性:** |
| 148 | +- 收益基于质押数量和锁定时长 |
| 149 | +- 锁定乘数:30 天=1x,60 天=1.25x,90 天=1.5x |
| 150 | +- 由协议费用和国库资金支持 |
| 151 | +- APY 可通过治理调整 |
| 152 | + |
| 153 | +**核心函数:** |
| 154 | +```solidity |
| 155 | +function claimRewards() external; |
| 156 | +
|
| 157 | +function calculateRewards(address auditor) external view returns (uint256); |
| 158 | +``` |
| 159 | + |
| 160 | +### ISNADGovernor + TimelockController |
| 161 | + |
| 162 | +协议升级的 DAO 治理。 |
| 163 | + |
| 164 | +**特性:** |
| 165 | +- 基于 OpenZeppelin Governor 模式 |
| 166 | +- 执行前 2 天时间锁 |
| 167 | +- 4% 法定人数要求 |
| 168 | +- 提案门槛:100,000 $ISNAD |
| 169 | + |
| 170 | +**可治理参数:** |
| 171 | +- 信任等级阈值 |
| 172 | +- 锁定期限制 |
| 173 | +- 奖励池 APY |
| 174 | +- 标记保证金金额 |
| 175 | +- 合约升级 |
| 176 | + |
| 177 | +## 信任等级阈值 |
| 178 | + |
| 179 | +| 等级 | 枚举值 | 阈值 | |
| 180 | +|------|--------|------| |
| 181 | +| UNVERIFIED | 0 | 0 | |
| 182 | +| COMMUNITY | 1 | 100 $ISNAD | |
| 183 | +| VERIFIED | 2 | 1,000 $ISNAD | |
| 184 | +| TRUSTED | 3 | 10,000 $ISNAD | |
| 185 | + |
| 186 | +## 锁定期乘数 |
| 187 | + |
| 188 | +| 时长 | 乘数 | 加权分数 | |
| 189 | +|------|------|---------| |
| 190 | +| 7 天 | 1.0x | 质押量 × 1.0 | |
| 191 | +| 30 天 | 1.0x | 质押量 × 1.0 | |
| 192 | +| 60 天 | 1.25x | 质押量 × 1.25 | |
| 193 | +| 90 天 | 1.5x | 质押量 × 1.5 | |
| 194 | + |
| 195 | +## 集成示例 |
| 196 | + |
| 197 | +使用 viem: |
| 198 | + |
| 199 | +```typescript |
| 200 | +import { createPublicClient, createWalletClient, http } from 'viem'; |
| 201 | +import { baseSepolia } from 'viem/chains'; |
| 202 | +import { ISNADStakingABI, ISNADTokenABI } from '@isnad/contracts'; |
| 203 | + |
| 204 | +const STAKING_ADDRESS = '0x58983D142A388A96B7d9F970005483AA044CCAD9'; |
| 205 | +const TOKEN_ADDRESS = '0xc41c1006A1AaC093C758A2f09de16fee2561651A'; |
| 206 | + |
| 207 | +// 读取信任分数 |
| 208 | +const publicClient = createPublicClient({ |
| 209 | + chain: baseSepolia, |
| 210 | + transport: http(), |
| 211 | +}); |
| 212 | + |
| 213 | +const trustScore = await publicClient.readContract({ |
| 214 | + address: STAKING_ADDRESS, |
| 215 | + abi: ISNADStakingABI, |
| 216 | + functionName: 'getTrustScore', |
| 217 | + args: [resourceHash], |
| 218 | +}); |
| 219 | + |
| 220 | +// 质押 token(需要钱包) |
| 221 | +const walletClient = createWalletClient({ ... }); |
| 222 | + |
| 223 | +// 1. 授权 |
| 224 | +await walletClient.writeContract({ |
| 225 | + address: TOKEN_ADDRESS, |
| 226 | + abi: ISNADTokenABI, |
| 227 | + functionName: 'approve', |
| 228 | + args: [STAKING_ADDRESS, amount], |
| 229 | +}); |
| 230 | + |
| 231 | +// 2. 质押 |
| 232 | +await walletClient.writeContract({ |
| 233 | + address: STAKING_ADDRESS, |
| 234 | + abi: ISNADStakingABI, |
| 235 | + functionName: 'stake', |
| 236 | + args: [resourceHash, amount, lockDuration], |
| 237 | +}); |
| 238 | +``` |
| 239 | + |
| 240 | +## 安全性 |
| 241 | + |
| 242 | +- 所有合约使用 OpenZeppelin 库 |
| 243 | +- 已完成 Slither 静态分析 |
| 244 | +- 所有输入均有零地址检查 |
| 245 | +- 状态变更函数使用 ReentrancyGuard |
| 246 | +- 基于角色的访问控制 |
| 247 | + |
| 248 | +## 源代码 |
| 249 | + |
| 250 | +所有合约均为开源,已在 BaseScan 上验证: |
| 251 | + |
| 252 | +- GitHub:https://github.com/counterspec/isnad/tree/main/contracts |
| 253 | +- BaseScan:https://sepolia.basescan.org/address/[contract_address] |
0 commit comments