rwadurian/backend/mpc-system/MPC_INTEGRATION_GUIDE.md

35 KiB
Executable File
Raw Blame History

MPC-System 集成指南

面向后端服务开发者: 如何与 MPC 分布式签名系统集成,发起密钥生成和签名会话


📚 目录

  1. 系统架构理解
  2. 服务职责说明
  3. 标准 MPC 会话类型
  4. 集成方式
  5. 完整示例代码
  6. 故障排查

1. 系统架构理解

1.1 为什么需要这些服务?

MPC-System 实现了一个真正的分布式多方计算系统,遵循以下核心原则:

核心设计理念:
├── 私钥永不完整存在于任何单点
├── 所有参与方地位对等 (无主从关系)
├── Coordinator 只协调流程,不参与计算
└── 密钥分片物理隔离存储

1.2 架构层次图

┌─────────────────────────────────────────────────────────────────┐
│                    业务层 (您的服务)                             │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐              │
│  │ API Gateway │  │ MPC Service │  │  Wallet App │              │
│  │             │  │             │  │   (前端)    │              │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘              │
│         │                │                │                     │
│         └────────────────┼────────────────┘                     │
│                          ▼                                      │
└──────────────────────────┼──────────────────────────────────────┘
                           │
         ┌─────────────────┼─────────────────┐
         │   MPC-System 边界 (独立部署)       │
         │                 ▼                  │
┌────────┴─────────────────────────────────────────────────────┐
│                   Account Service (入口层)                    │
│  端口: 4000                                                   │
│  职责: ❶ 统一入口 ❷ 账户管理 ❸ 认证授权 ❹ 业务编排           │
│  API: POST /api/v1/mpc/keygen                                │
│       POST /api/v1/mpc/sign                                  │
└──────────────────────┬───────────────────────────────────────┘
                       │
         ┌─────────────┼─────────────────┐
         │             ▼                 │
┌────────┴──────────────────────────────┴──────────────────────┐
│              协调层 (不参与 MPC 计算)                         │
│                                                               │
│  ┌───────────────────────┐    ┌───────────────────────┐     │
│  │ Session Coordinator   │    │   Message Router      │     │
│  │ 端口: 8081/50051      │◄──►│   端口: 8082/50051    │     │
│  ├───────────────────────┤    ├───────────────────────┤     │
│  │ ✓ 会话生命周期管理    │    │ ✓ P2P 消息路由        │     │
│  │ ✓ 参与方注册与认证    │    │ ✓ gRPC Stream 推送    │     │
│  │ ✓ 状态机控制          │    │ ✓ 消息持久化          │     │
│  │ ✓ 超时保护            │    │ ✓ 离线消息缓存        │     │
│  │                       │    │                       │     │
│  │ ✗ 不参与 MPC 计算     │    │ ✗ 不解密 MPC 消息     │     │
│  │ ✗ 不存储密钥分片      │    │ ✗ 不参与 MPC 计算     │     │
│  └───────────────────────┘    └───────────────────────┘     │
└───────────────────────────────────────────────────────────────┘
                       │
         ┌─────────────┼─────────────────┐
         │             ▼                 │
┌────────┴──────────────────────────────┴──────────────────────┐
│           MPC 计算层 (真正执行 TSS 协议的参与方)              │
│                                                               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │ Server Party │  │ Server Party │  │ Server Party │       │
│  │      1       │  │      2       │  │      3       │       │
│  │ (50051)      │  │ (50051)      │  │ (50051)      │       │
│  ├──────────────┤  ├──────────────┤  ├──────────────┤       │
│  │ ✓ 运行 tss-lib│  │ ✓ 运行 tss-lib│  │ ✓ 运行 tss-lib│       │
│  │ ✓ 存储加密分片│  │ ✓ 存储加密分片│  │ ✓ 存储加密分片│       │
│  │ ✓ 参与 TSS   │  │ ✓ 参与 TSS   │  │ ✓ 参与 TSS   │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
│                                                               │
│  ┌──────────────────────────────────────────────────┐        │
│  │        Server Party API (无状态)                 │        │
│  │        端口: 8083                                │        │
│  │  ✓ 为用户设备动态生成密钥分片                     │        │
│  │  ✓ 不存储用户分片(返回给调用方)                   │        │
│  └──────────────────────────────────────────────────┘        │
└───────────────────────────────────────────────────────────────┘

2. 服务职责说明

2.1 Account Service - 为什么需要它?

核心职责: MPC 系统的统一业务入口

存在的原因:

  1. 业务语义转换

    • 外部: "创建钱包账户" → 内部: "发起 2-of-3 keygen 会话 + 3 个参与方"
    • 外部: "交易签名" → 内部: "发起 sign 会话 + 加载账户分片"
  2. 账户生命周期管理

    • 账户创建/激活/暂停/恢复
    • 密钥分片元数据存储 (不是分片本身)
    • 账户恢复流程编排
  3. 认证授权

    • 用户登录验证
    • API 密钥认证
    • JWT 令牌管理
  4. 业务编排

    • 协调 Session Coordinator 创建会话
    • 协调 Server Parties 参与 TSS
    • 聚合结果并持久化

典型数据存储 (PostgreSQL):

-- 账户表 (不存储私钥!)
CREATE TABLE accounts (
    id UUID PRIMARY KEY,
    username VARCHAR(255) UNIQUE NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    public_key BYTEA NOT NULL,           -- 群公钥
    threshold_n INT NOT NULL,            -- 总参与方数
    threshold_t INT NOT NULL,            -- 签名阈值
    status VARCHAR(50) NOT NULL,
    created_at TIMESTAMP NOT NULL
);

-- 分片元数据表 (存储分片在哪,但不存储分片内容)
CREATE TABLE account_shares (
    id UUID PRIMARY KEY,
    account_id UUID REFERENCES accounts(id),
    share_type VARCHAR(50) NOT NULL,     -- user_device / server / recovery
    party_id VARCHAR(255) NOT NULL,
    party_index INT NOT NULL,
    device_type VARCHAR(50),             -- android / ios / server
    storage_location VARCHAR(255),       -- 分片存储位置标识
    is_active BOOLEAN DEFAULT true,
    created_at TIMESTAMP NOT NULL
);

关键点: Account Service 只知道"分片存在于哪里",而不存储实际的加密分片内容。


2.2 Session Coordinator - 会话协调器

核心职责: MPC 会话的生命周期管理器 (但不参与计算)

主要功能:

// 会话状态机
created  waiting  in_progress  completed/failed/expired
  1. 会话创建

    • 生成 session_id
    • 为每个参与方生成 join_token (JWT)
    • 记录会话元数据
  2. 参与方管理

    • 验证参与方身份 (join_token)
    • 追踪参与方状态: invited → joined → ready → computing → completed
    • 控制参与方数量限制
  3. 会话编排

    • 等待所有参与方就绪
    • 触发 TSS 协议启动
    • 收集完成状态
  4. 超时保护

    • 会话过期自动清理
    • 防止僵尸会话占用资源

典型数据存储:

-- 会话表
CREATE TABLE mpc_sessions (
    id UUID PRIMARY KEY,
    session_type VARCHAR(50) NOT NULL,   -- keygen / sign
    threshold_n INT NOT NULL,
    threshold_t INT NOT NULL,
    status VARCHAR(50) NOT NULL,
    message_hash BYTEA,                  -- 签名会话的待签消息
    public_key BYTEA,                    -- keygen 完成后的群公钥
    signature BYTEA,                     -- sign 完成后的签名
    created_at TIMESTAMP NOT NULL,
    expires_at TIMESTAMP NOT NULL
);

-- 参与方表
CREATE TABLE session_participants (
    id UUID PRIMARY KEY,
    session_id UUID REFERENCES mpc_sessions(id),
    party_id VARCHAR(255) NOT NULL,
    party_index INT NOT NULL,
    status VARCHAR(50) NOT NULL,
    device_type VARCHAR(50),
    joined_at TIMESTAMP
);

关键点: Coordinator 只管理会话元数据,从不参与 MPC 计算,也看不到密钥分片。


2.3 Message Router - 消息路由器

核心职责: MPC 参与方之间的通信基础设施

为什么需要独立的消息路由?

TSS 协议需要参与方之间频繁交换消息 (通常 3-9 轮):

Round 1: Party 0 → Party 1, Party 2  (承诺值)
Round 2: Party 1 → Party 0, Party 2  (秘密分享)
Round 3: 所有参与方互相广播          (验证值)
...

如果没有统一路由器,每个参与方需要:

  • 知道所有其他参与方的网络地址
  • 维护 N² 个连接
  • 处理离线消息重传

Message Router 解决的问题:

  1. P2P 消息中继

    • 统一的消息入口
    • 自动路由到目标参与方
    • 支持广播和点对点
  2. 实时推送 (gRPC Stream)

    rpc SubscribeMessages(SubscribeRequest) returns (stream MPCMessage);
    
    • 长连接推送消息
    • 低延迟 (毫秒级)
  3. 消息持久化

    • 离线参与方的消息缓存
    • 消息去重和排序
    • 支持轮询回退 (如果 Stream 不可用)
  4. 安全性

    • 消息是端到端加密的 (tss-lib 加密)
    • Router 只转发,不解密内容
    • 按 session_id 隔离

典型数据流:

Party 0 (tss-lib) → Message Router → Party 1 (tss-lib)
     ↓                                      ↑
加密消息 payload                       原样转发
(Router 看不懂)                      (不解密)

2.4 Server Parties - MPC 计算节点

核心职责: 真正执行 TSS 协议的参与方

特点:

  1. 运行完整的 tss-lib

    • 与客户端地位完全对等
    • 执行相同的 Keygen/Signing 算法
  2. 存储加密的密钥分片

    Server Party 1 → 分片 1 (AES-256-GCM 加密) → PostgreSQL
    Server Party 2 → 分片 2 (AES-256-GCM 加密) → PostgreSQL
    Server Party 3 → 分片 3 (AES-256-GCM 加密) → PostgreSQL
    
  3. 物理隔离

    • 3 个 Party 独立部署 (可以在不同服务器)
    • 互相看不到对方的分片
    • 任意 2 个被攻破也无法重建私钥
  4. 自动参与会话

    • 监听 Session Coordinator 的事件
    • 自动加入指定的 keygen/sign 会话
    • 完成后上报结果

2.5 Server Party API - 用户分片生成服务

核心职责: 为用户设备提供临时分片生成 (无状态)

为什么需要它?

场景: 用户在手机 App 上创建钱包

问题: 手机端无法直接参与服务端的 MPC 会话 (网络/性能限制)
解决: Server Party API 代表用户参与一次 keygen生成分片后返回

工作流程:

1. 手机 App 调用: POST /api/v1/keygen/generate-user-share
   ↓
2. Server Party API:
   - 代表用户加入 MPC 会话
   - 与 Server Party 1, 2 执行 TSS Keygen
   - 获得用户的密钥分片
   ↓
3. 返回加密分片给手机
   ↓
4. 手机存储到 Android KeyStore / iOS Secure Enclave
   ↓
5. Server Party API 丢弃分片 (不存储)

关键特性:

  • 无状态: 不存储任何分片
  • 即时返回: 同步 API (等待 keygen 完成)
  • 端到端加密: 可选用户公钥加密分片

2.6 服务间关系总结

┌──────────────────────────────────────────────────────┐
│  关系矩阵                                            │
├──────────────────────────────────────────────────────┤
│                                                      │
│  Account Service                                     │
│       ├─ 调用 → Session Coordinator (创建会话)      │
│       ├─ 调用 → Server Party API (生成用户分片)     │
│       └─ 查询 → Session Coordinator (会话状态)      │
│                                                      │
│  Session Coordinator                                 │
│       ├─ 读写 → PostgreSQL (会话元数据)             │
│       ├─ 发布 → RabbitMQ (会话事件)                 │
│       └─ 被调用 ← Server Parties (加入会话)         │
│                                                      │
│  Message Router                                      │
│       ├─ 转发 → MPC 消息 (端到端加密)               │
│       ├─ 持久化 → PostgreSQL (离线消息)             │
│       └─ Stream → gRPC Stream (实时推送)            │
│                                                      │
│  Server Parties                                      │
│       ├─ 监听 → RabbitMQ (会话创建事件)             │
│       ├─ 调用 → Session Coordinator (加入会话)      │
│       ├─ 通信 → Message Router (交换 MPC 消息)      │
│       └─ 存储 → PostgreSQL (加密分片)               │
│                                                      │
│  Server Party API                                    │
│       ├─ 调用 → Session Coordinator (加入会话)      │
│       ├─ 通信 → Message Router (交换 MPC 消息)      │
│       └─ 返回 → 用户分片 (不存储)                   │
│                                                      │
└──────────────────────────────────────────────────────┘

3. 标准 MPC 会话类型

3.1 Keygen 会话 (密钥生成)

目的: 分布式生成 ECDSA 密钥对,无任何单点知道完整私钥

参与方配置:

{
  "threshold_n": 3,           // 总共 3 个参与方
  "threshold_t": 2,           // 至少 2 个参与方才能签名
  "participants": [
    {
      "party_id": "user_device_001",
      "device_type": "android"
    },
    {
      "party_id": "server_party_1",
      "device_type": "server"
    },
    {
      "party_id": "server_party_2",
      "device_type": "server"
    }
  ]
}

输出:

{
  "public_key": "04a1b2c3d4...",        // 群公钥 (以太坊地址)
  "shares": [
    {
      "party_id": "user_device_001",
      "share_data": "encrypted_share_1"  // 用户分片 (加密)
    },
    {
      "party_id": "server_party_1",
      "share_data": "encrypted_share_2"  // 服务端存储
    },
    {
      "party_id": "server_party_2",
      "share_data": "encrypted_share_3"  // 服务端存储
    }
  ]
}

常见阈值方案:

方案 场景 参与方 优势
2-of-3 个人钱包 用户设备 + 2 个服务器 用户 + 1 个服务器即可签名
3-of-5 企业多签 5 个高管 需要 3 人同意 (民主决策)
2-of-2 两方托管 用户 + 服务商 必须双方同意
4-of-7 高安全审批 7 个董事会成员 需要过半数同意

3.2 Sign 会话 (门限签名)

目的: 使用密钥分片对消息进行 ECDSA 签名

参与方配置:

{
  "account_id": "uuid-of-account",
  "message_hash": "a1b2c3d4...",       // 待签消息 (SHA-256)
  "participants": [
    {
      "party_id": "user_device_001",
      "share_data": "encrypted_share"  // 用户提供本地分片
    },
    {
      "party_id": "server_party_1"     // 服务端自动加载分片
    }
  ]
}

注意: Sign 会话只需要 threshold_t 个参与方 (例如 2-of-3 中的 2 个)

输出:

{
  "signature": "3045022100...",         // DER 编码签名
  "r": "a1b2c3d4...",                  // 签名 R 值
  "s": "e5f6g7h8...",                  // 签名 S 值
  "v": 0                               // 恢复 ID (以太坊需要)
}

验证签名:

// 以太坊 / 比特币标准验证
const publicKey = "04a1b2c3d4...";
const messageHash = "hash_of_transaction";
const signature = { r, s, v };

const isValid = ecrecover(messageHash, signature) === publicKey;

3.3 恢复会话 (密钥恢复)

场景: 用户丢失手机,需要恢复钱包

两种恢复方案:

方案 A: 使用恢复分片 (推荐)

初始 Keygen: user_device + server_1 + recovery_backup (3 方)
用户丢失设备后:
  → 使用 recovery_backup + server_1 执行 Sign (2-of-3 仍可用)
  → 生成新的 user_device_new 分片 (重新 keygen)

方案 B: 社交恢复

初始 Keygen: user + server + guardian_1 + guardian_2 + guardian_3 (5 方, 3-of-5)
用户丢失设备后:
  → 联系 3 个 guardians
  → 执行新的 keygen 生成新分片

4. 集成方式

4.1 推荐架构

┌────────────────────────────────────────────────┐
│          您的后端服务架构                       │
│                                                │
│  ┌──────────────┐      ┌──────────────┐       │
│  │ API Gateway  │      │ Wallet Service│      │
│  │ (Kong/Nginx) │─────►│              │       │
│  └──────────────┘      │ • 用户管理   │       │
│                        │ • 交易构建   │       │
│                        │ • 余额查询   │       │
│                        └───────┬──────┘       │
│                                │               │
└────────────────────────────────┼───────────────┘
                                 │
                    调用 MPC-System API
                                 │
┌────────────────────────────────▼───────────────┐
│          MPC-System (独立部署)                  │
│  ┌──────────────────────────────────────┐      │
│  │ Account Service: http://mpc:4000     │      │
│  └──────────────────────────────────────┘      │
└────────────────────────────────────────────────┘

4.2 环境配置

方式 1: Docker Compose (开发/测试)

# docker-compose.yml
version: '3.8'

services:
  # 您的服务
  wallet-service:
    build: ./wallet-service
    environment:
      - MPC_BASE_URL=http://mpc-account-service:4000
      - MPC_API_KEY=your_secure_api_key
    depends_on:
      - mpc-account-service

  # MPC 系统 (一键部署)
  mpc-account-service:
    image: rwadurian/mpc-account-service:latest
    ports:
      - "4000:8080"
    environment:
      - MPC_API_KEY=your_secure_api_key
      - DATABASE_URL=postgresql://...
    depends_on:
      - mpc-session-coordinator
      - mpc-postgres

  mpc-session-coordinator:
    image: rwadurian/mpc-session-coordinator:latest
    # ... 其他配置

  # ... 其他 MPC 服务

方式 2: Kubernetes (生产)

# values.yaml
mpc:
  accountService:
    enabled: true
    replicaCount: 3
    image: rwadurian/mpc-account-service:v1.0.0

  sessionCoordinator:
    enabled: true
    replicaCount: 2

  serverParties:
    count: 3
    resources:
      requests:
        memory: "2Gi"
        cpu: "1000m"

5. 完整示例代码

5.1 场景: 用户创建钱包

步骤 1: 创建 Keygen 会话

# HTTP API
POST http://mpc-account-service:4000/api/v1/mpc/keygen
Content-Type: application/json
X-API-Key: your_api_key

{
  "threshold_n": 3,
  "threshold_t": 2,
  "participants": [
    {
      "party_id": "user_device_12345",
      "device_type": "android",
      "device_id": "android_device_uuid"
    },
    {
      "party_id": "server_party_1",
      "device_type": "server",
      "platform": "linux"
    },
    {
      "party_id": "server_party_2",
      "device_type": "server",
      "platform": "linux"
    }
  ]
}

响应:

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "session_type": "keygen",
  "threshold_n": 3,
  "threshold_t": 2,
  "join_tokens": {
    "user_device_12345": "eyJhbGciOiJIUzI1NiIs...",
    "server_party_1": "eyJhbGciOiJIUzI1NiIs...",
    "server_party_2": "eyJhbGciOiJIUzI1NiIs..."
  },
  "status": "created"
}

步骤 2: 为用户生成分片

# 调用 Server Party API 代表用户参与 keygen
POST http://mpc-server-party-api:8083/api/v1/keygen/generate-user-share
Content-Type: application/json
X-API-Key: your_api_key

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "party_id": "user_device_12345",
  "join_token": "eyJhbGciOiJIUzI1NiIs...",
  "user_public_key": "optional_hex_for_e2e_encryption"
}

响应 (大约 30-90 秒后):

{
  "success": true,
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "party_id": "user_device_12345",
  "party_index": 0,
  "share_data": "a1b2c3d4e5f6...",          // 加密的用户分片 (hex)
  "public_key": "04a1b2c3d4e5f6..."         // 群公钥
}

步骤 3: 将分片和公钥返回给用户

// 前端 (React Native / Flutter)
const response = await createWallet(userId);

// 存储分片到设备安全存储
await SecureStore.setItemAsync(
  `wallet_share_${userId}`,
  response.share_data
);

// 存储公钥 (用于显示地址)
const ethereumAddress = publicKeyToAddress(response.public_key);
await AsyncStorage.setItem(`wallet_address_${userId}`, ethereumAddress);

5.2 场景: 用户签名交易

步骤 1: 构建交易并计算哈希

// 后端: 构建以太坊交易
const txParams = {
  to: "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
  value: ethers.utils.parseEther("1.0"),
  gasLimit: 21000,
  gasPrice: ethers.utils.parseUnits("50", "gwei"),
  nonce: await provider.getTransactionCount(walletAddress),
  chainId: 1
};

const txHash = ethers.utils.keccak256(
  ethers.utils.serializeTransaction(txParams)
);
// txHash: 0xa1b2c3d4e5f6...

步骤 2: 创建 Sign 会话

POST http://mpc-account-service:4000/api/v1/mpc/sign
Content-Type: application/json
X-API-Key: your_api_key

{
  "account_id": "user_account_uuid",
  "message_hash": "a1b2c3d4e5f6...",         // 去掉 0x 前缀
  "participants": [
    {
      "party_id": "user_device_12345",
      "device_type": "android"
    },
    {
      "party_id": "server_party_1",
      "device_type": "server"
    }
  ]
}

响应:

{
  "session_id": "660e8400-e29b-41d4-a716-446655440001",
  "session_type": "sign",
  "account_id": "user_account_uuid",
  "message_hash": "a1b2c3d4e5f6...",
  "threshold_t": 2,
  "join_tokens": {
    "user_device_12345": "eyJhbGciOiJIUzI1NiIs...",
    "server_party_1": "eyJhbGciOiJIUzI1NiIs..."
  },
  "status": "created"
}

步骤 3: 使用用户分片参与签名

POST http://mpc-server-party-api:8083/api/v1/sign/with-user-share
Content-Type: application/json
X-API-Key: your_api_key

{
  "session_id": "660e8400-e29b-41d4-a716-446655440001",
  "party_id": "user_device_12345",
  "join_token": "eyJhbGciOiJIUzI1NiIs...",
  "share_data": "a1b2c3d4e5f6...",           // 用户的加密分片 (从设备存储读取)
  "message_hash": "a1b2c3d4e5f6..."
}

响应 (大约 5-15 秒后):

{
  "success": true,
  "session_id": "660e8400-e29b-41d4-a716-446655440001",
  "party_id": "user_device_12345",
  "signature": "3045022100a1b2c3...",
  "r": "a1b2c3d4e5f6...",
  "s": "e5f6g7h8i9j0...",
  "v": 0
}

步骤 4: 广播交易到区块链

// 组装完整签名
const signedTx = ethers.utils.serializeTransaction(txParams, {
  r: "0x" + response.r,
  s: "0x" + response.s,
  v: response.v
});

// 广播到以太坊网络
const txResponse = await provider.sendTransaction(signedTx);
const receipt = await txResponse.wait();

console.log("Transaction hash:", receipt.transactionHash);

5.3 Go SDK 示例

package main

import (
    "context"
    "fmt"
    "github.com/rwadurian/mpc-client-sdk-go"
)

func main() {
    // 初始化 MPC 客户端
    client := mpc.NewClient(&mpc.Config{
        BaseURL: "http://mpc-account-service:4000",
        APIKey:  "your_api_key",
        Timeout: 5 * time.Minute,
    })

    ctx := context.Background()

    // 创建钱包
    keygenReq := &mpc.KeygenRequest{
        ThresholdN: 3,
        ThresholdT: 2,
        Participants: []mpc.Participant{
            {PartyID: "user_device", DeviceType: "android"},
            {PartyID: "server_party_1", DeviceType: "server"},
            {PartyID: "server_party_2", DeviceType: "server"},
        },
    }

    keygenResp, err := client.CreateKeygen(ctx, keygenReq)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Session ID: %s\n", keygenResp.SessionID)
    fmt.Printf("Join Token: %s\n", keygenResp.JoinTokens["user_device"])

    // 生成用户分片
    shareReq := &mpc.GenerateUserShareRequest{
        SessionID: keygenResp.SessionID,
        PartyID:   "user_device",
        JoinToken: keygenResp.JoinTokens["user_device"],
    }

    shareResp, err := client.GenerateUserShare(ctx, shareReq)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Public Key: %s\n", shareResp.PublicKey)
    fmt.Printf("User Share: %s\n", shareResp.ShareData)

    // 存储分片到数据库
    // ...

    // 稍后签名交易
    signReq := &mpc.SignRequest{
        AccountID:   "user_account_uuid",
        MessageHash: "a1b2c3d4e5f6...",
        Participants: []mpc.SignParticipant{
            {PartyID: "user_device", ShareData: shareResp.ShareData},
            {PartyID: "server_party_1"},
        },
    }

    signResp, err := client.CreateSign(ctx, signReq)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Signature R: %s\n", signResp.R)
    fmt.Printf("Signature S: %s\n", signResp.S)
}

5.4 Python SDK 示例

from mpc_client import MPCClient

# 初始化客户端
client = MPCClient(
    base_url="http://mpc-account-service:4000",
    api_key="your_api_key"
)

# 创建钱包
keygen_response = client.create_keygen(
    threshold_n=3,
    threshold_t=2,
    participants=[
        {"party_id": "user_device", "device_type": "ios"},
        {"party_id": "server_party_1", "device_type": "server"},
        {"party_id": "server_party_2", "device_type": "server"},
    ]
)

print(f"Session ID: {keygen_response.session_id}")

# 生成用户分片
share_response = client.generate_user_share(
    session_id=keygen_response.session_id,
    party_id="user_device",
    join_token=keygen_response.join_tokens["user_device"]
)

print(f"Public Key: {share_response.public_key}")
print(f"User Share: {share_response.share_data}")

# 签名交易
sign_response = client.sign_transaction(
    account_id="user_account_uuid",
    message_hash="a1b2c3d4e5f6...",
    participants=[
        {"party_id": "user_device", "share_data": share_response.share_data},
        {"party_id": "server_party_1"}
    ]
)

print(f"Signature: {sign_response.signature}")

6. 故障排查

6.1 常见错误

错误 1: "session not found"

原因: 会话已过期或不存在

解决:

# 检查会话状态
GET http://mpc-account-service:4000/api/v1/mpc/sessions/{session_id}

# 会话默认 10 分钟过期,确保在有效期内完成操作

错误 2: "insufficient participants"

原因: 参与方数量不足

解决:

// 确保 Sign 会话至少有 threshold_t 个参与方
{
  "account_id": "...",
  "participants": [
    {"party_id": "user_device"},
    {"party_id": "server_party_1"}  // 2-of-3 需要至少 2 个
  ]
}

错误 3: "invalid join token"

原因: Token 过期或被篡改

解决:

  • 重新创建会话获取新 token
  • 检查服务端时钟同步 (JWT 依赖时间)

错误 4: "keygen failed: timeout"

原因: TSS 协议执行超时

排查步骤:

# 1. 检查 Server Parties 是否都在运行
docker compose ps | grep server-party

# 2. 查看 Message Router 日志
docker compose logs message-router | grep ERROR

# 3. 检查网络连通性
docker compose exec server-party-1 nc -zv message-router 50051

6.2 性能优化

Keygen 性能

阈值方案 预期时间 优化建议
2-of-3 30-60s 正常
3-of-5 90-120s 增加 CPU 资源
4-of-7 180-240s 考虑异步处理

Sign 性能

阈值方案 预期时间 优化建议
2-of-3 5-10s 正常
3-of-5 10-15s 使用 gRPC Stream
4-of-7 15-20s 批量签名

并发优化

# docker-compose.yml
services:
  mpc-session-coordinator:
    deploy:
      replicas: 3           # 水平扩展
      resources:
        limits:
          cpus: '2'
          memory: 2G

6.3 监控指标

关键指标:

# Prometheus metrics
mpc_keygen_duration_seconds{quantile="0.95"} < 120
mpc_sign_duration_seconds{quantile="0.95"} < 15
mpc_session_success_rate > 0.99
mpc_active_sessions < 100

日志示例:

[INFO] Session 550e8400 created: type=keygen, participants=3
[INFO] Party user_device joined session 550e8400
[INFO] Party server_party_1 joined session 550e8400
[INFO] Session 550e8400 started: all parties ready
[INFO] Keygen completed: session=550e8400, duration=45.2s

7. 安全建议

7.1 API 密钥管理

# 生成强密钥
openssl rand -base64 48

# 环境变量方式 (推荐)
export MPC_API_KEY="your_generated_key"

# 定期轮换 (每 90 天)

7.2 网络隔离

# docker-compose.yml
networks:
  mpc-internal:
    internal: true              # 内部服务网络

  public:
    driver: bridge              # 外部访问网络

services:
  mpc-account-service:
    networks:
      - public                  # 暴露给外部
      - mpc-internal

  mpc-session-coordinator:
    networks:
      - mpc-internal            # 仅内部访问

7.3 审计日志

-- 记录所有 MPC 操作
CREATE TABLE mpc_audit_logs (
    id SERIAL PRIMARY KEY,
    session_id UUID NOT NULL,
    operation VARCHAR(50) NOT NULL,
    user_id VARCHAR(255),
    ip_address INET,
    user_agent TEXT,
    request_body JSONB,
    response_status INT,
    created_at TIMESTAMP DEFAULT NOW()
);

-- 查询异常活动
SELECT * FROM mpc_audit_logs
WHERE response_status >= 400
AND created_at > NOW() - INTERVAL '1 hour';

8. 附录

8.1 完整 API 参考

详细 API 文档请参考:

8.2 SDK 下载

  • Go SDK: go get github.com/rwadurian/mpc-client-sdk-go
  • Python SDK: pip install mpc-client-sdk
  • JavaScript SDK: npm install @rwadurian/mpc-client-sdk

8.3 联系支持


文档版本: 1.0.0 最后更新: 2025-12-05 适用于: MPC-System v1.0.0+