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

18 KiB
Raw Blame History

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,000Block-STM并行执行
Gas策略 平台前期全额补贴用户零Gas
原生代币 GNXGas + 治理前期Gas补贴用户不接触
节点运营 平台自营验证节点 + 未来开放合格机构节点
跨链 IBC连接Cosmos生态 + Axelar桥连接Ethereum

为什么自建链

维度 公链/L2 Genex Chain
Gas控制 受市场波动 平台完全控制,可设为零
合规执行 链层面无法强制 链级OFAC/Travel Rule内置
性能调优 共享资源 独享资源,针对券业务优化
升级自主 依赖链治理 平台自主决定升级
数据主权 完全公开 可控可见性
监管对接 难以定制 专属节点/API

3. 开发环境搭建

3.1 前置依赖

# 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本地开发

# 克隆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 合约开发环境

# 创建合约工程
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 — 券发行工厂

// 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) {
        // MVP阶段只允许Utility类型
        require(config.couponType == CouponType.Utility, "Only Utility Track in MVP");

        // 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 — 交易结算

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 — 兑付合约

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 — 合规合约

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 — 治理合约

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支付。

技术实现

# 创世配置
[app_state.evm.params]
  min_gas_price = "0"

# 或使用ERC-4337 Paymaster

Gas参数通过Governance合约动态调整无需硬分叉


8. 测试策略

8.1 合约测试Foundry

// 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. 部署流程

# 部署到本地测试链
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

合约验证

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密钥管理
  • 合约代码开源并在区块浏览器验证

文档版本: v1.0 基于: Genex 券交易平台 - 软件需求规格说明书 v4.1 + 技术架构开发需求 v3.0 技术栈: Cosmos SDK + cosmos/evm + CometBFT + Solidity + Foundry