quick_consolidate.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #!/bin/bash
  2. # 快速UTXO归集脚本
  3. # 简化版本,用于快速归集所有notes到指定地址
  4. set -e
  5. # 默认配置
  6. DEFAULT_FEE=1
  7. DEFAULT_MASTER_PUBKEY="33zmSubiizyAVzeSfKbVtLMKifm5u6VaTt9wae5K4CT6h5PLXovecjYwxwDXuzfKVsuefe1wh2VJVHAh4nbA53zBiXKf2Nc3fN3sVmZpmPWneUYGbWcXKzhmN714DVbzaS9U"
  8. # 颜色输出
  9. GREEN='\033[0;32m'
  10. BLUE='\033[0;34m'
  11. NC='\033[0m'
  12. print_info() {
  13. echo -e "${BLUE}[INFO]${NC} $1"
  14. }
  15. print_success() {
  16. echo -e "${GREEN}[SUCCESS]${NC} $1"
  17. }
  18. # 显示帮助
  19. show_help() {
  20. echo "快速UTXO归集脚本"
  21. echo ""
  22. echo "用法: $0 [选项]"
  23. echo ""
  24. echo "选项:"
  25. echo " -m, --master-pubkey PUBKEY 主公钥地址 (默认: $DEFAULT_MASTER_PUBKEY)"
  26. echo " -r, --recipient PUBKEY 接收地址 (默认: 使用主公钥)"
  27. echo " -f, --fee FEE 手续费 (默认: $DEFAULT_FEE nicks)"
  28. echo " -h, --help 显示帮助"
  29. echo ""
  30. echo "示例:"
  31. echo " $0 # 归集所有notes到主公钥地址"
  32. echo " $0 --fee 2 # 使用2 nicks手续费"
  33. echo " $0 --recipient PUBKEY # 归集到指定地址"
  34. }
  35. # 解析参数
  36. MASTER_PUBKEY="$DEFAULT_MASTER_PUBKEY"
  37. RECIPIENT=""
  38. FEE="$DEFAULT_FEE"
  39. while [[ $# -gt 0 ]]; do
  40. case $1 in
  41. -m|--master-pubkey)
  42. MASTER_PUBKEY="$2"
  43. shift 2
  44. ;;
  45. -r|--recipient)
  46. RECIPIENT="$2"
  47. shift 2
  48. ;;
  49. -f|--fee)
  50. FEE="$2"
  51. shift 2
  52. ;;
  53. -h|--help)
  54. show_help
  55. exit 0
  56. ;;
  57. *)
  58. echo "未知参数: $1"
  59. show_help
  60. exit 1
  61. ;;
  62. esac
  63. done
  64. if [[ -z "$RECIPIENT" ]]; then
  65. RECIPIENT="$MASTER_PUBKEY"
  66. fi
  67. print_info "开始快速归集流程..."
  68. # 1. 扫描余额
  69. print_info "扫描UTXO余额..."
  70. nockchain-wallet scan --master-pubkey "$MASTER_PUBKEY"
  71. # 2. 获取所有notes
  72. print_info "获取notes列表..."
  73. NOTES_OUTPUT=$(nockchain-wallet list-notes 2>&1 | strings)
  74. # 3. 解析notes并构建参数
  75. NAMES=""
  76. RECIPIENTS=""
  77. GIFTS=""
  78. TOTAL_BALANCE=0
  79. NOTE_COUNT=0
  80. # 提取Name和Assets信息
  81. # Name字段是跨行的,需要特殊处理,并保持完整的方括号格式
  82. ASSETS_LINES=$(echo "$NOTES_OUTPUT" | grep "Assets:" | sed 's/.*Assets: \([0-9]*\).*/\1/')
  83. # 手动构建完整的note名称
  84. NAMES_LINES=""
  85. while IFS= read -r line; do
  86. if [[ $line =~ Name: ]]; then
  87. # 提取前缀部分 (去掉 "- Name: [" 和行末的换行)
  88. prefix=$(echo "$line" | sed 's/^- Name: \[\(.*\)$/\1/' | sed 's/[[:space:]]*$//')
  89. # 读取下一行获取后缀部分
  90. read -r next_line
  91. # 去掉后缀末尾的 "]"
  92. suffix=$(echo "$next_line" | sed 's/\]$//')
  93. # 构建完整的note名称: [prefix suffix]
  94. full_name="[$prefix $suffix]"
  95. NAMES_LINES+="$full_name"$'\n'
  96. fi
  97. done <<< "$NOTES_OUTPUT"
  98. # 将Name和Assets转换为数组(使用 mapfile 避免 set -e 下的 read -d 错误)
  99. mapfile -t NAMES_ARRAY < <(printf '%s\n' "$NAMES_LINES")
  100. mapfile -t ASSETS_ARRAY < <(printf '%s\n' "$ASSETS_LINES")
  101. if [[ ${#NAMES_ARRAY[@]} -eq 0 || ${#ASSETS_ARRAY[@]} -eq 0 ]]; then
  102. print_info "没有找到可归集的notes"
  103. exit 0
  104. fi
  105. # 确保Name和Assets数组长度一致;不一致则截断至最短并给出警告
  106. if [[ ${#NAMES_ARRAY[@]} -ne ${#ASSETS_ARRAY[@]} ]]; then
  107. min_len=${#NAMES_ARRAY[@]}
  108. if [[ ${#ASSETS_ARRAY[@]} -lt $min_len ]]; then
  109. min_len=${#ASSETS_ARRAY[@]}
  110. fi
  111. print_info "Name与Assets数量不一致,按最短长度 $min_len 截断继续"
  112. NAMES_ARRAY=("${NAMES_ARRAY[@]:0:$min_len}")
  113. ASSETS_ARRAY=("${ASSETS_ARRAY[@]:0:$min_len}")
  114. fi
  115. # 构建参数
  116. for i in "${!NAMES_ARRAY[@]}"; do
  117. note_name="${NAMES_ARRAY[$i]}"
  118. balance="${ASSETS_ARRAY[$i]}"
  119. if [[ -n "$NAMES" ]]; then
  120. NAMES+=","
  121. RECIPIENTS+=","
  122. GIFTS+=","
  123. fi
  124. NAMES+="$note_name"
  125. RECIPIENTS+="[1 $RECIPIENT]"
  126. # 如果是最后一个note,需要扣除手续费
  127. if [[ $i -eq $((${#NAMES_ARRAY[@]} - 1)) ]]; then
  128. if [[ $balance -lt $FEE ]]; then
  129. print_error "最后一个note '$note_name' 的余额 ($balance) 不足以支付手续费 ($FEE)"
  130. exit 1
  131. fi
  132. # 从最后一个note扣除手续费
  133. adjusted_balance=$((balance - FEE))
  134. GIFTS+="$adjusted_balance"
  135. print_info "Note: $note_name, 余额: $balance nicks, 扣除手续费后: $adjusted_balance nicks"
  136. else
  137. GIFTS+="$balance"
  138. print_info "Note: $note_name, 余额: $balance nicks"
  139. fi
  140. TOTAL_BALANCE=$((TOTAL_BALANCE + balance))
  141. NOTE_COUNT=$((NOTE_COUNT + 1))
  142. done
  143. if [[ $NOTE_COUNT -eq 0 ]]; then
  144. print_info "没有找到可归集的notes"
  145. exit 0
  146. fi
  147. print_info "找到 $NOTE_COUNT 个notes,总余额: $TOTAL_BALANCE nicks"
  148. # 4. 创建归集交易
  149. print_info "创建归集交易..."
  150. print_info "归集到地址: $RECIPIENT"
  151. print_info "手续费: $FEE nicks"
  152. nockchain-wallet create-tx --names "$NAMES" --recipients "$RECIPIENTS" --gifts "$GIFTS" --fee "$FEE"
  153. print_success "归集完成!归集了 $NOTE_COUNT 个notes,总金额: $TOTAL_BALANCE nicks"