#!/bin/bash # ============================================================================= # 热钱包 MPC 初始化脚本 # ============================================================================= # # 用途: 创建系统热钱包的 MPC 密钥,用于提现转账 # # 前提条件: # 1. mpc-service 正在运行 # 2. mpc-system 正在运行且所有 party 已启动 # # 使用方法: # ./init-hot-wallet.sh [options] # # 选项: # -u, --username 热钱包用户名 (默认: system-hot-wallet) # -n, --threshold-n 总 party 数量 (默认: 3) # -t, --threshold-t 签名门限值 (默认: 2) # -h, --host mpc-service 地址 (默认: http://localhost:3013) # --help 显示帮助 # # ============================================================================= set -e # 默认配置 USERNAME="system-hot-wallet" THRESHOLD_N=3 THRESHOLD_T=2 MPC_HOST="http://localhost:3013" # 解析参数 while [[ $# -gt 0 ]]; do case $1 in -u|--username) USERNAME="$2" shift 2 ;; -n|--threshold-n) THRESHOLD_N="$2" shift 2 ;; -t|--threshold-t) THRESHOLD_T="$2" shift 2 ;; -h|--host) MPC_HOST="$2" shift 2 ;; --help) head -30 "$0" | tail -25 exit 0 ;; *) echo "未知参数: $1" exit 1 ;; esac done echo "==============================================" echo "热钱包 MPC 初始化" echo "==============================================" echo "用户名: $USERNAME" echo "门限: $THRESHOLD_T-of-$THRESHOLD_N" echo "MPC 服务: $MPC_HOST" echo "==============================================" echo "" # Step 1: 创建 Keygen 会话 echo "[1/4] 创建 Keygen 会话..." KEYGEN_RESPONSE=$(curl -s -X POST "$MPC_HOST/mpc/keygen" \ -H "Content-Type: application/json" \ -d "{ \"username\": \"$USERNAME\", \"thresholdN\": $THRESHOLD_N, \"thresholdT\": $THRESHOLD_T, \"requireDelegate\": true }") SESSION_ID=$(echo "$KEYGEN_RESPONSE" | jq -r '.sessionId') STATUS=$(echo "$KEYGEN_RESPONSE" | jq -r '.status') if [ "$SESSION_ID" == "null" ] || [ -z "$SESSION_ID" ]; then echo "错误: 创建 Keygen 会话失败" echo "响应: $KEYGEN_RESPONSE" exit 1 fi echo "会话 ID: $SESSION_ID" echo "状态: $STATUS" echo "" # Step 2: 轮询等待 Keygen 完成 echo "[2/4] 等待 Keygen 完成..." MAX_ATTEMPTS=180 # 最多等待 6 分钟 ATTEMPT=0 PUBLIC_KEY="" while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do STATUS_RESPONSE=$(curl -s -X GET "$MPC_HOST/mpc/keygen/$SESSION_ID/status") STATUS=$(echo "$STATUS_RESPONSE" | jq -r '.status') PUBLIC_KEY=$(echo "$STATUS_RESPONSE" | jq -r '.publicKey // empty') echo " 轮询 #$((ATTEMPT + 1)): 状态=$STATUS" if [ "$STATUS" == "completed" ]; then echo "" echo "Keygen 完成!" break fi if [ "$STATUS" == "failed" ] || [ "$STATUS" == "expired" ]; then echo "" echo "错误: Keygen 失败,状态=$STATUS" exit 1 fi ATTEMPT=$((ATTEMPT + 1)) sleep 2 done if [ "$STATUS" != "completed" ]; then echo "错误: Keygen 超时" exit 1 fi # Step 3: 显示公钥 echo "" echo "[3/4] 获取公钥..." if [ -z "$PUBLIC_KEY" ]; then # 再次获取状态以确保拿到公钥 STATUS_RESPONSE=$(curl -s -X GET "$MPC_HOST/mpc/keygen/$SESSION_ID/status") PUBLIC_KEY=$(echo "$STATUS_RESPONSE" | jq -r '.publicKey') fi if [ -z "$PUBLIC_KEY" ] || [ "$PUBLIC_KEY" == "null" ]; then echo "错误: 无法获取公钥" exit 1 fi echo "公钥: $PUBLIC_KEY" # Step 4: 从公钥派生 EVM 地址 echo "" echo "[4/4] 派生 EVM 地址..." # 使用 node 计算地址(如果安装了 ethers) if command -v node &> /dev/null; then ADDRESS=$(node -e " const { computeAddress } = require('ethers'); try { const address = computeAddress('0x$PUBLIC_KEY'); console.log(address); } catch (e) { console.error('Error:', e.message); process.exit(1); } " 2>/dev/null || echo "") if [ -n "$ADDRESS" ] && [ "$ADDRESS" != "Error:"* ]; then echo "EVM 地址: $ADDRESS" else echo "提示: 无法自动计算地址,请手动计算" echo "公钥 (hex): $PUBLIC_KEY" fi else echo "提示: 未安装 Node.js,请手动从公钥计算 EVM 地址" echo "公钥 (hex): $PUBLIC_KEY" fi echo "" echo "==============================================" echo "初始化完成!" echo "==============================================" echo "" echo "请将以下配置添加到 blockchain-service 的环境变量:" echo "" echo " HOT_WALLET_USERNAME=$USERNAME" if [ -n "$ADDRESS" ] && [ "$ADDRESS" != "Error:"* ]; then echo " HOT_WALLET_ADDRESS=$ADDRESS" else echo " HOT_WALLET_ADDRESS=<从公钥计算的地址>" fi echo "" echo "=============================================="