Development reference. Not independently verified for production.
MSG Chain 智能合约与 DApp 开发完全指南
数据来源:MSG Chain 代码库核实
主网状态: No-Go — 当前 MSGChain 主网裁决为 No-Go,以下内容反映代码实际状态,不代表生产可用。
一、MSG Chain 技术全景速览
1.1 区块链核心参数
| 参数 |
值 |
| 共识算法 |
Round-Robin + DAR(去中心化自主轮次) |
| 签名算法 |
Dilithium-5(后量子密码学 PQC) |
| 出块时间 |
5 秒 |
| 最大活跃验证者 |
100 |
| DAR 滞回区间 |
104 / 96 |
| 结算模型 |
双池结算 |
| Gas 分配 |
40/30/20/10(验证者/开发者/燃烧/基金会金库) |
| 重放保护 |
ChainID=1 |
| 智能合约引擎 |
CosmWasm(WASM 虚拟机) |
| 状态存储 |
BadgerDB |
| 跨链 |
bridge_adapter_v1(P1 规划) |
1.2 技术架构分层
AI Agent / dApp 应用层
──────────────────────────────
Agent API (REST) | MCP Server
JSON-RPC 2.0 | gRPC
──────────────────────────────
CosmWasm Smart Contracts
genesis_registry | dao | treasury | agent | micropayment
──────────────────────────────
MSG Chain Node (Round-Robin + DAR)
Dilithium-5 PQC | BadgerDB | libp2p
1.3 已实现的系统合约(10个)
| 合约 |
Canonical Key |
核心能力 |
genesis_registry_v1 |
genesis_registry |
创世注册中心、canonical key 寻址、合约地址查询 |
dao_governance_v1 |
dao_governance |
DAO 治理:提案创建/投票/执行、配置/计票查询 |
foundation_treasury_v2 |
foundation_treasury |
金库多签:创建/签名/执行、阈值查询 |
gas_fee_distribution_v2 |
gas_fee_distribution |
Gas 费用分配、开发者注册、重分配 |
candidate_node_staking_v2 |
candidate_node_staking |
节点质押/解质押/奖励、DAR 窗口 |
validator_qualification_v2 |
validator_qualification |
验证者注册/资格/作恶报告 |
msg_token_cw20 |
— |
CW20 标准代币 |
dar_rating_v1 |
— |
DAR 评分系统 |
block_time_schedule_v1 |
block_time_schedule |
出块时间调度 |
emission_schedule_v2 |
emission_schedule |
代币发行计划 |
1.4 已实现的业务合约(5个)
| 合约 |
类别 |
核心能力 |
agent_payment_v1 |
AI/支付 |
支付意图提交、授权、执行、结算、冻结、挑战 |
agent_registry_v1 |
AI/身份 |
Agent 注册、按能力发现、列表查询 |
ai_agent_constitution_v1 |
AI/治理 |
Agent 宪章查询、策略更新、暂停/撤销 |
aidid_did_registry_v1 |
身份 |
DID 注册/解析/更新/停用、PQ 验证 |
micropayment_session_v1 |
支付 |
微支付会话创建、按秒扣费、关闭结算 |
1.5 当前阶段边界
- 无公开 testnet — 开发环境为本地沙箱(local-first, fail-closed)
- SDK 未正式发布 —
@msg-chain/sdk 为 alpha 候选状态
- 部分写路径为 stub — DeFi、bridge、registry register 标记 X-MSG-Stub=true
- 所有合约 production_ready = false — 需 signed schema release + public E2E trace
- 资金/部署/治理操作必须人工审批 — 不能绕过 DAO/金库多签门禁
- ChainID=1 replay protection — 所有交易带 chainID
- Dilithium-5 后量子签名 — 公钥体系基于 PQC
- Native BankMsg / Gov / Staking / IBC / Stargate 为 fail-closed
二、DApp 完整类型目录(全部含现成参照物)
2.1 AI Agent 经济体
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| A2A 任务市场 |
OKX AI (okx.ai) |
Agent 身份/注册/支付/宪章 |
任务发布/竞标/争议仲裁合约 + 前端 |
| Agent 技能市场 |
OKX Skills Marketplace |
Agent 注册、能力列表 |
技能安装/验证/定价合约 + 前端 |
| Agent 支付网关 |
OKX Agentic Payment |
agent_payment_v1、micropayment_session_v1 |
前端支付面板 |
| Agent 声誉系统 |
Upwork 链上版 |
DID 身份锚定 |
评分/评价/徽章合约 + 前端 |
2.2 治理与 DAO
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| DAO 治理前台 |
Tally.xyz / Snapshot |
dao_governance_v1 提案/投票/执行 |
前端 UI |
| 金库多签管理 |
Gnosis Safe / Multis |
foundation_treasury_v2 多签/阈值 |
前端 UI |
| 治理分析 |
DeepDAO / Boardroom |
dao_governance_v1 查询接口 |
数据聚合+图表 |
| Gas 分配看板 |
— |
gas_fee_distribution_v2 |
前端 UI |
2.3 区块浏览器与数据
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| 区块浏览器 |
Etherscan / Mintscan |
/api/v1/blocks/txs/receipts、Indexer API |
前端+数据库 |
| 链上数据分析 |
Dune Analytics / Covalent |
Indexer 数据平面、RPC 查询 |
SQL 查询引擎+前端 |
| 合约验证器 |
Sourcify / Blockscout |
/api/v1/contracts 元数据 |
验证服务+UI |
2.4 支付与金融
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| 微支付平台 |
SatoshiPay / Coil |
micropayment_session_v1 按秒计费 |
前端付费墙 |
| 流式支付 |
Superfluid / Sablier |
micropayment_session_v1 |
前端仪表盘 |
| 托管支付 |
OKX AI Escrow |
agent_payment_v1 支付意图+结算 |
争议处理前端 |
| Staking 面板 |
Lido / Stader / Figment |
candidate_node_staking_v2 |
前端 UI |
| AMM DEX |
Uniswap V2/V3 |
CosmWasm 合约引擎 |
AMM 合约+前端 |
2.5 去中心化身份
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| DID 面板 |
ENS App / SpruceID |
aidid_did_registry_v1 |
前端 UI |
| 可验证凭证 |
Verite / Ceramic |
DID + PQ 签名 |
VC 颁发/验证合约+前端 |
| 身份聚合 |
Disco / Litentry |
agent_registry_v1 |
跨 DID 聚合 |
2.6 AI Agent 自治
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| Agent 宪章合规 |
World ID + 规则引擎 |
ai_agent_constitution_v1 |
合规审计前端 |
| Agent 自动化 |
Chainlink Keepers |
Agent API 事件订阅 |
触发合约 |
| Agent 沙箱 |
Autonolas |
agent_sandbox_v1(P0 规划) |
执行环境 |
2.7 基础设施工具
| 子类型 |
参照物 |
MSG 已有能力 |
需额外开发 |
| 钱包仪表盘 |
Zapper / Zerion |
Agent API 余额/交易查询 |
前端组合面板 |
| 多签管理 |
Gnosis Safe / Multis |
foundation_treasury_v2 |
前端 |
| 代币浏览器 |
DeBank |
msg_token_cw20 + RPC |
前端 |
| 验证者面板 |
— |
validator_qualification_v2 |
前端 |
三、完整开发手册
3.0 通用开发环境准备
3.0.1 项目初始化
# 前端项目(适用于所有 dApp)
mkdir my-dapp && cd my-dapp
npm create vite@latest . -- --template react-ts
npm install @cosmjs/cosmwasm-stargate @cosmjs/proto-signing @cosmjs/encoding @cosmjs/stargate
npm install @tanstack/react-query wagmi viem
npm install tailwindcss @shadcn/ui lucide-react recharts
npx tailwindcss init -p
3.0.2 cosmjs 客户端封装
// src/lib/cosmos.ts
import { CosmWasmClient, SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
const RPC_ENDPOINT = "http://localhost:26657"; // 本地沙箱
const CHAIN_ID = "msgchain-1";
let cosmWasmClient: CosmWasmClient | null = null;
let signingClient: SigningCosmWasmClient | null = null;
export async function getQueryClient(): Promise<CosmWasmClient> {
if (!cosmWasmClient) {
cosmWasmClient = await CosmWasmClient.connect(RPC_ENDPOINT);
}
return cosmWasmClient;
}
export async function getSigningClient(mnemonic: string): Promise<SigningCosmWasmClient> {
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
prefix: "msg",
gasPrice: GasPrice.fromString("1000000000attoMSG"),
});
signingClient = await SigningCosmWasmClient.connectWithSigner(RPC_ENDPOINT, wallet);
return signingClient;
}
// 通过 genesis_registry_v1 查询合约地址(推荐方式)
export async function resolveContractAddress(canonicalKey: string): Promise<string> {
const client = await getQueryClient();
const registryAddr = "msg1registry..."; // genesis_registry_v1 固定地址
const result = await client.queryContractSmart(registryAddr, {
resolve_contract_address: { canonical_key: canonicalKey },
});
return result.contract_address;
}
3.0.3 Agent API 客户端
// src/lib/agent-api.ts
// 适用于 AI Agent 通过 REST API 查询链状态
const AGENT_API_BASE = "http://localhost:8080";
const AGENT_API_KEY = process.env.VITE_AGENT_API_KEY;
export class AgentAPIClient {
private baseUrl: string;
private apiKey: string;
constructor(baseUrl = AGENT_API_BASE, apiKey = AGENT_API_KEY || "") {
this.baseUrl = baseUrl;
this.apiKey = apiKey;
}
private async fetch(path: string, options?: RequestInit) {
const headers: Record<string, string> = {
"Content-Type": "application/json",
};
if (this.apiKey) headers["X-API-Key"] = this.apiKey;
const res = await fetch(`${this.baseUrl}${path}`, { ...options, headers });
if (!res.ok) throw new Error(`Agent API error: ${res.status}`);
return res.json();
}
// 公开只读查询(无需 API Key)
async getBalance(address: string) {
return this.fetch(`/agent/v1/query/balance/${address}`);
}
async getBlock(height: number) {
return this.fetch(`/agent/v1/query/block/${height}`);
}
async getTx(hash: string) {
return this.fetch(`/agent/v1/query/tx/${hash}`);
}
// 受保护写路径(需 API Key)
async walletTransfer(walletId: string, to: string, amount: string, asset: string) {
return this.fetch(`/agent/v1/wallet/transfer`, {
method: "POST",
body: JSON.stringify({ wallet_id: walletId, to, amount, asset }),
});
}
}
export const agentApi = new AgentAPIClient();
3.0.4 React Hook 基础模式
// src/hooks/useCosmWasm.ts
import { useQuery } from "@tanstack/react-query";
import { getQueryClient } from "../lib/cosmos";
export function useContractQuery<T>(
contractAddress: string,
queryMsg: Record<string, unknown>,
enabled = true
) {
return useQuery<T>({
queryKey: ["contractQuery", contractAddress, queryMsg],
queryFn: async () => {
const client = await getQueryClient();
return client.queryContractSmart(contractAddress, queryMsg);
},
enabled,
});
}
// src/hooks/useAgentAPI.ts
import { useQuery } from "@tanstack/react-query";
import { agentApi } from "../lib/agent-api";
export function useAgentBalance(address: string) {
return useQuery({
queryKey: ["agentBalance", address],
queryFn: () => agentApi.getBalance(address),
enabled: !!address,
});
}
3.1 DAO 治理前台(参考 Tally.xyz)
合约交互封装
// src/contracts/dao.ts
import { resolveContractAddress, getSigningClient, getQueryClient } from "../lib/cosmos";
export interface Proposal {
id: number;
title: string;
description: string;
status: "pending" | "active" | "passed" | "rejected" | "executed";
for_votes: string;
against_votes: string;
abstain_votes: string;
start_height: number;
end_height: number;
proposer: string;
}
export interface ProposalList {
proposals: Proposal[];
}
export class DAOContract {
private contractAddress: string;
constructor(address: string) { this.contractAddress = address; }
static async create() {
const addr = await resolveContractAddress("dao_governance");
return new DAOContract(addr);
}
// 查询
async getProposal(id: number): Promise<Proposal> {
const client = await getQueryClient();
return client.queryContractSmart(this.contractAddress, { proposal: { proposal_id: id } });
}
async listProposals(limit = 20, startAfter?: number): Promise<ProposalList> {
const client = await getQueryClient();
return client.queryContractSmart(this.contractAddress, {
list_proposals: { limit, start_after: startAfter },
});
}
async getConfig() {
const client = await getQueryClient();
return client.queryContractSmart(this.contractAddress, { config: {} });
}
async getVotingPower(address: string): Promise<string> {
const client = await getQueryClient();
const result = await client.queryContractSmart(this.contractAddress, {
voting_power: { address },
});
return result.power;
}
// 写操作
async propose(mnemonic: string, sender: string, title: string, desc: string, msgs: any[], deposit: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.contractAddress, {
propose: { title, description: desc, msgs, deposit },
}, "auto");
}
async vote(mnemonic: string, sender: string, proposalId: number, vote: "yes" | "no" | "abstain" | "veto") {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.contractAddress, {
vote: { proposal_id: proposalId, vote },
}, "auto");
}
async execute(mnemonic: string, sender: string, proposalId: number) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.contractAddress, {
execute: { proposal_id: proposalId },
}, "auto");
}
}
前端页面实现
// src/pages/ProposalsPage.tsx
import { useQuery } from "@tanstack/react-query";
import { ProposalCard } from "../components/dao/ProposalCard";
import { DAOContract } from "../contracts/dao";
import { useWallet } from "../hooks/useWallet";
export function ProposalsPage() {
const { data: dao } = useQuery({
queryKey: ["dao"],
queryFn: () => DAOContract.create(),
});
const { data: proposals } = useQuery({
queryKey: ["proposals"],
queryFn: () => dao?.listProposals(50),
enabled: !!dao,
});
return (
<div className="container mx-auto p-6">
<div className="flex justify-between items-center mb-6">
<h1 className="text-3xl font-bold">Governance</h1>
<button
onClick={() => window.location.href = "/proposals/create"}
className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700"
>
+ New Proposal
</button>
</div>
<div className="grid gap-4">
{proposals?.proposals.map((p) => (
<ProposalCard key={p.id} proposal={p} />
))}
</div>
</div>
);
}
// src/components/dao/ProposalCard.tsx
import type { Proposal } from "../../contracts/dao";
interface Props { proposal: Proposal }
export function ProposalCard({ proposal }: Props) {
const statusColors: Record<string, string> = {
active: "bg-green-100 text-green-800",
passed: "bg-blue-100 text-blue-800",
rejected: "bg-red-100 text-red-800",
executed: "bg-gray-100 text-gray-800",
};
const totalVotes = BigInt(proposal.for_votes)
+ BigInt(proposal.against_votes)
+ BigInt(proposal.abstain_votes);
const forPercent = totalVotes > 0
? (Number(BigInt(proposal.for_votes) * 100n / totalVotes)).toFixed(1)
: "0";
return (
<div className="border rounded-lg p-4 hover:shadow-md transition-shadow">
<div className="flex justify-between items-start mb-3">
<div>
<h3 className="font-semibold text-lg">
<a href={`/proposals/${proposal.id}`} className="hover:text-blue-600">
#{proposal.id} {proposal.title}
</a>
</h3>
<p className="text-sm text-gray-500 mt-1">
by {proposal.proposer.slice(0, 10)}...{proposal.proposer.slice(-6)}
</p>
</div>
<span className={`px-2 py-1 rounded text-xs font-medium ${statusColors[proposal.status]}`}>
{proposal.status.toUpperCase()}
</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2.5 mb-2">
<div
className="bg-green-600 h-2.5 rounded-full"
style={{ width: `${forPercent}%` }}
/>
</div>
<div className="flex gap-4 text-sm text-gray-600">
<span className="text-green-600">For: {proposal.for_votes}</span>
<span className="text-red-600">Against: {proposal.against_votes}</span>
<span className="text-gray-400">Abstain: {proposal.abstain_votes}</span>
</div>
</div>
);
}
页面路由
// src/App.tsx
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ProposalsPage } from "./pages/ProposalsPage";
import { ProposalDetailPage } from "./pages/ProposalDetailPage";
import { CreateProposalPage } from "./pages/CreateProposalPage";
const queryClient = new QueryClient();
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<BrowserRouter>
<Routes>
<Route path="/proposals" element={<ProposalsPage />} />
<Route path="/proposals/:id" element={<ProposalDetailPage />} />
<Route path="/proposals/create" element={<CreateProposalPage />} />
</Routes>
</BrowserRouter>
</QueryClientProvider>
);
}
3.2 区块浏览器(参考 Etherscan / Mintscan)
后端数据服务
// explorer-backend/src/index.ts
import express from "express";
import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { Pool } from "pg";
const app = express();
const client = await CosmWasmClient.connect("http://localhost:26657");
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
// 区块列表
app.get("/api/blocks", async (req, res) => {
const { minHeight, maxHeight } = req.query;
const latest = await client.getHeight();
const from = Number(minHeight) || Math.max(0, latest - 100);
const to = Number(maxHeight) || latest;
const blocks = [];
for (let h = from; h <= to; h++) {
const block = await client.getBlock(h);
blocks.push({
height: block.header.height,
time: block.header.time,
num_txs: block.txs.length,
proposer: block.header.proposerAddress,
});
}
res.json({ blocks, latest });
});
// 交易详情
app.get("/api/tx/:hash", async (req, res) => {
const tx = await client.getTx(req.params.hash);
res.json({
hash: tx.hash,
height: tx.height,
code: tx.code,
gas_used: tx.gasUsed,
raw_log: tx.rawLog,
});
});
// 合约列表(通过 genesis_registry_v1)
app.get("/api/contracts", async (req, res) => {
const registryAddr = "msg1registry...";
const contracts = await client.queryContractSmart(registryAddr, {
list_contracts: { limit: 50 },
});
res.json(contracts);
});
app.listen(3001, () => console.log("Explorer API on :3001"));
前端数据面板
// src/pages/ExplorerPage.tsx
import { useQuery } from "@tanstack/react-query";
interface Block {
height: number;
time: string;
num_txs: number;
proposer: string;
}
export function ExplorerPage() {
const { data } = useQuery<{ blocks: Block[]; latest: number }>({
queryKey: ["blocks"],
queryFn: () => fetch("/api/blocks").then((r) => r.json()),
refetchInterval: 5000, // 每 5 秒刷新
});
return (
<div className="container mx-auto p-6">
<h1 className="text-3xl font-bold mb-2">MSG Chain Explorer</h1>
<p className="text-gray-500 mb-6">Latest Block: {data?.latest}</p>
<div className="bg-white rounded-lg shadow overflow-hidden">
<table className="min-w-full">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Block</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Age</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Txs</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">Proposer</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200">
{data?.blocks.map((block) => (
<tr key={block.height} className="hover:bg-gray-50">
<td className="px-6 py-4">
<a href={`/block/${block.height}`} className="text-blue-600 hover:underline font-mono">
{block.height}
</a>
</td>
<td className="px-6 py-4 text-gray-500">{formatDistance(block.time)}</td>
<td className="px-6 py-4">{block.num_txs}</td>
<td className="px-6 py-4 font-mono text-sm">{truncate(block.proposer)}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
function formatDistance(time: string) {
const seconds = Math.floor((Date.now() - new Date(time).getTime()) / 1000);
if (seconds < 60) return `${seconds}s ago`;
return `${Math.floor(seconds / 60)}m ago`;
}
function truncate(addr: string) {
return `${addr.slice(0, 8)}...${addr.slice(-6)}`;
}
Indexer 数据平面查询
// 通过 MSG Indexer API 获取链上数据
export async function queryIndexer(path: string) {
const res = await fetch(`http://localhost:8080/api/v1/indexer${path}`);
if (!res.ok && res.status === 503) {
throw new Error("Indexer data stale or unavailable (503 fail-closed)");
}
return res.json();
}
// 查询能力
const capabilities = await queryIndexer("/capabilities");
// 查询 retention proof
const retention = await queryIndexer("/retention/proof");
// 搜索交易/区块
const search = await queryIndexer("/memos/search?q=tx_hash");
3.3 微支付平台(参考 SatoshiPay / Superfluid)
合约交互
// src/contracts/micropayment.ts
import { resolveContractAddress, getSigningClient, getQueryClient } from "../lib/cosmos";
export interface MicropaymentSession {
session_id: string;
payer: string;
payee: string;
balance: number;
rate_per_sec: number;
status: "active" | "closed";
charged_total: number;
}
export class MicropaymentContract {
private address: string;
constructor(addr: string) { this.address = addr; }
static async create() {
const addr = await resolveContractAddress("micropayment_session_v1");
return new MicropaymentContract(addr);
}
// 创建微支付会话
async createSession(
mnemonic: string, sender: string,
sessionId: string, payee: string, balance: number, ratePerSec: number
) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
create_session: {
session_id: sessionId,
payer: sender,
payee,
balance,
rate_per_sec: ratePerSec,
terms_hash: `terms_${sessionId}`,
},
}, "auto");
}
// 按秒扣费
async chargeSession(mnemonic: string, sender: string, sessionId: string, elapsedSecs: number) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
charge_session: {
session_id: sessionId,
payer: sender,
elapsed_secs: elapsedSecs,
charge_receipt_hash: `receipt_${sessionId}_${Date.now()}`,
},
}, "auto");
}
// 关闭并结算
async closeSession(mnemonic: string, sender: string, sessionId: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
close_session: {
session_id: sessionId,
payer: sender,
close_receipt_hash: `close_${sessionId}`,
},
}, "auto");
}
// 查询会话
async getSession(sessionId: string): Promise<MicropaymentSession> {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { get_session: { session_id: sessionId } });
}
}
前端实时计费看板
// src/pages/MicropaymentDashboard.tsx
import { useState, useEffect } from "react";
import { MicropaymentContract } from "../contracts/micropayment";
export function MicropaymentDashboard() {
const [session, setSession] = useState<any>(null);
const [cost, setCost] = useState(0);
// 模拟实时计费
useEffect(() => {
if (!session) return;
const interval = setInterval(() => {
setCost((c) => c + session.rate_per_sec);
}, 1000);
return () => clearInterval(interval);
}, [session]);
return (
<div className="container mx-auto p-6">
<h1 className="text-3xl font-bold mb-6">Micropayment Dashboard</h1>
<div className="grid grid-cols-2 gap-6">
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Active Session</h2>
{session ? (
<div>
<p className="text-4xl font-bold text-blue-600">{cost.toFixed(2)} MSG</p>
<p className="text-gray-500 mt-2">Rate: {session.rate_per_sec} MSG/sec</p>
<p className="text-gray-500">Payee: {session.payee}</p>
<p className="text-gray-500">Balance: {session.balance}</p>
</div>
) : (
<p className="text-gray-400">No active session</p>
)}
</div>
<div className="bg-white p-6 rounded-lg shadow">
<h2 className="text-xl font-semibold mb-4">Create Session</h2>
<form className="space-y-4">
<input placeholder="Payee Address" className="w-full p-2 border rounded" />
<input type="number" placeholder="Balance" className="w-full p-2 border rounded" />
<input type="number" placeholder="Rate (MSG/sec)" className="w-full p-2 border rounded" />
<button className="bg-blue-600 text-white px-4 py-2 rounded w-full">
Start Session
</button>
</form>
</div>
</div>
</div>
);
}
3.4 AI Agent 支付网关(参考 OKX AI Agentic Payment)
Agent 支付流程
// src/contracts/agent-payment.ts
// 基于 agent_payment_v1 合约
export class AgentPaymentContract {
private address: string;
constructor(addr: string) { this.address = addr; }
static async create() {
const addr = await resolveContractAddress("agent_payment_v1");
return new AgentPaymentContract(addr);
}
// AI Agent 提交支付意图
async submitIntent(
mnemonic: string, sender: string,
intent: {
payment_id: string;
payer: string;
payee: string;
amount: string;
agent_id: string;
aidid: string;
service_id: string;
intent_hash: string;
}
) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
submit_intent: {
payment_id: intent.payment_id,
payer: intent.payer,
payee: intent.payee,
amount: intent.amount,
agent_id: intent.agent_id,
aidid: intent.aidid,
service_id: intent.service_id,
intent_hash: intent.intent_hash,
idempotency_key: `ip_${intent.payment_id}`,
action: "agent_service_payment",
budget_id: `budget_${intent.agent_id}`,
constitution_hash: "current",
constitution_version: "1",
expiry_unix: Math.floor(Date.now() / 1000) + 3600,
local_guard_hash: "guard_placeholder",
payment_terms_hash: `terms_${intent.payment_id}`,
policy_decision_hash: `decision_${intent.payment_id}`,
policy_id: "default_agent_policy",
remote_signer_id: sender,
runtime_hash: `runtime_${Date.now()}`,
},
}, "auto");
}
// 结算支付
async settle(mnemonic: string, sender: string, paymentId: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
settle_payment: {
payment_id: paymentId,
settler: sender,
settlement_hash: `settle_${paymentId}`,
settlement_receipt_hash: `receipt_${paymentId}`,
},
}, "auto");
}
}
Agent API 集成
// src/lib/agent-payment-integration.ts
// AI Agent 通过 Agent API 自主执行支付
import { agentApi } from "./agent-api";
export async function agentToAgentPayment(
fromAgentId: string,
toAgentId: string,
amount: string,
serviceId: string
) {
// 1. Agent 通过 Agent API 查询自身余额
const balance = await agentApi.getBalance(`agent:${fromAgentId}`);
if (BigInt(balance.balance) < BigInt(amount)) {
throw new Error("Insufficient balance");
}
// 2. Agent 发起支付(受保护写路径,需 API Key)
const result = await agentApi.walletTransfer(
`wallet_${fromAgentId}`,
`agent:${toAgentId}`,
amount,
"umsg"
);
return result;
}
3.5 Staking 仪表盘(参考 Lido / Stader)
合约交互
// src/contracts/staking.ts
export class StakingContract {
private address: string;
constructor(addr: string) { this.address = addr; }
static async create() {
const addr = await resolveContractAddress("candidate_node_staking");
return new StakingContract(addr);
}
// 查询验证者列表
async listCandidates() {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { list_candidates: {} });
}
// 查询质押详情
async getStaker(address: string) {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { staker: { address } });
}
// 质押
async stake(mnemonic: string, sender: string, candidate: string, amount: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
stake: { candidate, amount },
}, "auto");
}
// 领取奖励
async claimRewards(mnemonic: string, sender: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, { claim_rewards: {} }, "auto");
}
}
3.6 DID 身份管理(参考 ENS App / SpruceID)
合约交互
// src/contracts/did.ts
export class DIDContract {
private address: string;
constructor(addr: string) { this.address = addr; }
static async create() {
const addr = await resolveContractAddress("aidid_did_registry_v1");
return new DIDContract(addr);
}
async registerDID(mnemonic: string, sender: string, did: string, publicKey: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
register_did: { did, public_key: publicKey },
}, "auto");
}
async resolveDID(did: string) {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { resolve_did: { did } });
}
async updateDID(mnemonic: string, sender: string, did: string, newPublicKey: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, {
update_did: { did, new_public_key: newPublicKey },
}, "auto");
}
}
3.7 AI Agent 宪章合规面板
// src/contracts/constitution.ts
export class ConstitutionContract {
private address: string;
constructor(addr: string) { this.address = addr; }
static async create() {
const addr = await resolveContractAddress("ai_agent_constitution_v1");
return new ConstitutionContract(addr);
}
// 查询 Agent 宪章状态
async getActiveConstitution() {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { active_constitution: {} });
}
// 查询 Agent 是否合规
async checkActionPolicy(agentId: string, action: string) {
const client = await getQueryClient();
return client.queryContractSmart(this.address, {
check_action_policy: { agent_id: agentId, action },
});
}
// 暂停 Agent(admin only)
async pauseAgent(mnemonic: string, sender: string, agentId: string) {
const client = await getSigningClient(mnemonic);
return client.execute(sender, this.address, { agent_pause: { agent_id: agentId } }, "auto");
}
}
3.8 Genesis Registry 合约地址查询
// src/lib/registry.ts
// genesis_registry_v1 是所有合约寻址的统一入口
export class RegistryContract {
private address = "msg1genesis..."; // genesis_registry_v1 固定地址
async resolveCanonicalKey(key: string) {
const client = await getQueryClient();
const result = await client.queryContractSmart(this.address, {
get_contract_by_canonical_key: { canonical_key: key },
});
if (result.status === "reserved") {
throw new Error(`Canonical key ${key} is reserved (not yet deployed)`);
}
return {
address: result.contract_address,
name: result.contract_name,
status: result.status,
};
}
async listAllMappings() {
const client = await getQueryClient();
return client.queryContractSmart(this.address, { list_canonical_mappings: {} });
}
// 快捷获取所有系统合约地址
async getSystemContracts() {
const keys = [
"dao_governance", "foundation_treasury", "gas_fee_distribution",
"candidate_node_staking", "emission_schedule", "block_time_schedule",
];
const results = await Promise.all(
keys.map((key) => this.resolveCanonicalKey(key).catch(() => null))
);
return Object.fromEntries(keys.map((k, i) => [k, results[i]]));
}
}
四、DApp 开发路线图
4.1 按难度分类
| 难度 |
dApp 类型 |
预估工时 |
| ⭐ |
Agent API 简单查询面板 |
1-2 天 |
| ⭐ |
MSG 代币余额浏览器 |
1-2 天 |
| ⭐⭐ |
DAO 治理前台 |
3-5 天 |
| ⭐⭐ |
Staking 仪表盘 |
3-5 天 |
| ⭐⭐ |
DID 管理面板 |
2-4 天 |
| ⭐⭐⭐ |
区块浏览器 |
1-2 周 |
| ⭐⭐⭐ |
微支付平台 |
1-2 周 |
| ⭐⭐⭐ |
AI Agent 支付网关 |
1-2 周 |
| ⭐⭐⭐⭐ |
AMM DEX |
2-4 周 |
| ⭐⭐⭐⭐ |
Agent 任务市场 |
2-4 周 |
| ⭐⭐⭐⭐⭐ |
完整 OKX AI 复刻 |
8-12 周 |
4.2 推荐学习路径
第一步:基础查询 dApp(1-2 天)
→ 学习 cosmjs 查询
→ 实现余额/区块查询面板
→ 使用 Agent API 只读端点
第二步:链上写操作 dApp(3-5 天)
→ 实现 DAO 治理前台
→ 学习 SigningCosmWasmClient
→ 使用 genesis_registry_v1 寻址
第三步:AI Agent 集成(1-2 周)
→ 学习 Agent API 受保护写路径
→ 实现 agent_payment_v1 集成
→ 实现 ai_agent_constitution_v1 合规检查
第四步:复杂业务 dApp(2-4 周)
→ 实现任务市场/AMM/借贷等
→ 前端实时数据刷新
→ 多合约组合调用
4.3 通用开发检查清单
前置条件:
☐ MSG Chain 本地节点运行中(local sandbox)
☐ cosmjs 安装完成
☐ 钱包助记词已生成(BIP39/Dilithium-5)
合约地址获取(通过 genesis_registry_v1):
☐ 查询 canonical key 获取合约地址
☐ 地址不为 null(非 reserved 状态)
查询功能:
☐ CosmWasmClient.connect 成功
☐ contract query 返回正确格式
☐ 错误处理(合约不存在/参数错误)
写功能:
☐ SigningCosmWasmClient.connectWithSigner 成功
☐ gas 估算正常
☐ 交易广播成功
☐ receipt/tx_hash 可查
前端:
☐ 钱包连接(msg prefix)
☐ 链状态实时刷新
☐ 交易状态展示
☐ 错误状态处理
边界检查:
☐ 处理 reserved 状态的合约
☐ 处理 stub 接口(X-MSG-Stub=true)
☐ 处理 fail-closed(HTTP 503)
☐ 资金操作保留人工审批
五、AI Agent 开发入口与资源
5.1 主要 AI 入口
| 资源 |
链接 |
| AI 控制平面(中心入口) |
https://msgchain.org/whitepaper/modules/ai_control_plane.html |
| AI Agent 接入 |
https://msgchain.org/whitepaper/modules/ai_agent.html |
| AI Task L2 |
https://msgchain.org/whitepaper/modules/ai_task_l2.html |
| AI 权限控制面 |
https://msgchain.org/whitepaper/modules/ai_policy_capability.html |
| AI 钱包 |
https://msgchain.org/whitepaper/modules/ai_wallet.html |
| Agent API 表面 |
https://msgchain.org/whitepaper/modules/agent_api_surface.html |
| 合约引擎 |
https://msgchain.org/whitepaper/modules/contract.html |
| RPC 接口 |
https://msgchain.org/whitepaper/modules/rpc.html |
| 创世注册中心 |
https://msgchain.org/whitepaper/modules/registry.html |
| SDK 表面 |
https://msgchain.org/whitepaper/modules/sdk_dev_surface.html |
| Indexer 数据平面 |
https://msgchain.org/whitepaper/modules/indexer_data_plane.html |
| 区块浏览器 |
https://msgchain.org/whitepaper/modules/explorer.html |
5.2 机器可读入口(适合 AI/RAG 对接)
| 资源 |
链接 |
| Agent Entry |
https://msgchain.org/whitepaper/agent_entry.json |
| Developer Entry |
https://msgchain.org/whitepaper/developer_entry.json |
| 外部 AI Agent 引导提示词 |
https://msgchain.org/whitepaper/integration_examples/external_ai_agent_bootstrap_prompt.md |
| RAG 接入流程 |
https://msgchain.org/whitepaper/integration_examples/rag_ingest_flow.json |
| Agent API OpenAPI 规范 |
https://msgchain.org/whitepaper/api_specs/openapi/agent_surface.yaml |
| 合约 Reference 索引 |
https://msgchain.org/whitepaper/contract_reference/core_contracts.json |
| 业务示例目录 |
https://msgchain.org/whitepaper/examples/business_examples/catalog.json |
| 合约公开查询 OpenAPI |
https://msgchain.org/whitepaper/api_specs/openapi/public_query.yaml |
| 合约表面 OpenAPI |
https://msgchain.org/whitepaper/api_specs/openapi/contract_surface.yaml |
| 快速开始合约/dApp |
https://msgchain.org/whitepaper/quickstart/contract_and_dapp_minimal.json |
5.3 合约 Schema 参考
每个合约公开 Cargo.toml、msg.rs 和 Schema(JSON):
https://msgchain.org/whitepaper/contract_reference/contracts/{合约名}/
├── Cargo.toml
├── src/msg.rs
└── schema/
├── execute_msg.json
├── instantiate_msg.json
├── query_msg.json
└── migrate_msg.json
已有公开 Schema 的合约:
agent_payment_v1
agent_registry_v1
ai_agent_constitution_v1
aidid_did_registry_v1
micropayment_session_v1
dao_governance_v1
foundation_treasury_v2
genesis_registry_v1
candidate_node_staking_v2
validator_qualification_v2
gas_fee_distribution_v2
counter_v1
5.4 Agent API 端点完整列表
公开只读(无需 Key):
| 端点 |
功能 |
/agent/v1/query/account/{addr} |
查询账户信息 |
/agent/v1/query/balance/{addr} |
查询余额 |
/agent/v1/query/balances |
查询所有余额 |
/agent/v1/query/tx/{hash} |
查询交易 |
/agent/v1/query/block/{height} |
查询区块 |
/agent/v1/query/blocks/range |
查询区块范围 |
/agent/v1/events/history |
事件历史 |
/agent/v1/events/subscribe |
WebSocket 事件订阅 |
/agent/v1/oracle/price |
预言机价格 |
受保护写路径(需 API Key):
| 端点 |
功能 |
/agent/v1/wallet/* |
钱包操作 |
/agent/v1/mpc/sign |
MPC 签名编排 |
/agent/v1/payment/session |
支付会话 |
5.5 RPC/API 端点
| 端点族 |
功能 |
状态 |
/broadcast_tx_commit / sync / async |
交易广播 |
已实现 |
/abci_query |
ABCI 查询 |
已实现 |
/tx / /block / /blockchain |
链数据查询 |
已实现 |
/api/v1/blocks / txs / receipts |
浏览器查询 |
已实现 |
/api/v1/contracts/deploy / instantiate / execute |
合约操作 |
已实现 |
/api/v1/tx/transfer / delegate / undelegate |
服务器签名的交易 |
已实现 |
/api/v1/bank/balances / staking/validators |
Cosmos 风格 REST |
已实现 |
/api/v1/search?q=tx_hash_or_block_hash |
哈希搜索(committed index) |
已实现(503 fail-closed) |
/api/v1/indexer/capabilities |
Indexer 能力 |
已实现 |
/api/v1/indexer/retention/proof |
Retention 证明 |
已实现 |
六、AI Agent 开发提示词模板
将此模板输入到任何 AI coding agent(Claude Code / Cursor / OpenClaw),可立即开始 MSG Chain dApp 开发:
你是一个 AI 开发代理,在 MSG Chain 区块链上开发 dApp。
## 链信息
- 合约引擎: CosmWasm(Rust)
- 签名: Dilithium-5(后量子)
- 地址前缀: "msg"
- ChainID: 1
- RPC: http://localhost:26657
- Agent API: http://localhost:8080/agent/v1
## 合约地址获取
通过 genesis_registry_v1 查询 canonical key:
- dao_governance → DAO 治理
- foundation_treasury → 金库多签
- gas_fee_distribution → Gas 分配
- candidate_node_staking → 质押
- agent_payment_v1 → Agent 支付
- agent_registry_v1 → Agent 注册
- aidid_did_registry_v1 → DID 身份
- ai_agent_constitution_v1 → Agent 宪章
- micropayment_session_v1 → 微支付
## 开发资源
- Developer Entry: https://msgchain.org/whitepaper/developer_entry.json
- 合约 Schema: https://msgchain.org/whitepaper/contract_reference/contracts/{合约名}/
- Agent API OpenAPI: https://msgchain.org/whitepaper/api_specs/openapi/agent_surface.yaml
- 外部 AI Agent 引导: https://msgchain.org/whitepaper/integration_examples/external_ai_agent_bootstrap_prompt.md
## 可用工具
- cosmjs: CosmWasmClient(查询)/ SigningCosmWasmClient(写)
- Agent API: /agent/v1/query/*(只读)/ /agent/v1/wallet/*(需 Key)
- Indexer API: /api/v1/indexer/*
## 实现原则
1. 优先使用 genesis_registry_v1 解析合约地址(而非硬编码)
2. 处理 reserved 状态(合约未部署时抛出明确错误)
3. 处理 stub 接口(检查 X-MSG-Stub header)
4. 处理 fail-closed(HTTP 503 时 graceful degradation)
5. 资金操作保留人工审批
6. 所有交易携带 ChainID=1 防止重放
七、DApp 类型速查表
| 类型 |
参照项目 |
核心合约 |
前端复杂度 |
AI 可开发性 |
| DAO 治理 |
Tally.xyz |
dao_governance_v1 |
⭐⭐ |
高 |
| 金库多签 |
Gnosis Safe |
foundation_treasury_v2 |
⭐⭐ |
高 |
| 区块浏览器 |
Etherscan |
RPC + Indexer API |
⭐⭐⭐ |
中 |
| 微支付 |
SatoshiPay |
micropayment_session_v1 |
⭐⭐ |
高 |
| Agent 支付 |
OKX AI |
agent_payment_v1 |
⭐⭐⭐ |
高 |
| Agent 市场 |
OKX AI |
agent_registry_v1 |
⭐⭐⭐ |
中 |
| DID 身份 |
ENS |
aidid_did_registry_v1 |
⭐⭐ |
高 |
| Agent 宪章 |
— |
ai_agent_constitution_v1 |
⭐⭐ |
高 |
| Staking |
Lido |
candidate_node_staking_v2 |
⭐⭐ |
高 |
| 验证者面板 |
— |
validator_qualification_v2 |
⭐ |
高 |
| Gas 看板 |
— |
gas_fee_distribution_v2 |
⭐ |
高 |
| 代币浏览器 |
DeBank |
msg_token_cw20 |
⭐ |
高 |
| AMM DEX |
Uniswap |
CosmWasm 新合约 |
⭐⭐⭐⭐ |
中 |
| A2A 任务市场 |
OKX AI |
新合约 + agent_* |
⭐⭐⭐⭐ |
中 |
| 数据分析 |
Dune |
Indexer API |
⭐⭐⭐ |
中 |
八、推荐开发路径
从 developer_entry.json 开始
developer_entry.json
→ recommended_dapp_bootstrap_order
→ 钱包集成(keplr / cosmjs)
→ Agent API Query 适配器
→ 回执追踪
→ 受限发布审核
快速上手顺序
第1天: 余额查询面板(Agent API /agent/v1/query/balance)
第2天: DAO 治理前台(dao_governance_v1)
第3天: Staking 仪表盘(candidate_node_staking_v2)
第4天: Agent 注册查询(agent_registry_v1)
第5天: 微支付 demo(micropayment_session_v1)
第2周: Agent 支付网关(agent_payment_v1)
第3周: 区块浏览器(RPC + Indexer API)
第4周: A2A 任务市场(新合约 + 前端)