gcx/docs/guides/06-区块链开发指南.md

1071 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Genex Chain 区块链开发指南
> 自建EVM兼容应用链 + 智能合约体系
---
## 1. 链架构总览
| 组件 | 技术选型 | 说明 |
|------|---------|------|
| **链框架** | Cosmos SDK最新版本 | 200+生产链验证,模块化 |
| **共识引擎** | CometBFT原Tendermint | 拜占庭容错,**即时终结性** |
| **EVM模块** | **cosmos/evm**官方Cosmos EVM | Apache 2.0替代已弃用的Ethermint |
| **跨链通信** | IBC | Cosmos生态原生跨链协议 |
| **跨链桥** | Axelar/ Wormhole | 稳定币从Ethereum桥入 |
| **撮合架构** | 链下内存订单簿 + 链上结算 | 参考dYdX v4 |
### 参考链
| 链 | 价值 | 关键参考 |
|----|------|---------|
| **Cronos** | Cosmos SDK + EVM最成熟实现 | <1s出块Block-STM并行执行 |
| **dYdX v4** | 交易平台专用链标杆 | 链下订单簿+链上结算 |
| **Injective** | 金融应用Layer-1 | 链上CLOB机构级合规 |
---
## 2. 链设计参数
| 参数 | 目标值 |
|------|--------|
| 共识机制 | CometBFT PoS平台运营 + 合格机构验证节点 |
| EVM兼容 | 完全兼容SolidityHardhatMetaMask全套工具链 |
| 出块时间 | ** 1秒**CometBFT即时终结性 |
| TPS | 5,000Block-STM并行执行 |
| Gas策略 | 平台前期全额补贴用户零Gas |
| 原生代币 | GNXGas + 治理前期Gas补贴用户不接触基础单位 agnxatto GNX, 18位精度EVM标准 |
| 节点运营 | 平台运营验证节点 + 合格机构验证节点 |
| 跨链 | IBC连接Cosmos生态 + Axelar桥连接Ethereum |
### 为什么自建链
| 维度 | 公链/L2 | Genex Chain |
|------|---------|-------------|
| Gas控制 | 受市场波动 | 平台完全控制可设为零 |
| 合规执行 | 链层面无法强制 | 链级OFAC/Travel Rule内置 |
| 性能调优 | 共享资源 | 独享资源针对券业务优化 |
| 升级自主 | 依赖链治理 | 平台自主决定升级 |
| 数据主权 | 完全公开 | 可控可见性 |
| 监管对接 | 难以定制 | 专属节点/API |
---
## 3. 开发环境搭建
### 3.1 前置依赖
```bash
# Go 1.21+
go version
# Node.js 20+(合约开发工具)
node --version
# Foundry合约开发框架
curl -L https://foundry.paradigm.xyz | bash
foundryup
# Cosmos SDK CLI
go install cosmossdk.io/tools/cosmovisor/cmd/cosmovisor@latest
```
### 3.2 Genex Chain本地开发
```bash
# 克隆Genex Chain仓库
git clone https://git.gogenex.com/genex-chain.git
cd genex-chain
# 编译
make build
# 初始化本地测试链
./genexd init test-node --chain-id genex-localnet
# 创建创世账户
./genexd keys add validator
./genexd genesis add-genesis-account validator 1000000000000000000000000000agnx
# 启动本地节点
./genexd start
```
### 3.3 合约开发环境
```bash
# 创建合约工程
mkdir genex-contracts && cd genex-contracts
# 使用Foundry初始化
forge init
# 项目结构
genex-contracts/
├── src/
│ ├── CouponFactory.sol
│ ├── Coupon.sol
│ ├── Settlement.sol
│ ├── Redemption.sol
│ ├── Treasury.sol
│ ├── Compliance.sol
│ └── Governance.sol
├── test/
│ ├── CouponFactory.t.sol
│ ├── Settlement.t.sol
│ └── ...
├── script/
│ └── Deploy.s.sol
└── foundry.toml
```
---
## 4. 智能合约体系7合约系统
### 4.1 合约架构
```
┌─────────────────────────────────────────────┐
│ Governance治理
│ Gas参数调整 | 紧急冻结多签 | 合约升级管理 │
├─────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌───────────────────┐ │
│ │CouponFactory │ │ Compliance │ │
│ │ 券发行工厂 │ │ OFAC筛查 │ │
│ │ 铸造+类型标记 │ │ Travel Rule │ │
│ └──────┬───────┘ │ 紧急冻结 │ │
│ │ └───────────────────┘ │
│ ┌──────┴───────┐ │
│ │ Coupon │ ┌───────────────────┐ │
│ │ ERC-721/1155 │ │ Treasury │ │
│ │ 所有权+转移 │ │ 资金托管 │ │
│ └──────┬───────┘ │ 退款原子交换 │ │
│ │ └───────────────────┘ │
│ ┌──────┴───────────────────────┐ │
│ │ │ │
│ │ Settlement Redemption │ │
│ │ 交易结算 兑付清算 │ │
│ │ 原子交换 券销毁 │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────────────┘
```
### 4.2 CouponFactory — 券发行工厂
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
contract CouponFactory is Initializable, AccessControlUpgradeable {
enum CouponType { Utility, Security }
struct CouponConfig {
CouponType couponType; // 券类型(铸造后不可更改)
bool transferable; // 是否可转让
uint8 maxResaleCount; // 最大转售次数Utility默认2-3
uint256 maxPrice; // 价格上限Utility = 面值)
uint256 expiryDate; // 到期日
uint256 minPurchase; // 最低消费金额
bool stackable; // 是否可叠加
bytes32[] allowedStores; // 限定门店
}
event CouponBatchMinted(
address indexed issuer,
uint256 indexed batchId,
uint256 faceValue,
uint256 quantity,
CouponType couponType
);
function mintBatch(
address issuer,
uint256 faceValue,
uint256 quantity,
CouponConfig calldata config
) external onlyRole(MINTER_ROLE) returns (uint256[] memory tokenIds) {
// Utility Track强制价格上限 = 面值最长12个月
if (config.couponType == CouponType.Utility) {
require(config.maxPrice <= faceValue, "Utility: maxPrice <= faceValue");
require(config.expiryDate <= block.timestamp + 365 days, "Utility: max 12 months");
}
// Securities Track强制必须通过合格投资者验证 + Broker-Dealer合规
if (config.couponType == CouponType.Security) {
require(config.expiryDate > 0, "Security: expiry required");
// Securities Track由Compliance合约强制合格投资者KYC L2+
}
// 铸造逻辑
tokenIds = _mintTokens(issuer, faceValue, quantity, config);
emit CouponBatchMinted(issuer, batchId, faceValue, quantity, config.couponType);
}
}
```
### 4.3 Settlement — 交易结算
```solidity
contract Settlement is Initializable, AccessControlUpgradeable {
ICoupon public couponContract;
IERC20 public stablecoin; // USDC
ICompliance public compliance;
event TradeSettled(
uint256 indexed tokenId,
address indexed buyer,
address indexed seller,
uint256 price
);
/// @notice 原子交换:券 ↔ 稳定币 同时转移
function executeSwap(
uint256 tokenId,
address buyer,
address seller,
uint256 price
) external onlyRole(SETTLER_ROLE) {
// 合规检查
require(!compliance.isBlacklisted(buyer), "Buyer blacklisted");
require(!compliance.isBlacklisted(seller), "Seller blacklisted");
// Utility Track: 价格 ≤ 面值
CouponConfig memory config = couponContract.getConfig(tokenId);
if (config.couponType == CouponType.Utility) {
require(price <= config.maxPrice, "Utility: price exceeds face value");
}
// 转售次数检查
require(
couponContract.getResaleCount(tokenId) < config.maxResaleCount,
"Max resale count exceeded"
);
// 原子交换(要么全部成功,要么全部回滚)
stablecoin.transferFrom(buyer, seller, price);
couponContract.safeTransferFrom(seller, buyer, tokenId);
couponContract.incrementResaleCount(tokenId);
emit TradeSettled(tokenId, buyer, seller, price);
}
/// @notice 退款:反向原子交换
function executeRefund(
uint256 tokenId,
address buyer,
address seller,
uint256 refundAmount
) external onlyRole(SETTLER_ROLE) {
couponContract.safeTransferFrom(buyer, seller, tokenId);
stablecoin.transferFrom(seller, buyer, refundAmount);
}
}
```
### 4.4 Redemption — 兑付合约
```solidity
contract Redemption is Initializable {
ICoupon public couponContract;
event CouponRedeemed(
uint256 indexed tokenId,
address indexed consumer,
address indexed issuer,
bytes32 storeId
);
/// @notice 消费者直接与发行方结算,平台不介入
function redeem(
uint256 tokenId,
bytes32 storeId
) external {
require(couponContract.ownerOf(tokenId) == msg.sender, "Not owner");
CouponConfig memory config = couponContract.getConfig(tokenId);
// 验证到期
require(block.timestamp <= config.expiryDate, "Coupon expired");
// 验证门店限定
if (config.allowedStores.length > 0) {
require(_isAllowedStore(storeId, config.allowedStores), "Store not allowed");
}
// 销毁券burn
couponContract.burn(tokenId);
// 通知发行方event平台不介入消费数据
emit CouponRedeemed(tokenId, msg.sender, config.issuer, storeId);
}
}
```
### 4.5 Compliance — 合规合约
```solidity
contract Compliance is Initializable, AccessControlUpgradeable {
mapping(address => bool) private _blacklist; // OFAC黑名单
/// @notice OFAC筛查
function isBlacklisted(address account) external view returns (bool) {
return _blacklist[account];
}
/// @notice Travel Rule≥$3,000强制
function recordTravelRule(
address sender,
address receiver,
bytes32 senderInfoHash, // 身份信息哈希(明文链下保存)
bytes32 receiverInfoHash
) external {
emit TravelRuleRecorded(sender, receiver, senderInfoHash, receiverInfoHash);
}
/// @notice 紧急冻结需Governance多签
function freezeAccount(address account) external onlyRole(GOVERNANCE_ROLE) {
_blacklist[account] = true;
emit AccountFrozen(account);
}
}
```
### 4.6 Governance — 治理合约
```solidity
contract Governance is Initializable {
uint256 public constant REQUIRED_SIGNATURES = 3; // 3/5多签
uint256 public constant TIMELOCK = 48 hours; // 时间锁
uint256 public constant EMERGENCY_TIMELOCK = 4 hours;
struct Proposal {
bytes callData;
address target;
uint256 executeAfter;
uint256 approvalCount;
bool executed;
mapping(address => bool) approvals;
}
function propose(address target, bytes calldata data) external onlyMultisig {
// 创建提案,设置时间锁
}
function approve(uint256 proposalId) external onlyMultisig {
// 审批提案
}
function execute(uint256 proposalId) external {
Proposal storage p = proposals[proposalId];
require(p.approvalCount >= REQUIRED_SIGNATURES, "Not enough approvals");
require(block.timestamp >= p.executeAfter, "Timelock not expired");
require(!p.executed, "Already executed");
p.executed = true;
(bool success,) = p.target.call(p.callData);
require(success, "Execution failed");
}
}
```
---
## 5. 合约升级策略
**模式Transparent Proxy透明代理**
```
用户/前端 → Proxy合约地址不变→ Implementation合约可替换
```
**升级流程:**
```
发起升级提案 → 多签审批3/5→ 时间锁48h → 自动执行
紧急通道4/5多签 → 4h时间锁
```
**不可升级的逻辑(安全红线):**
- 券类型标记Utility/Security)— 不可修改
- 所有权记录 不可被升级篡改
- 链上转售计数器 防止绕过Utility Track限制
---
## 6. 链级合规能力
| 能力 | 实现 |
|------|------|
| 链级OFAC过滤 | 验证节点拒绝处理制裁地址交易 |
| 链级Travel Rule | 大额转移必须携带身份哈希否则拒绝打包 |
| 链级监控 | 节点内置异常交易检测模块 |
| 监管API | 监管机构专属只读API |
| 紧急冻结 | Governance多签冻结涉案地址 |
---
## 7. Gas费策略
### 前期(全额补贴)
| 操作 | Gas承担方 |
|------|----------|
| 券发行铸造 | 平台补贴 |
| 一级/二级市场交易 | 平台补贴 |
| P2P转移 | 平台补贴 |
| 券兑付消费 | 平台补贴 |
> 自建链Gas = 平台运营成本(服务器/节点非公链ETH支付。
### 技术实现
```toml
# 创世配置
[app_state.evm.params]
min_gas_price = "0"
# 或使用ERC-4337 Paymaster
```
Gas参数通过Governance合约动态调整无需硬分叉)。
---
## 8. 测试策略
### 8.1 合约测试Foundry
```solidity
// test/Settlement.t.sol
contract SettlementTest is Test {
Settlement settlement;
MockCoupon coupon;
MockERC20 usdc;
function setUp() public {
usdc = new MockERC20("USDC", "USDC", 6);
coupon = new MockCoupon();
settlement = new Settlement();
settlement.initialize(address(coupon), address(usdc));
}
function test_UtilityCannotExceedFaceValue() public {
// 面值100的Utility券尝试以110价格交易应被拒绝
vm.expectRevert("Utility: price exceeds face value");
settlement.executeSwap(tokenId, buyer, seller, 110e6);
}
function test_AtomicSwapSuccess() public {
// 正常交易:券和稳定币同时转移
settlement.executeSwap(tokenId, buyer, seller, 85e6);
assertEq(coupon.ownerOf(tokenId), buyer);
assertEq(usdc.balanceOf(seller), 85e6);
}
function test_RefundReverseSwap() public {
// 退款:反向原子交换
settlement.executeRefund(tokenId, buyer, seller, 85e6);
assertEq(coupon.ownerOf(tokenId), seller);
assertEq(usdc.balanceOf(buyer), 85e6);
}
}
```
### 8.2 测试覆盖要求
| 测试类型 | 覆盖 |
|---------|------|
| 单元测试 | 每个合约函数 |
| Fuzz测试 | 价格边界数量溢出 |
| 集成测试 | 完整发行交易核销流程 |
| Gas优化 | 批量操作Gas消耗 |
| 安全审计 | 第三方审计上线前必须 |
---
## 9. 部署流程
```bash
# 部署到本地测试链
forge script script/Deploy.s.sol --rpc-url http://localhost:8545 --broadcast
# 部署到Genex Chain测试网
forge script script/Deploy.s.sol \
--rpc-url https://testnet-rpc.gogenex.com \
--broadcast \
--verify
# 部署到Genex Chain主网需多签审批
forge script script/Deploy.s.sol \
--rpc-url https://rpc.gogenex.com \
--broadcast \
--verify \
--etherscan-api-key $GENEX_EXPLORER_KEY
```
### 合约验证
```bash
forge verify-contract \
--chain-id 8888 \
--compiler-version v0.8.20 \
$CONTRACT_ADDRESS \
src/CouponFactory.sol:CouponFactory
```
---
## 10. GCFN全球清算节点架构
```
┌─────────────────────────────────────────────┐
│ Global Coupon Financial Network (GCFN) │
├─────────────────────────────────────────────┤
│ ROOT NODE │
│ (US / Global Hub) │
│ 全球路由 | 跨境清算 | 合规协调 │
├──────────────┬──────────────┬───────────────┤
│ ASIA-PACIFIC │ EMEA │ AMERICAS │
├──────────────┼──────────────┼───────────────┤
│ 新加坡(MAS) │ 伦敦(FCA) │ 美国(FinCEN) │
│ 香港(SFC) │ 法兰克福 │ │
│ 日本(FSA) │ (BaFin) │ │
└──────────────┴──────────────┴───────────────┘
```
| 节点类型 | 职责 |
|---------|------|
| 根节点 | 全球路由跨境清算主验证节点 |
| 区域节点 | 区域清算监管报送本地化 |
| 本地节点 | 用户服务本地支付法规遵从 |
| 监管节点 | 只读审计实时监控 |
---
## 11. 多机构验证节点架构
### 11.1 节点类型与准入
| 节点类型 | 运营方 | 权限 | 准入条件 |
|---------|--------|------|---------|
| **创世验证节点** | Genex平台 | 出块 + 治理 | 平台自有 |
| **机构验证节点** | 持牌金融机构 | 出块 + 治理 | KYC L3 + 机构资质审查 + 最低质押 |
| **监管观察节点** | 监管机构 | 只读 + 审计API | 监管机构官方申请 |
| **全节点** | 任何人 | 只读同步 | 无门槛 |
### 11.2 验证节点配置
```toml
# genex-chain/config/config.toml — 生产验证节点配置
[consensus]
timeout_propose = "1s"
timeout_prevote = "500ms"
timeout_precommit = "500ms"
timeout_commit = "800ms"
[mempool]
size = 10000
max_txs_bytes = 1073741824 # 1GB
[p2p]
max_num_inbound_peers = 100
max_num_outbound_peers = 50
persistent_peers = "node1@us-east:26656,node2@sg:26656,node3@eu:26656"
```
### 11.3 节点部署拓扑
```
生产网络最少5个验证节点推荐7-11个
Genex节点 x3 — 美国(2) + 新加坡(1)
机构节点 x4+ — 合格金融机构各自运维
监管节点 x3 — FinCEN / MAS / FCA 只读
```
---
## 12. 安全规范
- 所有合约上线前必须通过第三方安全审计
- 核心合约采用Transparent Proxy部署
- 升级需3/5多签 + 48小时时间锁
- Bug Bounty计划严重漏洞奖励$10K-$100K
- MPC/HSM密钥管理
- 合约代码开源并在区块浏览器验证
---
## 13. GNX原生代币经济模型
### 13.1 代币用途
| 用途 | 说明 | 状态 |
|------|------|------|
| **Gas消耗** | 支付交易费用平台全额补贴 | 已上线 |
| **治理投票** | 参与链参数决策 | 平台内部运行 |
| **质押收益** | 验证节点质押获奖励 | 需合规审批 |
| **二级市场交易** | 交易所买卖GNX | 需合规审批 |
> GNX当前用于Gas平台补贴不上交易所回避SEC证券风险。质押和二级市场交易需取得合规审批后开放。
### 13.2 代币分配
```
总供应量: 1,000,000,000 GNX= 10^27 agnx
基础单位: agnxatto GNX, 18位精度与EVM wei对齐
中间单位: ngnxnano GNX, 10^9 agnx类似gwei
显示单位: GNX10^18 agnx
├── 平台运营/Gas补贴: 40%4亿— 前期Gas支出从此池扣除
├── 团队与顾问: 20%2亿— 4年线性释放1年锁定期
├── 生态基金: 15%1.5亿)— 开发者激励、做市商激励
├── 未来融资预留: 15%1.5亿)— Reg D/Reg S豁免发行
└── 社区治理: 10%1亿— DAO治理基金
```
### 13.3 Gas经济模型
```go
// genex-chain/x/evm/keeper/gas.go
// 当前阶段Gas Price = 0平台全额补贴
// 后期可通过Governance合约调整Gas参数
func (k Keeper) GetBaseFee(ctx sdk.Context) *big.Int {
params := k.GetParams(ctx)
if params.MinGasPrice.IsZero() {
return big.NewInt(0) // 免费Gas
}
return params.MinGasPrice.BigInt()
}
```
---
## 14. Coupon合约补充 — 不可转让券
```solidity
// src/Coupon.sol — 补充transfer限制逻辑
contract Coupon is ERC721Upgradeable, AccessControlUpgradeable {
mapping(uint256 => CouponConfig) private _configs;
/// @notice 重写transfer不可转让券直接revert
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId,
uint256 /* batchSize */
) internal virtual override {
// 铸造from=0和销毁to=0不受限
if (from == address(0) || to == address(0)) return;
CouponConfig memory config = _configs[tokenId];
// 不可转让券revert
require(config.transferable, "Coupon: non-transferable");
// 转售次数检查
require(
_resaleCount[tokenId] < config.maxResaleCount,
"Coupon: max resale count exceeded"
);
}
/// @notice 批量转移批量P2P/批量交易)
function batchTransfer(
address from,
address to,
uint256[] calldata tokenIds
) external {
for (uint256 i = 0; i < tokenIds.length; i++) {
safeTransferFrom(from, to, tokenIds[i]);
}
}
}
```
---
## 15. Compliance合约补充 — 差异化KYC检查
```solidity
// src/Compliance.sol — 补充KYC等级差异化检查
contract Compliance is Initializable, AccessControlUpgradeable {
// KYC等级映射
mapping(address => uint8) private _kycLevels; // 0=L0, 1=L1, 2=L2, 3=L3
// 不同操作要求不同KYC等级
function requireKycLevel(address account, uint8 requiredLevel) public view {
require(_kycLevels[account] >= requiredLevel, "Compliance: insufficient KYC level");
}
/// @notice 交易前合规检查Settlement调用
function preTradeCheck(
address buyer,
address seller,
uint256 amount,
CouponType couponType
) external view {
// OFAC黑名单检查
require(!_blacklist[buyer], "Buyer blacklisted");
require(!_blacklist[seller], "Seller blacklisted");
// Utility Track: 双方至少KYC L1
if (couponType == CouponType.Utility) {
requireKycLevel(buyer, 1);
requireKycLevel(seller, 1);
}
// Securities Track: 双方至少KYC L2
else {
requireKycLevel(buyer, 2);
requireKycLevel(seller, 2);
}
// 大额交易: KYC L2+
if (amount >= 10000e6) { // $10,000
requireKycLevel(buyer, 2);
requireKycLevel(seller, 2);
}
// 做市商: KYC L3
// 做市商身份由链下服务标记链上通过MARKET_MAKER_ROLE验证
}
/// @notice P2P转移合规路由
function p2pComplianceCheck(
address sender,
address receiver,
uint256 amount
) external {
require(!_blacklist[sender], "Sender blacklisted");
require(!_blacklist[receiver], "Receiver blacklisted");
// ≥$3,000 强制Travel Rule
if (amount >= 3000e6) {
requireKycLevel(sender, 2);
requireKycLevel(receiver, 2);
// Travel Rule数据必须已记录
require(_travelRuleRecorded[sender][receiver], "Travel Rule data required");
}
}
}
```
---
## 16. 验证节点级交易拦截
```go
// genex-chain/x/evm/ante/compliance_ante.go
// 验证节点在打包交易前执行合规检查
type ComplianceAnteHandler struct {
ofacList map[string]bool
travelRule TravelRuleChecker
}
func (h ComplianceAnteHandler) AnteHandle(
ctx sdk.Context, tx sdk.Tx, simulate bool,
) (sdk.Context, error) {
for _, msg := range tx.GetMsgs() {
evmMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok { continue }
from := evmMsg.GetFrom()
to := evmMsg.GetTo()
// 1. OFAC地址拦截链级强制
if h.ofacList[from.Hex()] || h.ofacList[to.Hex()] {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized,
"OFAC sanctioned address, transaction rejected at validator level")
}
// 2. Structuring检测拆分交易规避$3,000阈值
if h.isStructuringPattern(ctx, from, evmMsg.GetValue()) {
// 不拒绝但标记为可疑升级为Travel Rule流程
ctx = ctx.WithValue("suspicious_structuring", true)
}
// 3. Travel Rule预打包检查
if evmMsg.GetValue().Cmp(big.NewInt(3000e6)) >= 0 {
if !h.travelRule.HasRecord(from, *to) {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized,
"Travel Rule: identity data required for transfers >= $3,000")
}
}
}
return ctx, nil
}
```
---
## 17. Treasury合约 — 保障资金锁定
```solidity
// src/Treasury.sol — 补充保障资金逻辑
contract Treasury is Initializable, AccessControlUpgradeable {
IERC20 public stablecoin;
// 发行方保障资金(自愿缴纳,提升信用评级)
mapping(address => uint256) public guaranteeFunds;
// 发行方冻结的销售款(自愿,作为兑付保障)
mapping(address => uint256) public frozenSalesRevenue;
/// @notice 发行方缴纳保障资金
function depositGuaranteeFund(uint256 amount) external {
stablecoin.transferFrom(msg.sender, address(this), amount);
guaranteeFunds[msg.sender] += amount;
emit GuaranteeFundDeposited(msg.sender, amount);
}
/// @notice 发行方违约时启用保障资金赔付
function activateGuaranteeFund(
address issuer,
address[] calldata claimants,
uint256[] calldata amounts
) external onlyRole(GOVERNANCE_ROLE) {
uint256 totalClaim = 0;
for (uint256 i = 0; i < claimants.length; i++) {
totalClaim += amounts[i];
}
require(guaranteeFunds[issuer] >= totalClaim, "Insufficient guarantee fund");
guaranteeFunds[issuer] -= totalClaim;
for (uint256 i = 0; i < claimants.length; i++) {
stablecoin.transfer(claimants[i], amounts[i]);
}
emit GuaranteeFundActivated(issuer, totalClaim);
}
/// @notice 交易资金托管(原子交换中间态)
function escrow(
uint256 orderId,
address buyer,
uint256 amount
) external onlyRole(SETTLER_ROLE) {
stablecoin.transferFrom(buyer, address(this), amount);
emit FundsEscrowed(orderId, buyer, amount);
}
/// @notice 释放托管资金给卖方
function release(
uint256 orderId,
address seller,
uint256 amount,
uint256 platformFee
) external onlyRole(SETTLER_ROLE) {
stablecoin.transfer(seller, amount - platformFee);
// 平台手续费归集
stablecoin.transfer(platformFeeCollector, platformFee);
emit FundsReleased(orderId, seller, amount);
}
}
```
---
## 18. 合约升级回滚能力
```solidity
// src/Governance.sol — 补充回滚能力
contract Governance is Initializable {
// 保留前一版Implementation地址
mapping(address => address) public previousImplementations;
/// @notice 紧急回滚至上一版本需4/5多签
function rollback(address proxy) external {
require(
_getApprovalCount(currentProposalId) >= 4,
"Rollback requires 4/5 multisig"
);
address prevImpl = previousImplementations[proxy];
require(prevImpl != address(0), "No previous version");
// 执行回滚
ITransparentUpgradeableProxy(proxy).upgradeTo(prevImpl);
emit ContractRolledBack(proxy, prevImpl);
}
/// @notice 升级时自动记录前一版本
function _recordPreviousImpl(address proxy, address newImpl) internal {
address currentImpl = ITransparentUpgradeableProxy(proxy).implementation();
previousImplementations[proxy] = currentImpl;
}
}
```
---
## 19. 多稳定币支持
```solidity
// src/Settlement.sol — 补充多稳定币支持
contract Settlement is Initializable, AccessControlUpgradeable {
// 支持多种稳定币
mapping(address => bool) public supportedStablecoins;
// 默认稳定币
address public defaultStablecoin; // USDC
function addStablecoin(address token) external onlyRole(GOVERNANCE_ROLE) {
supportedStablecoins[token] = true;
emit StablecoinAdded(token);
}
/// @notice 原子交换(支持指定稳定币)
function executeSwap(
uint256 tokenId,
address buyer,
address seller,
uint256 price,
address stablecoin // 买方选择的稳定币
) external onlyRole(SETTLER_ROLE) {
require(supportedStablecoins[stablecoin], "Unsupported stablecoin");
// 合规检查 + 原子交换
// ...同原有逻辑使用传入的stablecoin地址
IERC20(stablecoin).transferFrom(buyer, seller, price);
couponContract.safeTransferFrom(seller, buyer, tokenId);
}
}
```
---
## 20. Oracle集成汇率
```solidity
// src/Oracle.sol — 汇率预言机集成
interface IChainlinkPriceFeed {
function latestRoundData() external view returns (
uint80 roundId, int256 answer, uint256 startedAt,
uint256 updatedAt, uint80 answeredInRound
);
}
contract ExchangeRateOracle is Initializable {
// 各币种对USD汇率Feed
mapping(string => address) public priceFeeds;
function getRate(string calldata currency) external view returns (uint256) {
address feed = priceFeeds[currency];
require(feed != address(0), "Unsupported currency");
(, int256 answer,, uint256 updatedAt,) = IChainlinkPriceFeed(feed).latestRoundData();
// 汇率不能太旧最多15分钟
require(block.timestamp - updatedAt <= 900, "Stale price data");
return uint256(answer);
}
}
```
---
## 21. 资产证券化合约 — CBSCoupon-Backed Securities
```solidity
// src/CouponBackedSecurity.sol — 券收益流打包为资产支持证券
// Securities Track + Broker-Dealer牌照下运营
contract CouponBackedSecurity is Initializable, AccessControlUpgradeable {
ICompliance public compliance;
ICoupon public couponContract;
IERC20 public stablecoin;
struct Pool {
uint256[] couponIds; // 底层券资产
uint256 totalFaceValue; // 底层面值总额
uint256 totalShares; // 份额总数
uint256 maturityDate; // 到期日
string creditRating; // 信用评级(由链下评级机构写入)
address issuer; // 池创建方
bool active; // 是否活跃
}
mapping(uint256 => Pool) public pools;
// 份额持有poolId → holder → shares
mapping(uint256 => mapping(address => uint256)) public shares;
uint256 public nextPoolId;
event PoolCreated(uint256 indexed poolId, address indexed issuer, uint256 couponCount, uint256 totalFaceValue);
event SharesPurchased(uint256 indexed poolId, address indexed buyer, uint256 shares, uint256 amount);
event YieldDistributed(uint256 indexed poolId, uint256 totalYield);
/// @notice 创建CBS池 — 将一组券的收益流打包
function createPool(
uint256[] calldata couponIds,
uint256 totalShares,
uint256 maturityDate
) external onlyRole(ISSUER_ROLE) returns (uint256 poolId) {
// 合规检查创建者必须KYC L3 + Broker-Dealer资质
compliance.requireKycLevel(msg.sender, 3);
uint256 totalFace = 0;
for (uint256 i = 0; i < couponIds.length; i++) {
CouponConfig memory config = couponContract.getConfig(couponIds[i]);
require(config.couponType == CouponType.Security, "CBS: only Security coupons");
totalFace += couponContract.getFaceValue(couponIds[i]);
// 锁定底层券到池中
couponContract.safeTransferFrom(msg.sender, address(this), couponIds[i]);
}
poolId = nextPoolId++;
pools[poolId] = Pool({
couponIds: couponIds,
totalFaceValue: totalFace,
totalShares: totalShares,
maturityDate: maturityDate,
creditRating: "",
issuer: msg.sender,
active: true
});
emit PoolCreated(poolId, msg.sender, couponIds.length, totalFace);
}
/// @notice 购买CBS份额 — 仅合格投资者KYC L2+
function purchaseShares(
uint256 poolId,
uint256 shareCount
) external {
compliance.requireKycLevel(msg.sender, 2);
require(pools[poolId].active, "Pool not active");
uint256 price = (pools[poolId].totalFaceValue * shareCount) / pools[poolId].totalShares;
stablecoin.transferFrom(msg.sender, address(this), price);
shares[poolId][msg.sender] += shareCount;
emit SharesPurchased(poolId, msg.sender, shareCount, price);
}
/// @notice 链下评级机构写入信用评级
function setCreditRating(
uint256 poolId,
string calldata rating
) external onlyRole(RATING_AGENCY_ROLE) {
pools[poolId].creditRating = rating;
}
/// @notice 收益分配 — 按份额比例分配到期收益
function distributeYield(uint256 poolId, uint256 totalYield) external onlyRole(SETTLER_ROLE) {
require(block.timestamp >= pools[poolId].maturityDate, "Not matured");
// 按份额比例分配由链下clearing-service计算后调用
emit YieldDistributed(poolId, totalYield);
}
}
```
---
*文档版本: v3.0(量产版)*
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1 + 技术架构开发需求 v3.0*
*技术栈: Cosmos SDK + cosmos/evm + CometBFT + Solidity + Foundry*
*v3.0更新: 去除MVP/阶段性限制,全面进入量产模式 — 开放Securities Track双轨制、CBS资产证券化完整合约、多机构验证节点架构、GNX代币完整模型*