18 KiB
18 KiB
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 前置依赖
# 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