合约参考
Solana 合约定义
权威定义: 本文档是 Microcosm Solana 合约的单一真相源。
最后更新: 2026-02-02
状态: ✅ 8 个合约全部主网部署完成,Token 使用 SPL Token + Metaplex Metadata,MCC Mint Authority 已放弃 (None),MCD Mint Authority 保留
2026-02-02: 🔄 SPL Token + Metaplex 迁移完成 - MCC/MCD 从 Token-2022 切换到 SPL Token,解决 Solscan/钱包 Logo 显示问题
2026-01-30: Reincarnation 合约添加 USDT 支持 - 所有稳定币视为等价 (1 USDC = 1 USDT = 1 USD)
2026-01-29: 主网部署完成 - 8 个合约部署
2026-01-23: MCD Token 合约新增账户关闭指令 - close_user_mcd_account 支持僵尸账户租金回收
2026-01-21: MCD Token 合约新增白名单功能 - 3 个白名单管理指令 + consume_mcd 自动验证
2026-01-20: Reincarnation 合约升级完成 - 新增 execute_mining + execute_monthly_cycle 指令
一、已部署合约
1.1 合约概览
⚠️ 重要概念区分:
- Token Mint = 代币本身的账户地址,由 SPL Token 程序管理
- 业务合约 Program ID = 我们开发的 Anchor 程序(铸造/分发/消费等业务逻辑)
- 两者完全不同!Token Mint 重新部署会变,业务合约升级时 Program ID 不变
业务合约 (我们开发的 Anchor 程序)
| 合约 | Program ID | 状态 | 说明 |
|---|---|---|---|
| MCC Program | mCCUkDxoDfnVjTQjQHWkVi1PWBU2jxfQGJUhhDbeq5x | ✅ 主网运行中 (2026-01-31 重新部署) | MCC 铸造/分发业务逻辑 |
| MCD Program | McDVieuEFv5ucnM3C7p8wsT6LY8BAipKDrTG9HjAu3R | ✅ 主网运行中 | MCD 积分业务逻辑 |
| Lending | LENCJ9MYbnTrMJgh8vBLpHnMkzrj6JP6m6XWvgA7jqz | ✅ 主网运行中 | MCC 质押借贷 |
| Territory NFT | TeRxGfJEyixj1NM7bwprGoPtQ7j5PdZncQnsTZCyH17 | ✅ 主网运行中 | 领地 NFT |
| Auction | AucBs7tZhsSYqYSJrE4LEF4uMNHxq7p5mWtzU4UghQkd | ✅ 主网运行中 | 领地拍卖 |
| Level Verifier | VPt7uKujw7YrCbFasXZdS3nK3o3TbbuXJ1RYktTCsG7 | ✅ 主网运行中 | 用户等级验证 |
| Fragment | FRGBrfuzTE9vjZVKBFA4eHgqyLdg5gPsJc8gLx3bSnPv | ✅ 主网运行中 | NFT 碎片化 |
| Reincarnation | REn8oKyydvjRsistZ2cVi6tksPubvR3bEuLdVTyGknb | ✅ 主网运行中 | MCC/MCD 轮回 |
Token 层 (由 Solana 官方 SPL Token 程序管理)
| Token | Token Mint 地址 | Genesis ATA | 供应量 |
|---|---|---|---|
| MCC | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i | 10 亿 |
| MCD | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | 100 亿 |
Token Program:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA(Solana SPL Token)2026-02-02: MCC/MCD 切换到 SPL Token + Metaplex Metadata,Solscan/钱包完美支持
1.2 关键地址 (主网)
| 名称 | 地址 | 用途 |
|---|---|---|
| Genesis Authority (Mainnet) | MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A | 主网部署/升级/签名 |
| MCC Mint (Mainnet) | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | MCC 代币铸造地址 (10 亿枚,SPL Token + Metaplex) |
| MCC Genesis ATA | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i | MCC 创世池 ATA |
| MCD Mint (Mainnet) | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty | MCD 积分铸造地址 (100 亿枚,SPL Token + Metaplex) |
| MCD Genesis ATA | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | MCD 创世池 ATA |
| Reincarnation USDC Vault | ET3NjENp8TiL8KyL1zFpq1Qiyfy8vxDAcHciyXLbmrkQ | x402 支付接收地址(轮回池 USDC 金库,合约控制) |
1.3 钱包管理
主网 Authority 地址:
MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A
查询主网余额:
curl -s https://api.mainnet-beta.solana.com -X POST -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0", "id": 1,
"method": "getBalance",
"params": ["MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A"]
}' | python -c "import sys,json; d=json.load(sys.stdin); print(f'{d[\"result\"][\"value\"]/1e9:.4f} SOL')"
获取密钥:
# 主网 Authority
gcloud secrets versions access latest --secret=solana-mainnet-authority --project=double-helix-9f030
二、MCC Token 合约
2.1 基本信息 (主网 - SPL Token + Metaplex)
⚠️ 区分:MCC Program (业务合约) ≠ Token Program (Solana 官方 SPL Token)
业务合约 (我们开发的)
| 项目 | 值 |
|---|---|
| MCC Program | mCCUkDxoDfnVjTQjQHWkVi1PWBU2jxfQGJUhhDbeq5x |
| MCC Mining Config PDA | 7RB17e42pe5xY5vwe7wvwbaQDHmnahAGHThYcQt1uf1M (bump: 255) |
Token 层 (由 SPL Token 管理)
| 项目 | 值 |
|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA (SPL Token) |
| MCC Mint (主网) | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e |
| MCC Genesis ATA | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i |
| 总供应量 | 10 亿 MCC(永不增发)✅ 2026-02-02 SPL Token 重新部署 |
| Mint Authority | 已放弃 (None) ✅ 2026-02-10 确认 |
| 小数位 | 9 |
| Metadata | Metaplex Token Metadata V3 |
2026-02-02: MCC Token 切换到 SPL Token + Metaplex Metadata,全部 10 亿枚铸造到 Genesis ATA,Mint Authority 已放弃 (None)。Logo 可在 Solscan 和钱包中正常显示。
2.2 指令列表
2026-01-20 更新: 移除
initialize_user_vault和withdraw,User PDA 托管设计已废弃
| 指令 | 用途 |
|---|---|
initialize_token | MCC 代币初始化 |
initialize_mining_config | 铸造配置(减半规则) |
initialize_vaults | 团队/政务官金库 |
process_mining_payment | USDC 铸造(50-10-10-30 分配) |
admin_mining_reward | 管理员铸造奖励(基于交易盈亏) |
update_mcc_price | 更新 MCC 价格(预言机) |
set_halt_status | 设置系统停机状态 |
get_mining_stats | 查询铸造统计信息 |
cycle | MCC 轮回(x402 卖出) |
dao_create / dao_contribute | DAO 募资 |
2.3 分配规则
三、MCD Token 合约
3.1 基本信息 (主网 - SPL Token + Metaplex)
⚠️ 区分:MCD Program (业务合约) ≠ Token Program (Solana 官方 SPL Token)
业务合约 (我们开发的)
| 项目 | 值 |
|---|---|
| MCD Program | McDVieuEFv5ucnM3C7p8wsT6LY8BAipKDrTG9HjAu3R |
| MCD Config PDA | 9ru4MVNzxHM7ADgSTSYZaRNJ7JVS2mT3QXg9tZri7mYp (2026-01-31 初始化) |
Token 层 (由 SPL Token 管理)
| 项目 | 值 |
|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA (SPL Token) |
| MCD Mint (主网) | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty |
| MCD Genesis ATA | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC |
| 总供应量 | 100 亿 MCD ✅ 2026-02-02 SPL Token 重新部署 |
| Mint Authority | 保留 ✅ MCD 内部积分,保留铸造权 |
| 小数位 | 9 |
| 汇率 | 1 MCD = 1 USDC(固定) |
| Metadata | Metaplex Token Metadata V3 |
2026-02-02: MCD Token 切换到 SPL Token + Metaplex Metadata,解决 Solscan/钱包 Logo 显示问题。MCD Config PDA 已初始化完成。
3.2 关键 PDA (主网)
| PDA | 地址 | Seeds | 状态 |
|---|---|---|---|
| MCD Config | 9ru4MVNzxHM7ADgSTSYZaRNJ7JVS2mT3QXg9tZri7mYp | b"mcd_config" | ✅ 已初始化 (2026-01-31) |
| Genesis Pool | H6TjQWbch58vvj9vT4fShJH5y4YQ4SrUsDLYA3SWRnyw | b"mcd_genesis_pool" | PDA (无 Token 账户) |
| Recycle Pool | FwkEqJNZvDsbJJHnkCuwPeBvF93qQXZKr5JW52J5AJGT | b"mcd_recycle_pool" | PDA (无 Token 账户) |
| MCD Genesis ATA | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | ATA | ✅ 100 亿 MCD |
Station MCD Vault (待重新初始化)
Territory ID 规范: Station 使用
stations.id生成 Territory ID(如 S-00001),不使用units.id⚠️ 2026-02-02: MCD 切换到 SPL Token 后,Station Vault ATA 需要重新初始化
| Station ID | Territory ID | Vault PDA | Vault ATA (SPL Token) | 状态 |
|---|---|---|---|---|
| 1 | S-00001 | GayhXUqw5Esy7VGF269Vz3K75wLcLDEtu9za91YDHauG | G6vcWY4BW81HMnPeiDL1BSEUkaDDFBgZ48SKfMEWtbwe | ✅ 已初始化 (2026-02-02) |
PDA 计算公式:
# Station Vault PDA
seeds = [b"station_vault", station_id.to_le_bytes()] # station_id 是 u64
vault_pda, bump = Pubkey.find_program_address(seeds, MCD_PROGRAM_ID)
# Station Vault ATA (SPL Token)
vault_ata = get_associated_token_address(MCD_MINT, vault_pda, TOKEN_PROGRAM_ID)
3.3 PDA Seeds(重要!)
# Python 和 Rust 代码必须使用相同的 seeds
MCD_CONFIG_SEED = b"mcd_config"
MCD_GENESIS_POOL_SEED = b"mcd_genesis_pool"
MCD_RECYCLE_POOL_SEED = b"mcd_recycle_pool"
STATION_VAULT_SEED = b"station_vault" # 没有 mcd_ 前缀!
USER_MCD_SEED = b"user_mcd" # 不是 user_mcd_account!
MCD_WHITELIST_SEED = b"mcd_whitelist" # 白名单 PDA (2026-01-21 新增)
3.4 指令列表
2026-01-23 更新: 新增 close_user_mcd_account 账户关闭指令,支持僵尸账户租金回收
2026-01-21 更新: 新增白名单管理指令(add_to_whitelist, remove_from_whitelist, update_whitelist_status)
| 指令 | 用途 | 权限 |
|---|---|---|
initialize_mcd / initialize_mcd_config | 初始化 MCD Token 和配置 | 管理员 |
initialize_station_vault | Station 金库 PDA | 管理员 |
initialize_user_mcd_account | 用户 MCD PDA 账户 | 管理员 |
mint_mining_mcd | 铸造 MCD 到金库(30%) | 管理员 |
mint_genesis_supply | 铸造创世供应到 Genesis Pool | 管理员 |
distribute_daily_mcd | 每日 1% 分配给 Miner | 管理员 |
consume_mcd | MCD 消费(自动验证白名单) | 管理员 |
mcd_mining_payment | MCD 铸造支付(70% 回收,30% 铸造) | 管理员 |
close_user_mcd_account | 关闭用户 MCD 账户(租金回收) | 管理员 |
add_to_whitelist | 添加项目到白名单 | 管理员 |
remove_from_whitelist | 从白名单移除项目 | 管理员 |
update_whitelist_status | 更新白名单状态(暂停/激活) | 管理员 |
migrate_config / fix_config_bump | 合约迁移和修复 | 管理员 |
3.5 MCD 白名单机制(2026-01-21 新增)
设计目的: 确保 MCD 保持为系统控制的积分,而非自由流通的代币。
白名单 PDA 结构:
pub struct McdWhitelist {
pub project_id: u64, // 项目 ID
pub wallet_address: Pubkey, // 项目方 MCD 钱包地址
pub project_name: [u8; 64], // 项目名称(最多 64 字节)
pub registered_at: i64, // 注册时间戳
pub status: u8, // 0=active, 1=suspended
pub updated_at: i64, // 最后更新时间戳
pub bump: u8, // PDA bump
}
白名单验证流程:
- 用户调用
consume_mcd消费 MCD - 合约自动验证目标项目是否在白名单中(通过 PDA seeds 查找)
- 验证项目方钱包地址是否匹配白名单记录
- 验证项目状态是否为
active(未被暂停) - 验证通过后执行 MCD 转账(用户 PDA → 项目方钱包)
白名单管理:
- 管理员通过
add_to_whitelist添加项目,提供 project_id、wallet_address、project_name - 管理员通过
update_whitelist_status暂停(suspend)或激活(active)项目 - 管理员通过
remove_from_whitelist完全移除项目(关闭 PDA 账户)
状态常量:
pub const STATUS_ACTIVE: u8 = 0; // 激活状态,可接收 MCD
pub const STATUS_SUSPENDED: u8 = 1; // 暂停状态,拒绝 MCD 转账
3.6 账户关闭与租金回收(2026-01-23 新增)
设计目的: 关闭僵尸 MCD 账户,回收链上 SOL 租金到 Genesis Authority。
3.6.1 close_user_mcd_account 指令
pub fn close_user_mcd_account(ctx: Context<CloseUserMcdAccount>) -> Result<()> {
// 1. 验证 Token Account 余额为 0
// 2. 关闭 User Token Account (ATA),租金返回 rent_receiver
// 3. 关闭 UserMcdAccount PDA,租金返回 rent_receiver
}
#[derive(Accounts)]
pub struct CloseUserMcdAccount<'info> {
#[account(mut)]
pub authority: Signer<'info>, // MCD 管理员
#[account(
mut,
seeds = [USER_MCD_SEED, &user_mcd_account.uid.to_le_bytes()],
bump,
close = rent_receiver
)]
pub user_mcd_account: Account<'info, UserMcdAccount>,
#[account(
mut,
associated_token::mint = mcd_mint,
associated_token::authority = user_mcd_account,
constraint = user_token_account.amount == 0 @ McdError::AccountNotEmpty
)]
pub user_token_account: Account<'info, TokenAccount>,
/// CHECK: rent_receiver 接收回收的租金 (Genesis Authority)
#[account(mut)]
pub rent_receiver: AccountInfo<'info>,
pub mcd_mint: Account<'info, Mint>,
pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
}
3.6.2 账户租金明细
| 账户类型 | 大小 | 租金 (SOL) |
|---|---|---|
| User Token Account (ATA) | 165 bytes | ~0.00203928 |
| UserMcdAccount PDA | ~72 bytes | ~0.00089 |
| 合计 | ~0.00293 |
3.6.3 僵尸账户判定条件
管理员可关闭同时满足以下条件的账户:
- MCD 余额 = 0
- 未加入任何 Station (
station_id IS NULL) - 超过 180 天未登录
3.6.4 租金回收地址
Genesis Authority: Gq8ubUZwFrBgscZjerWHZCTYXXFMN2b8W6kRyaKMQYJo
3.6.5 安全约束
- 只有 MCD 管理员 (authority) 可以执行关闭
- 只能关闭余额为 0 的账户(合约强制校验)
- 所有关闭操作记录到数据库(mcd_account_closures 表)
3.6.6 链上租金验证机制(2026-01-24 新增)
设计目的: 确保数据库记录的租金与链上实际回收金额一致,避免预估值与实际值不符。
验证流程:
- 查询 Authority SOL 余额 (balance_before)
- 执行 close_user_mcd_account 交易
- 查询 Authority SOL 余额 (balance_after)
- 计算实际回收租金 = balance_after - balance_before
- 将实际值写入数据库(非预估值)
Python 实现:
# mcd_solana_client.py
async def close_user_mcd_account(self, uid: int) -> dict:
# 🔍 链上验证 Step 1: 记录关闭前 Authority 余额
balance_before = await self.solana_client.get_balance(self.authority.pubkey())
# 构建并发送关闭交易...
signature = await self.solana_client.send_transaction(tx, self.authority)
await self.solana_client.confirm_transaction(signature)
# 🔍 链上验证 Step 2: 记录关闭后 Authority 余额
balance_after = await self.solana_client.get_balance(self.authority.pubkey())
# 🔍 链上验证 Step 3: 计算实际回收租金
rent_recovered_lamports = balance_after - balance_before
rent_recovered_sol = rent_recovered_lamports / 1e9
return {
'signature': str(signature),
'rent_recovered_lamports': rent_recovered_lamports,
'rent_recovered_sol': rent_recovered_sol
}
降级策略:
| 场景 | 处理方式 |
|---|---|
| 链上验证成功 | 使用实际回收值 rent_recovered_sol |
| 链上验证失败(RPC 错误等) | 使用预估值 0.00361 SOL 作为降级 |
| 余额差值为负或异常 | 记录警告日志,使用预估值 |
为什么预估值是 0.00361 而不是 0.00293:
- 理论计算值: Token Account (~0.00204) + PDA (~0.00089) = ~0.00293 SOL
- 实际测试值: 0.00361 SOL(包含链上交易的额外租金返还)
- 链上验证确保使用实际值,预估值仅作为降级兜底
3.6.7 后端 API
| 端点 | 方法 | 功能 |
|---|---|---|
/api/mcd/admin/zombie-accounts | GET | 获取僵尸账户列表 |
/api/mcd/admin/close-account/{uid} | POST | 关闭单个账户 |
/api/mcd/admin/batch-close-accounts | POST | 批量关闭账户 |
/api/mcd/admin/rent-statistics | GET | 获取租金统计 |
/api/mcd/admin/closure-history | GET | 获取关闭历史 |
四、Lending 合约
4.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | 5JRnecaAZNfF1bBjdW93JB8VFJVpWWDkR3NKg2jHnMPQ |
| ProgramData | FksPZc5UTYfMCf8PiHgi4E5D7R8FAoN644vfsSGxMhw8 |
| 合约大小 | 451 KB |
| 部署费用 | 3.21 SOL |
4.2 已初始化账户(2026-01-15)
| 账户 | 地址 | 类型 |
|---|---|---|
| Lending Pool | 9qyYsbHebyxLMQmgLmfPdP74vESvUSv7xxhDajoH4HE4 | PDA |
| LP Mint | 144sJixjMTdJrKFVrdZBQSSqeorxEvkr2dZGUxV3Nnsm | PDA |
| Vault | 8NGHVECRLyhWYFmyT332uPfFFEy2P5Sd3TvPQojXP5sN | ATA |
| NFT Oracle | Fqu5YMqRmq5ckWn1x4kjtHxGq5DMWsGTai3VkaxHnKKk | PDA |
4.3 PDA Seeds
const LENDING_POOL_SEED = "mcc_lending_pool";
const LP_MINT_SEED = "mcc_lp_mint";
const NFT_PRICE_ORACLE_SEED = "nft_price_oracle";
// Vault 是 ATA,不使用 seeds
4.4 Vault 地址计算(重要!)
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
// Vault 是 ATA,不是自定义 PDA!
// allowOwnerOffCurve = true,因为 owner 是 PDA
const vault = getAssociatedTokenAddressSync(MCC_MINT, lendingPool, true);
4.5 初始化参数
{
pool_name: "mcc-lending-pool",
base_rate: 1000, // 10% APR
optimal_utilization: 8000, // 80%
slope1: 1000, // 10%
slope2: 8000, // 80%
}
4.6 贷款规则
| 规则 | 值 |
|---|---|
| 支持资产 | 只支持 MCC(不支持 USDC) |
| LTV | 100% |
| 最高 APR | 100% |
| 清算条件 | 连续 3 次未还款 |
4.7 指令 Discriminator(已验证)
const DISCRIMINATORS = {
initializeLendingPool: [236, 76, 136, 68, 196, 14, 9, 177],
initializeLpMint: [205, 250, 9, 201, 188, 220, 164, 60], // IDL 自动生成值错误!
initializeVault: [48, 191, 163, 44, 71, 129, 63, 164],
initializeNftOracle: [6, 80, 1, 161, 115, 198, 249, 112],
};
4.8 后端集成状态(2026-01-16)
| 组件 | 文件 | 状态 |
|---|---|---|
| Solana Client | blockchain-service/app/utils/lending_client.py | ✅ 已实现 |
| Service Layer | blockchain-service/app/services/lending_service.py | ✅ 已实现 |
| API Routes | blockchain-service/app/routes/lending.py | ✅ 已实现 |
| Proxy Routes | organization-service/app/routes/organizations/lending.py | ✅ 已实现 |
| 前端 API | portal-service/lib/api/services.ts | ✅ 已实现 |
| Open API | open-api-service/fastapi_app/routers/lending.py | ✅ 已实现 |
API 端点:
| 端点 | 方法 | 说明 |
|---|---|---|
/api/lending/pool | GET | 获取借贷池配置 |
/api/lending/stats | GET | 获取借贷池统计 |
/api/lending/position/<wallet> | GET | 获取用户仓位 |
/api/lending/loans/<wallet> | GET | 获取用户贷款列表 |
/api/lending/loan/<wallet>/<id> | GET | 获取贷款详情 |
/api/lending/lp-balance/<wallet> | GET | 获取 LP 余额 |
/api/lending/calculate-interest | POST | 计算利息 |
/api/lending/estimate-borrow-cost | POST | 估算借款成本 |
/api/lending/deposit/prepare | POST | 准备存款交易 |
/api/lending/withdraw/prepare | POST | 准备取款交易 |
/api/lending/borrow/prepare | POST | 准备借款交易 |
/api/lending/repay/prepare | POST | 准备还款交易 |
/api/lending/liquidate/prepare | POST | 准备清算交易 |
Open API 端点 (/v1/lending):
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/lending/pool | GET | 获取借贷池配置 |
/v1/lending/stats | GET | 获取借贷池统计 |
/v1/lending/position/{wallet} | GET | 获取用户仓位 |
/v1/lending/loans/{wallet} | GET | 获取用户贷款列表 |
/v1/lending/loan/{wallet}/{loan_id} | GET | 获取贷款详情 |
/v1/lending/lp-balance/{wallet} | GET | 获取 LP 余额 |
/v1/lending/calculate-interest | POST | 计算利息 |
/v1/lending/estimate-borrow-cost | POST | 估算借款成本 |
五、构建与部署规范
5.1 版本要求
| 组件 | 版本 | 备注 |
|---|---|---|
| Solana CLI | 3.0.10 | Anza 发行版 |
| Anchor CLI | 0.30.1 | cargo 安装 |
| Rust | 1.86+ | 系统 Rust |
5.2 Cargo.toml 必须配置
[dependencies]
anchor-lang = { version = "0.30.1", features = ["init-if-needed"] }
anchor-spl = { version = "0.30.1", features = ["token", "associated_token", "metadata"] }
# 关键!固定 blake3 版本避免 edition2024 问题
blake3 = "=1.7.0"
5.3 Cloud Build 命令
必须使用
--region=asia-northeast1,禁止使用 global 区域!
# 构建
gcloud builds submit --config=cloudbuild.yaml --project=double-helix-9f030 --region=asia-northeast1
# 部署
gcloud builds submit --config=cloudbuild-deploy.yaml --project=double-helix-9f030 --region=asia-northeast1
5.4 密钥管理
所有密钥存储在 GCP Secret Manager:
| Secret | 用途 |
|---|---|
solana-genesis-keypair | Authority(部署/升级) |
solana-lending-keypair | Lending Program ID |
solana-territory-nft-keypair | Territory NFT Program ID |
solana-auction-keypair | Auction Program ID |
solana-level-verifier-keypair | Level Verifier Program ID |
# 获取密钥
gcloud secrets versions access latest --secret=solana-genesis-keypair --project=double-helix-9f030
六、已知问题与解决方案
6.1 Anchor 0.30.1 TypeScript 客户端 Bug
问题: 使用 program.methods.xxx().accounts().rpc() 初始化 PDA 时出现 "writable privilege escalated" 错误。
解决方案: 绕过 Anchor 客户端,使用原生 TransactionInstruction:
const ix = new TransactionInstruction({
keys: [
{ pubkey: authority.publicKey, isSigner: true, isWritable: true },
{ pubkey: lendingPool, isSigner: false, isWritable: true },
{ pubkey: MCC_MINT, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
programId: PROGRAM_ID,
data: Buffer.concat([discriminator, ...args]),
});
6.2 IDL Discriminator 不正确
问题: anchor build 生成的 IDL 中 discriminator 可能错误。
解决方案: 手动计算验证:
const crypto = require('crypto');
const hash = crypto.createHash('sha256');
hash.update('global:initialize_lp_mint'); // snake_case
const discriminator = [...hash.digest().slice(0, 8)];
// [205, 250, 9, 201, 188, 220, 164, 60]
6.3 edition2024 兼容性
问题: blake3 >= 1.8 需要 edition2024,但 Solana platform-tools 的 Cargo 是 1.84。
解决方案: 在 Cargo.toml 中固定 blake3 = "=1.7.0"。
七、Territory NFT 合约
7.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | ipYLo2aitVyNXGzCgpiaKKA2JLvtbBvMHiV7qKZTPVZ |
| ProgramData | Gsnqy6dxni66faY52J7Q6tGGijn6wrA1fY4F78g2Hfex |
| 合约大小 | ~490 KB |
| 部署费用 | ~3.5 SOL |
7.2 已初始化账户(2026-01-16)
| 账户 | 地址 | 类型 |
|---|---|---|
| Collection Config | Fy3mbmJCgDXvhHzQhm7gMAGgNpvPXLXNs7nBnaaAgkVQ | PDA |
| Collection Mint | BvV8jWSkLfw7GQthdrsqF6DZm91aVDbcEbpDWYNP88ST | Keypair |
| Collection Token Account | 7NH3fokZ3v9RRqFeeh9juq4YCjEfWatFC8MUdc7VxRfh | Keypair |
| Collection Metadata | FGAJFhEmYCicDdk2teMbcxYdKJ2MsjaSc9DEwSic3PB9 | Metaplex PDA |
| Collection Master Edition | Hn8HJYERA6foCRuw2vxpVCNaYFWdxXbXZtpAswMHxvfW | Metaplex PDA |
7.3 PDA Seeds
const COLLECTION_SEED = "territory_collection";
const TERRITORY_NFT_SEED = "territory_nft";
7.4 指令列表
| 指令 | 用途 | Discriminator |
|---|---|---|
initialize_config | Step 1: 创建 Collection Config PDA | [208, 127, 21, 1, 194, 190, 196, 70] |
initialize_collection_nft | Step 2: 创建 mint/metadata/edition | [232, 111, 94, 240, 74, 97, 50, 238] |
mint_station_nft | 铸造 Station NFT | - |
mint_matrix_nft | 铸造 Matrix NFT | - |
mint_sector_nft | 铸造 Sector NFT | - |
mint_system_nft | 铸造 System NFT | - |
transfer_nft | 转移 NFT 所有权 | - |
burn_nft | 销毁 NFT | - |
7.5 领地 NFT 类型
| 类型 | 代码 | 容量 | 说明 |
|---|---|---|---|
| Station | 0 | 1000 用户 | 最基础的领地单元 |
| Matrix | 1 | 10 Station | 由 10 个 Station 组成 |
| Sector | 2 | 10 Matrix | 由 10 个 Matrix 组成 |
| System | 3 | 10 Sector | 由 10 个 Sector 组成 |
7.6 栈溢出问题与解决方案
问题: 在 Devnet/Mainnet 上执行 InitializeCollection 时出现 Access violation in stack frame 错误。
原因: Solana 程序栈限制 4KB,多个 init 约束 + CPI 调用导致栈溢出。特性 EenyoWx9UMXYKpR8mW5Jmfmy2fRjzUtM7NduYMY8bx33 在 devnet/mainnet 未启用。
解决方案:
- 将初始化拆分为两步(
initialize_config+initialize_collection_nft) - 使用
Box<Account<>>将账户移到堆上 - 使用
#[inline(never)]将 CPI 调用拆分到独立函数
7.7 后端集成状态(2026-01-16)
| 组件 | 文件 | 状态 |
|---|---|---|
| Solana 客户端 | blockchain-service/app/utils/territory_nft_client.py | ✅ 完成 |
| 业务服务层 | blockchain-service/app/services/territory_service.py | ✅ 完成 |
| API 路由 | blockchain-service/app/routes/territory.py | ✅ 完成 |
| 代理路由 | organization-service/app/routes/organizations/territory.py | ✅ 完成 |
| 前端 API | portal-service/lib/api/services.ts | ✅ 完成 |
| Open API | open-api-service/fastapi_app/routers/territory.py | ✅ 完成 |
API 端点:
GET /api/territory/config- 获取 Collection 配置GET /api/territory/holdings/<wallet>- 获取 NFT 持有量GET /api/territory/nft/<mint>- 获取 NFT 详情GET /api/territory/list/<wallet>- 获取用户 NFT 列表POST /api/territory/mint- 铸造 NFT [管理员]POST /api/territory/transfer/prepare- 准备 NFT 转移POST /api/territory/burn/prepare- 准备 NFT 销毁
Open API 端点 (/v1/territory):
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/territory/collection | GET | 获取 Collection 配置 |
/v1/territory/nft/{mint} | GET | 获取 NFT 元数据 |
/v1/territory/nfts/{wallet} | GET | 获取用户 NFT 列表 |
/v1/territory/unit/{unit_id}/nft | GET | 获取领地关联 NFT |
八、Auction 合约
8.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | 6JRmShodszZca3ez7GfDkmsRSzTi5ELwscWCDgjsteJx |
| ProgramData | 3ji7ahcBepzeyntEFwnSMaHC7uFKg1C285i2uLWzgTF1 |
| 合约大小 | ~347 KB |
| 部署费用 | ~2.47 SOL |
8.2 已初始化账户(2026-01-16)
| 账户 | 地址 | 类型 |
|---|---|---|
| Auction Config | 32h5ZUhd4cqAw42JQqy8geWz44MGpgbX9pdykRP8LyhJ | PDA |
8.3 PDA Seeds
const AUCTION_CONFIG_SEED = "auction_config";
const AUCTION_SEED = "auction";
const BID_SEED = "bid";
const MCC_ESCROW_SEED = "mcc_escrow";
8.4 初始化参数
{
min_bid_increment_percent: 5, // 5%
auction_duration: 604800, // 7 天
extension_duration: 600, // 10 分钟
extension_threshold: 300, // 5 分钟
}
8.5 指令列表
| 指令 | 用途 | Discriminator |
|---|---|---|
initialize_auction_config | 初始化拍卖配置 | [94, 1, 96, 31, 46, 102, 88, 102] |
create_auction | 创建拍卖 | - |
place_bid | 出价(托管 MCC) | - |
cancel_bid | 取消出价(退还 MCC) | - |
complete_auction | 结算拍卖 | - |
cancel_auction | 取消拍卖 | - |
8.6 收益分配规则
| 拍卖类型 | 收益归属 |
|---|---|
| 首拍(First) | 100% 团队 |
| 二拍(Secondary) | 100% 原政务官 |
8.7 后端集成状态(2026-01-16)
| 组件 | 文件 | 状态 |
|---|---|---|
| Solana Client | blockchain-service/app/utils/auction_client.py | ✅ 已实现 |
| Service Layer | blockchain-service/app/services/auction_solana_service.py | ✅ 已实现 |
| API Routes | blockchain-service/app/routes/auction_solana.py | ✅ 已实现 |
| Proxy Routes | organization-service/app/routes/organizations/auction_solana.py | ✅ 已实现 |
| 前端 API | portal-service/lib/api/services.ts | ✅ 已实现 |
| Open API | open-api-service/fastapi_app/routers/auction_solana.py | ✅ 已实现 |
API 端点:
| 端点 | 方法 | 说明 |
|---|---|---|
/api/auction-solana/config | GET | 获取拍卖配置 |
/api/auction-solana/active | GET | 获取活跃拍卖列表 |
/api/auction-solana/<id> | GET | 获取拍卖详情 |
/api/auction-solana/<id>/bids | GET | 获取出价列表 |
/api/auction-solana/create | POST | 创建拍卖 [管理员] |
/api/auction-solana/bid/prepare | POST | 准备出价交易 |
/api/auction-solana/<id>/complete | POST | 结算拍卖 [管理员] |
/api/auction-solana/<id>/cancel | POST | 取消拍卖 [管理员] |
Open API 端点 (/v1/auction-solana):
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/auction-solana/config | GET | 获取拍卖配置 |
/v1/auction-solana/active | GET | 获取活跃拍卖列表 |
/v1/auction-solana/auction/{auction_id} | GET | 获取拍卖详情 |
/v1/auction-solana/auction/{auction_id}/bids | GET | 获取竞价历史 |
/v1/auction-solana/bids/{wallet} | GET | 获取用户竞价记录 |
/v1/auction-solana/auctions/{wallet} | GET | 获取用户创建的拍卖 |
九、Level Verifier 合约
9.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | 8TSuNuR1Carh8GpjqrZiVo3oz1nC2K9FSy6BhqbWb3ek |
| ProgramData | 9H8tZdrfbuJ5LBYoZiiNNdCptjGnh3Qv1QJuq26knmXu |
| 合约大小 | ~302 KB |
| 部署费用 | ~2.15 SOL |
9.2 已初始化账户(2026-01-16)
| 账户 | 地址 | 类型 |
|---|---|---|
| Verifier Config | EF3sYSzXeWEHPjquTX3GaqiRpFn8VGWfNvEwzfZZGBEG | PDA |
9.3 PDA Seeds
const VERIFIER_CONFIG_SEED = "verifier_config";
const USER_PROFILE_SEED = "user_profile";
const MINING_RECORD_SEED = "mining_record";
9.4 初始化参数
{
territory_nft_program: "ipYLo2aitVyNXGzCgpiaKKA2JLvtbBvMHiV7qKZTPVZ", // Territory NFT 合约
mcc_token_program: "FDRy2jpKqXD5pp8Xj2arEbEm78nCEcRnKCmGxBTiFWxr", // MCC Token 合约
}
9.5 指令列表
| 指令 | 用途 | 说明 |
|---|---|---|
initialize_config | 初始化验证器配置 | 管理员执行一次 |
update_config | 更新验证器配置 | 管理员可更新程序地址 |
initialize_user_profile | 创建用户档案 | 用户注册时调用 |
bind_wallet | 绑定钱包 | Recruit → Prospect |
record_mining_day | 记录铸造日 | CronJob 调用 |
verify_miner_upgrade | 验证 Miner 升级 | ≥21 天铸造 |
verify_commander_upgrade | 验证 Commander 升级 | ≥1 Station NFT |
verify_pioneer_upgrade | 验证 Pioneer 升级 | ≥10 Station NFT |
verify_warden_upgrade | 验证 Warden 升级 | ≥10 Matrix NFT |
verify_admiral_upgrade | 验证 Admiral 升级 | ≥10 Sector NFT |
check_level_demotion | 检查降级 | NFT 转让后 |
9.6 用户级别体系
| 级别 | 英文 | 升级条件 | 验证方式 |
|---|---|---|---|
| 1 | Recruit | 注册账户 | 链下 |
| 2 | Prospect | 绑定钱包 + 开始铸造 | 链上 |
| 3 | Miner | 30天内铸造 ≥21天 | 链上 |
| 4 | Commander | ≥1 Station NFT | 链上 |
| 5 | Pioneer | ≥10 Station NFT | 链上 |
| 6 | Warden | ≥10 Matrix NFT | 链上 |
| 7 | Admiral | ≥10 Sector NFT | 链上 |
9.7 后端集成 (2026-01-16 完成)
服务版本:
| 服务 | 版本 | 说明 |
|---|---|---|
| blockchain-service | v1.2.3 | Level API + async 修复 |
| organization-service | v2.1.20 | Level 代理层 |
API 端点 (organization-service):
| 端点 | 方法 | 功能 |
|---|---|---|
/level/config | GET | 获取验证器配置 |
/level/profile/<wallet> | GET | 获取用户链上档案 |
/level/status/{uid} | GET | 获取用户等级状态 |
/level/init | POST | 初始化链上档案 |
/level/upgrade | POST | 请求等级升级 |
/level/sync | POST | 同步链上等级 |
CronJob: k8s/level-sync-cronjob.yaml
- 执行时间: UTC 00:20 (每日)
- 功能: 记录铸造日、检查降级、同步等级
十、Fragment 合约
10.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | J7wyftDtfzqn2pbpLr8QPqKQkAxecgVze75SUz9D4Fq3 |
| 合约大小 | ~497 KB |
| 部署费用 | ~3.5 SOL |
10.2 已初始化账户(2026-01-16)
| 账户 | 地址 | 类型 |
|---|---|---|
| Fragment Config | 4bihhgqevyvTpBN5A73JyD2jxMQbbw3JGejtCpNzkzKV | PDA |
10.3 PDA Seeds
const FRAGMENT_CONFIG_SEED = "fragment_config";
const FRAGMENT_VAULT_SEED = "fragment_vault";
const FRAGMENT_MINT_SEED = "fragment_mint";
const BUYOUT_SEED = "buyout";
const BUYOUT_VAULT_SEED = "buyout_vault";
10.4 初始化参数(默认值)
{
min_fragments: 100, // 最小碎片数量
max_fragments: 10000, // 最大碎片数量
buyout_duration: 604800, // 买断期限: 7天
}
10.5 指令列表
| 指令 | 用途 | 说明 |
|---|---|---|
initialize_config | 初始化协议配置 | 管理员执行一次 |
fragmentize_nft | 碎片化 NFT | 将 NFT 拆分成碎片代币 |
redeem_nft | 赎回 NFT | 需持有所有碎片 |
transfer_fragments | 转让碎片 | 碎片自由流通 |
initiate_buyout | 发起买断 | 设置每碎片价格 |
accept_buyout | 接受买断 | 出售碎片给买家 |
complete_buyout | 完成买断 | 买家收集所有碎片后 |
cancel_buyout | 取消买断 | 仅发起者可执行 |
update_config | 更新配置 | 管理员操作 |
10.6 碎片化流程
1. NFT 拥有者调用 fragmentize_nft
↓
2. 创建 Fragment Vault(托管 NFT)
↓
3. 创建 Fragment Mint(碎片代币)
↓
4. 铸造碎片代币到拥有者账户
↓
5. 碎片可自由交易
↓
6. 收集所有碎片后调用 redeem_nft 赎回原 NFT
10.7 买断机制
| 阶段 | 说明 |
|---|---|
| 发起 | 持有者设置每碎片价格,创建 Buyout 账户 |
| 接受 | 其他持有者可选择出售碎片获取 USDC |
| 完成 | 买家收集所有碎片后获得 NFT |
| 取消 | 发起者可取消,退还已支付款项 |
10.8 后端集成状态(2026-01-16)
| 组件 | 文件 | 状态 |
|---|---|---|
| Solana Client | blockchain-service/app/utils/fragment_client.py | ✅ 已实现 |
| Service Layer | blockchain-service/app/services/fragment_service.py | ✅ 已实现 |
| API Routes | blockchain-service/app/routes/fragment.py | ✅ 已实现 |
| Proxy Routes | organization-service/app/routes/organizations/fragment.py | ✅ 已实现 |
| 前端 API | portal-service/lib/api/services.ts | ✅ 已实现 |
| Open API | open-api-service/fastapi_app/routers/fragment.py | ✅ 已实现 |
API 端点:
| 端点 | 方法 | 说明 |
|---|---|---|
/api/fragment/config | GET | 获取碎片化协议配置 |
/api/fragment/vault/<nft_mint> | GET | 获取碎片化金库 |
/api/fragment/balance/<wallet>/<nft_mint> | GET | 获取碎片余额 |
/api/fragment/buyout/<nft_mint>/<initiator> | GET | 获取买断请求 |
/api/fragment/fragmentize/prepare | POST | 准备碎片化交易 |
/api/fragment/redeem/prepare | POST | 准备赎回交易 |
/api/fragment/buyout/initiate/prepare | POST | 准备发起买断 |
/api/fragment/buyout/accept/prepare | POST | 准备接受买断 |
/api/fragment/buyout/complete/prepare | POST | 准备完成买断 |
/api/fragment/buyout/cancel/prepare | POST | 准备取消买断 |
Open API 端点 (/v1/fragment):
| 端点 | 方法 | 说明 |
|---|---|---|
/v1/fragment/config | GET | 获取 Fragment 配置 |
/v1/fragment/vaults | GET | 获取所有 Vault |
/v1/fragment/vault/{vault_id} | GET | 获取 Vault 详情 |
/v1/fragment/vault/{vault_id}/holders | GET | 获取 Vault 持仓分布 |
/v1/fragment/holdings/{wallet} | GET | 获取用户 Fragment 持仓 |
十一、Reincarnation 合约(轮回/回购)
2026-02-02 迁移: MCC/MCD 切换到 SPL Token,Vault 已重新初始化,使用 InterfaceAccount 和 TokenInterface 支持双标准
2026-01-30 升级: 添加 USDT 铸造支持,所有稳定币视为等价 (1 USDC = 1 USDT = 1 USD)
2026-01-29 主网部署: 合约已部署到主网,Pool 和 Vaults 已初始化完成
2026-01-20 升级: 新增
execute_mining和execute_monthly_cycle指令,实现铸造分发和月度轮回功能
11.1 基本信息
| 项目 | 值 |
|---|---|
| Program ID | REn8oKyydvjRsistZ2cVi6tksPubvR3bEuLdVTyGknb |
| 状态 | ✅ 主网运行中 |
| 代码路径 | solana-contracts/reincarnation/ |
| 初始部署 | 2026-01-19 (Devnet) |
| 主网部署 | 2026-01-29 |
11.1.1 已初始化账户 (主网)
2026-01-30 更新: 添加 USDT Vault 支持
2026-01-29 主网部署完成: Pool 和所有 Vaults 已初始化。
| 账户 | 地址 | 类型 |
|---|---|---|
| Program ID | REn8oKyydvjRsistZ2cVi6tksPubvR3bEuLdVTyGknb | Upgradeable |
| Reincarnation Pool | H3azAs4vdPKa1zVJ74dkGyUtNzpobE8fDKAn4BmZ26it | PDA (bump: 255) |
| USDC Vault | ET3NjENp8TiL8KyL1zFpq1Qiyfy8vxDAcHciyXLbmrkQ | ATA |
| USDT Vault | AVCMbMqcsUZQXiTbvSbX2nrrDfpcyT2Kb1xrxAPkxfA | ATA (2026-01-30 初始化完成) |
| MCC Vault | DhS2L2ga55iaMHbk3VAPYr43HaQv4Q8ft2eXYkdkofWj | ATA (SPL Token, 2026-02-02 迁移) |
| MCD Vault | 2hG2FsxRSEdiZdq86p9NMA9XxWvsEBx1DL3NT6d9eEHo | ATA (SPL Token, 2026-02-02 迁移) |
| Authority | MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A | Mainnet Authority |
11.1.2 支持的稳定币 (2026-01-30 新增)
| 稳定币 | Mint 地址 | Vault 地址 | 状态 |
|---|---|---|---|
| USDC | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | ET3NjENp8TiL8KyL1zFpq1Qiyfy8vxDAcHciyXLbmrkQ | ✅ 可用 |
| USDT | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB | AVCMbMqcsUZQXiTbvSbX2nrrDfpcyT2Kb1xrxAPkxfA | ✅ 可用 |
设计原则: 所有稳定币视为等价 (1 USDC = 1 USDT = 1 USD),
base_price代表 MCC 的美元价格
11.1.3 初始化参数 (主网)
| 参数 | 值 | 说明 |
|---|---|---|
pool_name | MCC Reincarnation Pool | 池名称 |
base_price | 1,000,000 | 1 USDC (6 decimals) |
premium_bps | 500 | 5% 溢价 |
daily_limit | 100,000,000,000 | 100,000 USDC 每日限额 |
11.1.4 硬编码创世地址 (constants.rs - 主网)
2026-02-02 更新: MCC/MCD 切换到 SPL Token + Metaplex,Genesis ATA 地址已更新
| 常量 | 地址 | 说明 |
|---|---|---|
MCC_GENESIS_AUTHORITY | MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A | 主网 Authority,铸造分发 + 月度轮回接收 |
MCC_MINT | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | MCC Token Mint (SPL Token) |
MCC_GENESIS_ATA | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i | MCC 创世池 ATA (主网) |
MCD_GENESIS_POOL | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | MCD 创世池 ATA (主网) |
安全设计: 创世地址硬编码在合约常量中,编译后不可修改,防止资金被转移到错误地址
11.2 功能概述
轮回合约(Reincarnation)是 MCC 回购协议的链上实现:
- 核心功能: 用户使用 MCC 换取 USDC(回购)
- 回购价格:
base_price × 1.05(+5% 溢价) - 价格来源: 预言机服务(Oracle)
- MCC 处理: 回购的 MCC 进入 burn vault,后续可销毁
11.2.1 价格架构
价格数据流向:
- 价格来源层: 市场价格 (Pyth/Raydium) [优先级1] / 管理员价格 (Open API) [优先级2]
- 预言机服务 (每4小时): 计算 30天 x 4小时收盘价均值 (180数据点),调用 contract.update_price(base_price)
- Reincarnation 合约 (价格唯一真实来源): 存储 base_price, premium_bps=500 (5%),计算 buyback_price = base_price x 1.05
- 下游消费者:
- 数据库缓存 (每小时同步): 用途为前端展示,非交易用途
- 用户回购 (x402实时): 直接从合约读取价格,钱包签名执行交易
核心原则:
- 合约是价格的唯一真实来源 (Single Source of Truth)
- 轮回合约不关心价格来源,只认预言机
- 用户交易从合约读取价格,不从数据库
预言机价格来源优先级:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1 | 市场价格 (Pyth/Raydium) | MCC 上线 DEX 后可用 |
| 2 | 管理员价格 (Open API) | 当前阶段主要来源 |
| 3 | 默认价格 (10 USDC) | 兜底价格 |
更新频率:
| 组件 | 更新频率 | 触发方式 |
|---|---|---|
| 预言机服务 | 每 4 小时 | 定时任务 |
| 合约价格 | 预言机更新后 立即 | 预言机调用 update_price |
| 数据库缓存 | 每小时 | CronJob 从合约同步 |
| 用户交易 | 实时 | 直接从合约读取 |
11.3 PDA Seeds
const REINCARNATION_POOL_SEED = "reincarnation_pool";
const USDC_VAULT_SEED = "usdc_vault";
const MCC_BURN_VAULT_SEED = "mcc_burn_vault";
const BUYBACK_RECORD_SEED = "buyback_record";
11.4 指令列表
| 指令 | 用途 | 说明 |
|---|---|---|
initialize_pool | Step 1: 初始化轮回池配置 | 创建 PDA,设置价格/溢价/限额 |
initialize_vaults | Step 2: 初始化金库 | 创建 USDC/MCC vault ATA |
execute_buyback | 执行回购 | 用户 MCC → USDC |
execute_mining | ✅ 执行铸造分发 | 50-10-10-30 分发 (2026-01-20 新增) |
execute_monthly_cycle | ✅ 月度轮回 | 每月1日转回创世地址 (2026-01-20 新增) |
update_price | 更新基础价格 | 管理员/Oracle 调用 |
withdraw_usdc | 提取 USDC | 管理员提取流动性 |
pause_pool | 暂停池 | 暂停回购功能 |
unpause_pool | 恢复池 | 恢复回购功能 |
close_old_vault_ata | ✅ 关闭旧 Vault ATA | 回收废弃 Token-2022 ATA 租金 (2026-02-02 新增) |
11.4.1 execute_mining 指令详情
用途: 执行铸造 MCC/MCD 分发
分配比例 (50-10-10-30):
- 50% MCC → 用户外部钱包 ATA
- 10% MCC → Team Vault
- 10% MCC → 4级政务官代管钱包 (4%+3%+2%+1%)
- 30% MCD → Station Vault
MCC 分发目标地址 (Mainnet - 2026-02-02 SPL Token 更新):
| 名称 | 钱包地址 | MCC ATA (SPL Token) | 比例 |
|---|---|---|---|
| Team Vault | 4HenU6EH44Kdxq6jnjU3w5mTTtwC8VHzdZkGiKKMEPWh | AkcGSBr23ZuYvca89cgAmADJFgZ9cRQJVZSfX69oMago | 10% |
| team_station | 5uo1HYjQXokE9UAd8UYiwAKomL5WACqpQMbV2Ftk7pXx | 8wJD1bpkh1MiqHskkA1Bp7FTDiFKARd1dibNDiU9sPST | 4% |
| team_matrix | 7GptS1XqVjmkBhVrUXUDQV7293NZKbNf8SQ5Lk5JLCJD | 8AnVXYf7WvgF6VDgDcwpYCh8JN8QfDNaYQ2NERGpXwwf | 3% |
| team_sector | 5Lq2sx4FLsMANijGkn19twNKmyLrnmzeoxYbyBB3r82x | GiLe4n2Eo89tzQYkuQHaTMRunbR4wxBxy1MAM3vMi1xR | 2% |
| team_system | 3HwYuVB4F5KVjQeCXoruSUiuu6G8qCdmkE4NsyMMQfFo | 4v6WbmsKCQLQDh19g7qjtneUh3XQjtTrz6xaT4tRLtD4 | 1% |
注意: 4级政务官使用独立代管钱包,便于未来政务官拍卖后资金追溯和转移。
首次拍卖收款钱包 (2026-01-24 新增):
| 用途 | 钱包名称 | 钱包地址 |
|---|---|---|
| 首次领地拍卖收款 | team_auction | Ggga8grwEneqn2gFHmDFkHqkFydyzabHzHNoSJpWKZ6b |
账户参数:
pub struct ExecuteMining<'info> {
pub authority: Signer<'info>, // Genesis Authority 签名
pub reincarnation_pool: Account<'info>, // Pool PDA
pub user_mcc_account: Account<'info>, // 用户外部钱包 ATA
pub team_vault: Account<'info>, // Team Vault
pub magistrate_pool: Account<'info>, // Magistrate Pool
pub station_vault: Account<'info>, // Station MCD Vault
pub mcc_genesis_ata: Account<'info>, // MCC 创世 ATA
pub mcd_genesis_pool: Account<'info>, // MCD 创世池
pub token_program: Program<'info>,
}
11.4.2 execute_monthly_cycle 指令详情
用途: 月度轮回 - 将 MCC/MCD Vault 中的余额转回创世地址
执行条件:
- 只有 authority 可以调用
- 合约内校验:只允许每月 1 日执行
- 防重放:检查距上次执行是否超过 25 天
CronJob: k8s/monthly-cycle-cronjob.yaml
- Schedule:
"30 0 1 * *"(每月 1 日 UTC 00:30)
安全保障:
| 攻击方式 | 防护措施 |
|---|---|
| 黑客调用指令 | authority 签名验证,没有私钥无法调用 |
| 篡改目标地址 | MCC/MCD 创世地址硬编码在常量 |
| 非 1 日调用 | 合约内 day_of_month == 1 校验 |
| 同月重复调用 | last_cycle_timestamp 检查 |
11.5 回购流程
1. 用户调用 execute_buyback(mcc_amount)
↓
2. 合约计算 usdc_amount = mcc_amount × buyback_price / 10^3
↓
3. 用户 MCC 转入 mcc_burn_vault
↓
4. usdc_vault 中的 USDC 转给用户
↓
5. 更新统计(total_mcc_bought, total_usdc_paid)
11.6 参数配置(默认值)
注意: 以下是合约默认值,主网实际初始化值请参见 11.1.2 初始化参数 (主网)
| 参数 | 默认值 | 说明 |
|---|---|---|
base_price | 10,000,000 | 10 USDC (6 decimals) - 默认值 |
premium_bps | 500 | 5% 溢价 |
daily_limit | 1,000,000,000,000 | 1M USDC 每日限额 - 默认值 |
min_buyback_amount | 10,000,000,000 | 最小 10 MCC |
max_buyback_amount | 100,000,000,000,000 | 最大 100,000 MCC |
11.6.1 ReincarnationPool 结构体解析(重要!)
⚠️ 2026-01-29 修复: Anchor String 使用
4字节长度 + 实际内容,不是固定 32 字节!
ReincarnationPool 结构体布局:
Offset Field Size 说明
------ ----- ---- ----
0 discriminator 8 Anchor 账户标识
8 name (String) 4 + N 4字节长度 + N字节实际内容(动态!)
8+4+N authority 32 管理员 Pubkey
... mcc_mint 32
... usdc_mint 32
... mcd_mint 32
... usdc_vault 32
... mcc_vault 32
... mcd_vault 32 (共 7 个 Pubkey = 224 字节)
... base_price 8 u64
... premium_bps 8 u64
... price_updated_at 8 i64 (之前常被遗漏!)
... paused 1 bool (之前常被遗漏!)
... daily_limit 8 u64
... daily_used 8 u64
... last_reset_day 8 i64
... (buyback stats) 24 3 × u64
... (mining stats) 32 4 × u64
... (cycle stats) 32 1 × i64 + 3 × u64
... created_at 8 i64
... bump 1 u8
... _reserved 32 保留字段
正确的 Python 解析示例:
offset = 8 # 跳过 discriminator
# name: Anchor String = 4字节长度 + 实际内容
name_len = struct.unpack_from('<I', raw, offset)[0]
offset += 4
pool_name = raw[offset:offset + name_len].decode('utf-8')
offset += name_len # ✅ 只跳过实际长度,不是固定 32 字节!
# 7 个 Pubkeys
offset += 224
# base_price, premium_bps
base_price = struct.unpack_from('<Q', raw, offset)[0]
offset += 8
premium_bps = struct.unpack_from('<Q', raw, offset)[0]
offset += 8
# price_updated_at - 不要漏掉!
price_updated_at = struct.unpack_from('<q', raw, offset)[0]
offset += 8
# paused - 不要漏掉!
paused = raw[offset] != 0
offset += 1
# daily_limit
daily_limit = struct.unpack_from('<Q', raw, offset)[0]
常见错误:
| 错误 | 原因 | 后果 |
|---|---|---|
offset += 32 代替 offset += name_len | 假设名称固定 32 字节 | 后续所有字段偏移错误 |
漏掉 price_updated_at 字段 | 未仔细阅读结构体定义 | daily_limit 等字段读取垃圾值 |
漏掉 paused 字段 | 1 字节 bool 容易遗忘 | 偏移量错位 1 字节 |
11.7 Token 地址 (2026-02-02 SPL Token + Metaplex 升级)
重要: MCC/MCD 已切换到 SPL Token + Metaplex Metadata,Solscan/钱包完美支持
| Token | 地址 (主网) | 地址 (Devnet) | 小数位 | Token Program |
|---|---|---|---|---|
| MCC Mint | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | - | 9 | SPL Token |
| MCD Mint | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty | - | 9 | SPL Token |
| MCC Genesis ATA | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i | - | - | - |
| MCD Genesis ATA | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | - | - | - |
| USDC Mint (Devnet Test) | - | 6aW6K4BW6UtzRJTj6YHqT5XDex3bYBv8pkm4X9Lj1osf | 6 | SPL Token |
SPL Token + Metaplex 特性:
- MCC: 供应量 10 亿,名称 "Microcosm Coin",符号 "MCC"
- MCD: 供应量 100 亿,名称 "Microcosm Dollar",符号 "MCD"
- MCC Mint Authority: 已放弃 (None),MCD Mint Authority: 保留 (MCWe3gEYqTjRCShEkhqbMXhcR4xP2dz29gurSpLbk4A)
- Metadata: 通过 Metaplex Token Metadata V3 管理 (name/symbol/uri)
11.8 部署步骤
cd solana-contracts/reincarnation
# 1. 安装依赖
yarn install
# 2. 构建合约
anchor build
# 3. 获取 Program ID
solana address -k target/deploy/reincarnation-keypair.json
# 4. 更新 Anchor.toml 和 lib.rs 中的 Program ID
# 5. 重新构建
anchor build
# 6. 部署到 Devnet
anchor deploy --provider.cluster devnet
# 7. 运行初始化脚本
yarn init
11.9 集成状态(2026-01-20 更新)
前端集成: ✅ 已完成(使用 Solana Wallet Adapter 直接调用链上合约)
| 组件 | 文件 | 状态 |
|---|---|---|
| TypeScript 客户端 | portal-service/lib/solana/reincarnation-client.ts | ✅ 完成 |
| 页面组件 | portal-service/components/reincarnation/ReincarnationPage.tsx | ✅ 完成 |
| Wallet Provider | portal-service/components/providers/SolanaWalletProvider.tsx | ✅ 完成 |
后端集成: ✅ 已完成 (2026-01-20)
| 组件 | 文件 | 状态 |
|---|---|---|
| Solana Client | blockchain-service/app/utils/reincarnation_client.py | ✅ 完成 |
| x402 路由 | blockchain-service/app/routes/x402.py | ✅ 完成 |
| Monthly CronJob | k8s/monthly-cycle-cronjob.yaml | ✅ 完成 |
后端关键功能:
execute_mining()- 执行链上 MCC/MCD 分发execute_monthly_cycle()- 执行月度轮回get_pool_info()- 获取轮回池状态
x402 非托管铸造流程:
- 用户 USDC 支付是独立交易(用户签名)
- 后端验证链上交易
- 后端调用
execute_mining(只需 authority 签名) - 链上分发 MCC/MCD (50-10-10-30)
x402 非托管回购流程:
- 回购操作使用 x402 非托管支付协议
- 用户钱包直接与链上合约交互,平台不托管用户资金
- 前端使用 Solana Wallet Adapter(支持 Phantom、Solflare 等)
execute_buyback指令将用户 MCC 转入 MCC Vault,从 USDC Vault 支付 USDC 给用户
十二、合约部署状态汇总
🎉 2026-01-29 主网部署完成: 所有 8 个合约已部署到主网!
| 合约 | Program ID | 状态 | 最新更新 |
|---|---|---|---|
| MCC Token | FDRy2jpKqXD5pp8Xj2arEbEm78nCEcRnKCmGxBTiFWxr | ✅ 主网运行中 | 2026-01-29 |
| MCD Token | J9UwVmFEr7ujLcp19T8nqpDnpBLcDzpL4cpwh5TMSd36 | ✅ 主网运行中 | 2026-01-29 |
| Lending | 5JRnecaAZNfF1bBjdW93JB8VFJVpWWDkR3NKg2jHnMPQ | ✅ 主网运行中 | 2026-01-29 |
| Territory NFT | ipYLo2aitVyNXGzCgpiaKKA2JLvtbBvMHiV7qKZTPVZ | ✅ 主网运行中 | 2026-01-29 |
| Auction | 6JRmShodszZca3ez7GfDkmsRSzTi5ELwscWCDgjsteJx | ✅ 主网运行中 | 2026-01-29 |
| Level Verifier | 8TSuNuR1Carh8GpjqrZiVo3oz1nC2K9FSy6BhqbWb3ek | ✅ 主网运行中 | 2026-01-29 |
| Fragment | J7wyftDtfzqn2pbpLr8QPqKQkAxecgVze75SUz9D4Fq3 | ✅ 主网运行中 | 2026-01-29 |
| Reincarnation | REn8oKyydvjRsistZ2cVi6tksPubvR3bEuLdVTyGknb | ✅ 主网运行中 | 2026-01-29 |
Token Mint 汇总 (主网) - 2026-02-02 SPL Token + Metaplex 升级
| Token | Mint 地址 | 总供应量 | Mint Authority | Token Program |
|---|---|---|---|---|
| MCC | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | 10 亿枚 | ✅ 保留 (MCWe3...) | SPL Token |
| MCD | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty | 100 亿枚 | ✅ 保留 (MCWe3...) | SPL Token |
版本历史
| 版本 | 日期 | 更新内容 |
|---|---|---|
| v1.0 | 2026-01-15 | 初始版本,包含 MCC/MCD/Lending 合约定义 |
| v1.1 | 2026-01-16 | 添加 Territory NFT 合约(含栈溢出解决方案) |
| v1.2 | 2026-01-16 | 添加 Auction 合约 |
| v1.3 | 2026-01-16 | 添加 Level Verifier 合约 |
| v1.4 | 2026-01-16 | Level Verifier 添加 update_config 指令,修正 territory_nft_program 地址 |
| v1.5 | 2026-01-16 | 添加 Fragment 合约(NFT 碎片化协议) |
| v1.6 | 2026-01-16 | Level Verifier 后端集成完成(blockchain-service v1.2.3) |
| v1.7 | 2026-01-16 | Territory NFT 后端集成完成 |
| v1.8 | 2026-01-16 | Auction 后端集成完成 |
| v1.9 | 2026-01-16 | Fragment 后端集成完成 |
| v2.0 | 2026-01-16 | Lending 后端集成完成 |
| v2.1 | 2026-01-16 | 前端 API + Open API v1.1.0 完成(Territory/Auction/Fragment/Lending) |
| v2.2 | 2026-01-16 | 前端页面集成完成,8 个合约/服务全部 100% 集成 |
| v2.3 | 2026-01-17 | Territory NFT 浏览器完成,文档同步更新 |
| v2.4 | 2026-01-18 | MCC Token Mint 重新部署,供应量从 100 亿修复为正确的 10 亿 |
| v2.5 | 2026-01-19 | 添加 Reincarnation 合约(轮回/回购协议),代码完成待部署 |
| v2.6 | 2026-01-19 | Reincarnation 前端集成完成(Solana Wallet Adapter),修复 USDC Mint 地址 |
| v2.7 | 2026-01-19 | 重构 Reincarnation 价格机制:预言机服务作为价格聚合层,合约为唯一真实来源 |
| v2.8 | 2026-01-20 | Reincarnation 合约升级: 新增 execute_mining + execute_monthly_cycle 指令 |
| v2.9 | 2026-01-20 | 添加 MCD Vault (9t5Kv8Qn14mgwe97gfBwSsxA2CFj8ZwnsSAsUNK3Tpca),重命名 mcc_burn_vault → mcc_vault |
| v3.0 | 2026-01-20 | 后端集成完成 (reincarnation_client.py),添加 monthly-cycle-cronjob.yaml |
| v4.0 | 2026-01-29 | 🎉 主网部署完成: 8 个合约全部部署到主网,MCC (20亿) + MCD (100亿) Token Mint 已创建 |
| v4.1 | 2026-01-31 | Mint Authority 状态更新: MCC Mint Authority 已放弃 (None),MCD Mint Authority 保留 |
| v5.0 | 2026-02-02 | 🔄 SPL Token + Metaplex 迁移完成: MCC/MCD 从 Token-2022 切换到 SPL Token + Metaplex Metadata,解决 Solscan/钱包 Logo 显示问题 |
| v5.1 | 2026-02-02 | Reincarnation v1.4.0: 添加 close_old_vault_ata 指令,回收废弃 Token-2022 ATA 租金 |
| v5.2 | 2026-02-02 | 后端 ATA 计算修复: reincarnation_client.py 和 mcd_solana_client.py 切换到 SPL Token Program ID |
Token-2022 → SPL Token 迁移记录 (2026-02-02)
重要: Token-2022 版本已废弃,以下旧地址仅作记录,不再使用!
废弃原因:
- Token-2022 的 Metaplex Metadata 支持不完善
- Solscan/钱包显示 Logo/Name 需要 Metaplex,而 Metaplex 不支持 Token-2022
- 切换到 SPL Token + Metaplex Metadata 标准
旧 Token-2022 地址(已废弃):
| 名称 | 旧地址 | 状态 |
|---|---|---|
5WRLP7HB3VtQtA9QmUzA6Bs8ViMKPs3Fkr4b1f1nuhKH | ❌ 已废弃 | |
BDZBCDDAdpk9PxEEoUTBxUZKBjtmkpwzmtmGijggtqGS | ❌ 已废弃,已 burn + close | |
8EuRvXfjDsGGhNmAGfoeVXQWFbWY4A4rJGY9H1NfLEGr | ❌ 已废弃 | |
ELjvTLShfWvQAe94Mc1vMxnaVVsKY8yD2DazGZ1nGGTS | ❌ 已废弃,已 burn + close | |
D2g1WAs3b9tH78pzgxtpqpYv64f11J7hLq9R294rrhtx | ❌ 已关闭,租金已回收 | |
FJ2PFRYMArzHRTESoGSd7x1Xo7hmeeqhuhqhUPqyCfk5 | ❌ 已关闭,租金已回收 | |
BpWvEJ8N8zWPwk1jZ3RL2gbHfRyxUojie3oNztRJwjZ9 | ❌ 已关闭,租金已回收 |
新 SPL Token 地址(当前使用):
| 名称 | 新地址 | 说明 |
|---|---|---|
| MCC Token Mint | MCCpDtigJLYnfGe1fW5xrSA8AXo6AeAj8ECE7wVqP5e | SPL Token + Metaplex |
| MCC Genesis ATA | D77aFnhcRr5PFgmb5TdFngcYyzM6ig2HXzUSYCJSHz7i | 10 亿枚 |
| MCD Token Mint | MCDXTiLK6idQSycdb8QkwKYVP8HEbfe4JbJZjC7Fkty | SPL Token + Metaplex |
| MCD Genesis ATA | DfLGbEV6FDSsG5BaFeCDLMrr9LKMupDQvENvp9943QiC | 100 亿枚 |
| Reincarnation MCC Vault | DhS2L2ga55iaMHbk3VAPYr43HaQv4Q8ft2eXYkdkofWj | SPL Token |
| Reincarnation MCD Vault | 2hG2FsxRSEdiZdq86p9NMA9XxWvsEBx1DL3NT6d9eEHo | SPL Token |
| Station 1 MCD Vault ATA | G6vcWY4BW81HMnPeiDL1BSEUkaDDFBgZ48SKfMEWtbwe | SPL Token |
SOL 回收:
- 详见
docs/SOL回收指南.md - 总计回收约 3.36 SOL(Program Buffer + 旧 ATA 租金)
⚠️⚠️⚠️ ATA 地址计算问题 (2026-02-02 重要修复) ⚠️⚠️⚠️
核心问题: 不同的 Token Program ID 会导致相同的 owner + mint 计算出完全不同的 ATA 地址!
ATA 地址计算公式:
# ATA = PDA([owner, token_program, mint], ATA_PROGRAM_ID)
# 关键:token_program 参与 seeds 计算!
# SPL Token ATA (正确)
ata_spl = get_associated_token_address(mint, owner, TOKEN_PROGRAM_ID)
# TOKEN_PROGRAM_ID = TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
# Token-2022 ATA (错误 - 会计算出不同地址)
ata_2022 = get_associated_token_address(mint, owner, TOKEN_2022_PROGRAM_ID)
# TOKEN_2022_PROGRAM_ID = TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
实际案例 - Station 1 MCD Vault:
| Token Program | Vault PDA (相同) | 计算出的 ATA (不同!) | 状态 |
|---|---|---|---|
| SPL Token | GayhXUqw5Esy7VGF269Vz3K75wLcLDEtu9za91YDHauG | G6vcWY4BW81HMnPeiDL1BSEUkaDDFBgZ48SKfMEWtbwe | ✅ 正确 |
GayhXUqw5Esy7VGF269Vz3K75wLcLDEtu9za91YDHauG | 33wxwR1XpcWFxN4Q31kHmGMGMxzVyeAYP9S19XhhArR6 | ❌ 错误 |
后端修复 (2026-02-02):
| 文件 | 修复内容 |
|---|---|
reincarnation_client.py | get_associated_token_address() 默认使用 SPL Token Program ID |
mcd_solana_client.py | get_associated_token_address() 默认使用 SPL Token Program ID |
修复代码示例:
def get_associated_token_address(mint: Pubkey, owner: Pubkey, token_program: Pubkey = None) -> Pubkey:
# ⚠️ 关键:默认使用 SPL Token (2026-02-02 切换到 SPL Token + Metaplex)
if token_program is None:
token_program = TOKEN_PROGRAM_ID # 不是 TOKEN_2022_PROGRAM_ID!
seeds = [bytes(owner), bytes(token_program), bytes(mint)]
return Pubkey.find_program_address(seeds, ASSOCIATED_TOKEN_PROGRAM_ID)[0]
开发注意事项:
- MCC/MCD 使用 SPL Token,所有 ATA 计算必须使用
TOKEN_PROGRAM_ID - 不要假设 ATA 地址在不同 Token Program 间相同 - 它们完全不同
- 链上交易中的
token_programAccountMeta 必须与 ATA 计算时使用的一致 - 后端代码中搜索
TOKEN_2022_PROGRAM_ID,确保所有涉及 MCC/MCD 的地方都已切换到TOKEN_PROGRAM_ID
十二、前端页面集成状态
12.1 集成概览
| 合约/服务 | 页面组件 | 集成度 | 修改日期 |
|---|---|---|---|
| MCC Token | WalletPage, MiningPage | 100% | - |
| MCD Token | MCDPage | 100% | - |
| Auction | AuctionsPage | 100% | - |
| Lending | LendingPage | 100% | 2026-01-16 |
| Territory NFT | StationDetailPage | 100% | 2026-01-16 |
| Level Verifier | ProfilePage | 100% | 2026-01-16 |
| Fragment | FragmentPage | 100% | 2026-01-16 |
| x402 API | api.ts, services.ts | 100% | 2026-01-16 |
12.2 页面修复详情
| 页面 | 修改内容 | 文件路径 |
|---|---|---|
| LendingPage | 从模拟数据改为真实 API 调用 | components/lending/LendingPage.tsx |
| StationDetailPage | 添加 Territory NFT 显示和铸造功能 | components/stations/StationDetailPage.tsx |
| ProfilePage | 添加用户等级状态卡片、铸造进度、升级进度 | components/profile/ProfilePage.tsx |
| FragmentPage | 新建完整的 NFT 碎片化交易页面 | components/fragment/FragmentPage.tsx (新建) |
| Fragment 路由 | 添加 /mcc/fragment 路由页面 | app/(dashboard)/mcc/fragment/page.tsx (新建) |
| 菜单配置 | 添加 "NFT 碎片化" 菜单项 | config/menu-config.ts |
12.3 新增前端文件
| 文件 | 类型 | 说明 |
|---|---|---|
app/(dashboard)/mcc/fragment/page.tsx | 路由页面 | Fragment 页面入口 |
components/fragment/FragmentPage.tsx | 组件 | 碎片化交易完整 UI |
12.4 x402 API 类型定义
新增类型 (lib/types/api.ts):
MiningRequest- 铸造请求MiningRequestResponse- 铸造请求响应PaymentConfirmRequest- 支付确认请求PaymentConfirmResponse- 支付确认响应MiningRatioInfo- 铸造产值比例信息
新增 API 函数 (lib/api/services.ts):
createMiningRequest()- 创建铸造请求confirmMiningPayment()- 确认铸造支付getMiningRatio()- 获取产值比例getMiningRequestStatus()- 获取请求状态
十三、Redis 缓存架构 (2026-01-20 新增)
重要: 链上数据不直接从 Solana RPC 获取,而是通过 Redis 缓存层优化性能。
13.1 架构概述
blockchain-service 实现了工业标准的 Cache-Aside Pattern(旁路缓存模式)。
数据流: Frontend (Portal) --> blockchain-service --> Redis Cache (命中时直接返回) --> 若 cache miss 则查询 Solana RPC (Helius)
13.2 缓存 API 端点
| 端点 | 方法 | 功能 | TTL |
|---|---|---|---|
/balance/wallet/{address} | GET | 获取钱包全量余额(SOL/MCC/USDC/MCD) | 60s |
/balance/wallet/{address}/mcc | GET | 获取 MCC 余额 | 60s |
/balance/wallet/{address}/mcd | GET | 获取 MCD 积分余额 | 60s |
/balance/wallet/{address}/refresh | POST | 强制刷新钱包余额 | - |
/balance/invalidate/{address} | POST | 失效钱包缓存 | - |
/balance/pool/reincarnation | GET | 获取轮回池状态 | 300s |
13.3 缓存 Key 格式
# 钱包全量余额
f"blockchain:balance:all:{wallet_address}"
# MCC 单独余额
f"blockchain:balance:mcc:{wallet_address}"
# MCD 单独余额
f"blockchain:balance:mcd:{wallet_address}"
# 轮回池状态
"blockchain:pool:reincarnation"
13.4 缓存策略
| 策略 | 说明 |
|---|---|
| Cache-Aside | 读取时先查 Redis,未命中则查链上,然后写入 Redis |
| TTL 过期 | 余额缓存 60 秒,池状态 300 秒,自动过期 |
| 事件驱动失效 | 交易完成后主动调用 /balance/invalidate/{address} |
| 强制刷新 | 用户点击刷新时调用 ?force=true 忽略缓存 |
| 降级策略 | Redis 不可用时直接查询链上,不阻塞请求 |
13.5 前端集成
// 获取钱包余额(自动缓存)
const balance = await fetch(`/api/blockchain/balance/wallet/${address}`)
// 强制刷新余额
const fresh = await fetch(`/api/blockchain/balance/wallet/${address}?force=true`)
// 交易后失效缓存
await fetch(`/api/blockchain/balance/invalidate/${address}`, { method: 'POST' })
13.6 代码位置
| 组件 | 文件路径 |
|---|---|
| 缓存模块 | services/blockchain-service/app/cache/ |
| 余额缓存 | services/blockchain-service/app/cache/balance_cache.py |
| 缓存 API | services/blockchain-service/app/routes/balance.py |
| 前端 API | services/portal-service/lib/api/blockchain.ts |
| 代理路由 | services/portal-service/app/api/blockchain/balance/ |
13.7 Token 精度
| Token | 小数位数 | 转换公式 |
|---|---|---|
| SOL | 9 | raw_amount / 1e9 |
| MCC | 9 | raw_amount / 1e9 |
| USDC | 6 | raw_amount / 1e6 |
此文档是 Solana 合约的权威定义,其他文档应引用而非重复定义。