# 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兼容 | 完全兼容（Solidity、Hardhat、MetaMask全套工具链） |
| 出块时间 | **≤ 1秒**（CometBFT即时终结性） |
| TPS | ≥ 5,000（Block-STM并行执行） |
| Gas策略 | 平台前期全额补贴，用户零Gas |
| 原生代币 | GNX（Gas + 治理；前期Gas补贴，用户不接触） |
| 节点运营 | 平台自营验证节点 + 未来开放合格机构节点 |
| 跨链 | 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 1000000000ugnx

# 启动本地节点
./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类型，Securities Track需牌照后启用
        require(config.couponType == CouponType.Utility, "Only Utility Track enabled");

        // Utility Track强制：价格上限 = 面值
        if (config.couponType == CouponType.Utility) {
            require(config.maxPrice <= faceValue, "Utility: maxPrice <= faceValue");
            require(config.expiryDate <= block.timestamp + 365 days, "Utility: max 12 months");
        }

        // 铸造逻辑
        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. 安全规范

- 所有合约上线前必须通过第三方安全审计
- 核心合约采用Transparent Proxy部署
- 升级需3/5多签 + 48小时时间锁
- Bug Bounty计划：严重漏洞奖励$10K-$100K
- MPC/HSM密钥管理
- 合约代码开源并在区块浏览器验证

---

## 12. GNX原生代币经济模型

### 12.1 代币用途

| 用途 | 说明 | 状态 |
|------|------|------|
| **Gas消耗** | 支付交易费用（平台全额补贴） | 已上线 |
| **治理投票** | 参与链参数决策 | 平台内部运行 |
| **质押收益** | 验证节点质押获奖励 | 待法律意见书后开放 |
| **二级市场交易** | 交易所买卖GNX | 待合规审批后开放 |

> GNX当前用于Gas（平台补贴），不上交易所，回避SEC证券风险。质押和二级市场交易需取得法律意见书后开放。

### 12.2 代币分配（预留设计）

```
总供应量: 1,000,000,000 GNX
├── 平台运营/Gas补贴: 40%（4亿）— 前期Gas支出从此池扣除
├── 团队与顾问: 20%（2亿）— 4年线性释放，1年锁定期
├── 生态基金: 15%（1.5亿）— 开发者激励、做市商激励
├── 未来融资预留: 15%（1.5亿）— Reg D/Reg S豁免发行
└── 社区治理: 10%（1亿）— DAO治理基金
```

### 12.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()
}
```

---

## 13. 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]);
        }
    }
}
```

---

## 14. 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");
        }
    }
}
```

---

## 15. 验证节点级交易拦截

```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
}
```

---

## 16. 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);
    }
}
```

---

## 17. 合约升级回滚能力

```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;
    }
}
```

---

## 18. 多稳定币支持

```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);
    }
}
```

---

## 19. 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);
    }
}
```

---

## 20. 资产证券化合约预留（Phase 4）

```solidity
// src/future/CouponBackedSecurity.sol — 预留设计
// Phase 4: 券收益流打包为CBS（Coupon-Backed Securities）
// 仅在Securities Track + Broker-Dealer牌照后启用

/**
 * @notice 预留接口定义，待Securities Track启用后实现
 * - 券收益流打包
 * - 信用评级接口
 * - 收益曲线计算
 */
interface ICouponBackedSecurity {
    function createPool(uint256[] calldata couponIds) external returns (uint256 poolId);
    function getCreditRating(uint256 poolId) external view returns (string memory);
    function getYieldCurve(uint256 poolId) external view returns (uint256[] memory);
}
```

---

*文档版本: v2.0*
*基于: Genex 券交易平台 - 软件需求规格说明书 v4.1 + 技术架构开发需求 v3.0*
*技术栈: Cosmos SDK + cosmos/evm + CometBFT + Solidity + Foundry*
*更新: 补充GNX代币经济/不可转让revert/差异化KYC/验证节点拦截/批量转移/Treasury保障资金/回滚能力/多稳定币/Oracle/资产证券化预留*
