第04讲:多重签名交易

status author date difficulty

💡 自学入门 Web3 不是一件容易的事,作为一个刚刚入门 Web3 的新人,梳理一下最简单直观的 Web3 小白入门教程。整合开源社区优质资源,为大家从入门到精通 Web3 指路。每周更新 1-3 讲。

欢迎关注我的推特:@bhbtc1337

进入微信交流群请填表:表格链接

文章开源在 GitHub:Get-Started-with-Web3

购买BTC/ETH/USDT 等加密货币推荐 币安注册链接

目录

前言

在前一章《比特币交易基础》中,我们学习了比特币交易的基本组成、UTXO模型和P2PKH交易。现在,我们将深入探讨比特币交易系统的一个重要功能:多重签名(MultiSig)。

多重签名是比特币技术发展的重要里程碑,它不仅增强了安全性,还为企业和机构提供了更灵活的资金管理方案。本章将详细讲解多重签名的原理、实现方式和实际应用。

多重签名基础概念

什么是多重签名?

多重签名(MultiSig)是一种需要多个私钥签名才能花费资金的机制,类似于银行的联合账户或公司的财务审批流程。

🔑 不同交易类型的签名要求

P2PKH(付款给公钥哈希)- 单签名交易

之前交易输出: OP_DUP OP_HASH160 <Alice的公钥哈希> OP_EQUALVERIFY OP_CHECKSIG
当前交易输入: <Alice的签名> <Alice的公钥>
  • 只需要1个签名:因为之前交易指定"付款给Alice的公钥哈希"
  • 🔓 解锁条件:提供正确的公钥和对应的私钥签名即可
  • 👤 使用场景:个人钱包之间的转账

多重签名交易 - 需要多个签名

之前交易输出: OP_2 <公钥1> <公钥2> <公钥3> OP_3 OP_CHECKMULTISIG (2-of-3多签)
当前交易输入: OP_0 <签名1> <签名2> <赎回脚本>
  • ⚠️ 需要多个签名:因为之前交易设定了"需要3个公钥中的任意2个签名"
  • 🔓 解锁条件:必须提供足够数量的有效签名
  • 🏢 使用场景:企业资金管理、托管服务、增强安全性

为什么签名要求不同?

交易类型 之前交易的锁定条件 解锁所需签名 原因
P2PKH 付款给单个公钥哈希 1个签名 资金归单人所有
2-of-3多签 需要3个公钥中的2个 2个签名 资金需要多方共同控制
3-of-5多签 需要5个公钥中的3个 3个签名 更高的安全要求

💡 关键理解:签名要求由之前交易的输出脚本决定,不是任意选择的!

🌟 形象化理解

想象比特币就像一个智能保险箱:

普通保险箱(P2PKH)

📦 之前有人给Alice发了一个保险箱,上面写着:"只有Alice的钥匙能打开"
🔑 现在Alice要用这个保险箱里的钱,只需要用她的钥匙(私钥签名)即可

多重签名保险箱(MultiSig)

📦 之前有人给公司发了一个保险箱,上面写着:"需要CEO、CFO、CTO中任意2人的钥匙才能打开"
🔑🔑 现在公司要用这个保险箱里的钱,必须有2个人同时用钥匙(2个私钥签名)

重点:保险箱的开锁规则是发送者在创建保险箱时就设定好的,接收者必须按照规则来解锁!

多重签名技术原理

🐛 深入理解:为什么多签需要 OP_0?

这是比特币历史上一个著名的技术债务!

📖 历史背景

当中本聪最初实现多重签名验证时,犯了一个小错误:

// 比特币源码中的多签验证逻辑(简化版)
bool CheckMultiSig() {
    // ... 验证签名逻辑 ...

    // 🐛 这里有个bug:会多pop一个元素
    stack.pop();  // 本来不应该有这一行

    // 验证结果
    return isValid;
}

🛠️ 解决方案:添加 OP_0

为了补偿这个多出来的pop操作,必须在堆栈顶部放一个"垫片":

实际需要的堆栈:
[OP_0] [签名2] [签名1] [公钥1] [公钥2] [公钥3] [2] [3] [OP_CHECKMULTISIG]
 ↑
 这个OP_0就是"垫片",会被bug多pop掉

🤔 为什么不修复这个bug?

  1. 向后兼容性:修复会导致所有历史多签交易失效
  2. 共识规则:所有节点必须保持相同的验证逻辑
  3. 历史成本:修复的风险远大于收益

💭 有趣的事实:这个 OP_0 至今仍存在于每一笔多重签名交易中,成为比特币历史的永久印记!

多重签名交易示例

例子1:多重签名交易输入

{
  "txid": "b2c3d4e5f6a7...(省略)",
  "vout": 1,
  "scriptSig": {
    "asm": "OP_0 3045022100a1b2c3...(签名1) 3044022067c8d9...(签名2)",
    "hex": "00483045022100a1b2c3...473044022067c8d9..."
  },
  "sequence": 4294967295
}

分析

  • OP_0:多重签名的特殊要求(Bitcoin的一个已知bug,需要额外的0)
  • 包含两个数字签名,满足2-of-3多签要求
  • 这笔输入对应的之前交易规定了需要3个公钥中的2个签名

P2SH多重签名

P2SH输出(支持复杂脚本)

{
  "value": 0.05000000,
  "n": 1,
  "scriptPubKey": {
    "asm": "OP_HASH160 1234567890abcdef...(20字节脚本哈希) OP_EQUAL",
    "hex": "a9141234567890abcdef...87",
    "type": "scripthash",
    "address": "3AnNyxwqnDUP7r3jKFaLWcqwYBdXjTPoBe"
  }
}

分析

  • 地址以3开头的P2SH地址
  • 可以包含多重签名、时间锁等复杂条件
  • 脚本哈希隐藏了真实的复杂脚本,提高隐私性

P2SH vs 原生多签

特性 原生多签 P2SH多签
地址格式 1开头 3开头
脚本可见性 脚本完全暴露 脚本哈希隐藏
隐私性 较差 较好
兼容性 所有节点支持 需要P2SH支持
费用 较高 较低

企业级应用场景

1. 企业资金管理

典型配置:3-of-5多签
参与者:
- CEO(主要决策者)
- CFO(财务负责人)
- CTO(技术负责人)
- 董事会成员A
- 董事会成员B

使用场景:
- 大额资金转移需要3人同意
- 防止单点故障
- 增强安全性

2. 托管服务

典型配置:2-of-3多签
参与者:
- 用户(资金所有者)
- 托管服务商
- 第三方仲裁者

使用场景:
- 用户保留部分控制权
- 托管服务商提供专业管理
- 第三方在争议时介入

3. 家庭财务管理

典型配置:2-of-2多签
参与者:
- 配偶A
- 配偶B

使用场景:
- 共同管理家庭资金
- 需要双方同意才能花费
- 增强家庭财务安全

4. 冷钱包备份

典型配置:2-of-3多签
参与者:
- 主钱包
- 备份钱包A
- 备份钱包B

使用场景:
- 防止单点故障
- 多重备份保护
- 灾难恢复

实战演练:创建多签钱包

创建多重签名地址

import requests
import json

def bitcoin_rpc(method, params=[]):
    url = "http://localhost:8332"
    headers = {'content-type': 'application/json'}

    payload = {
        "method": method,
        "params": params,
        "jsonrpc": "2.0",
        "id": 0,
    }

    response = requests.post(url, data=json.dumps(payload), headers=headers, auth=('user', 'password'))
    return response.json()

def create_multisig_address():
    # 1. 生成公钥(示例)
    pubkeys = [
        "03a1b2c3d4e5f6...",  # 公钥1
        "03b1c2d3e4f5a6...",  # 公钥2
        "03c1d2e3f4a5b6..."   # 公钥3
    ]

    # 2. 创建2-of-3多签地址
    result = bitcoin_rpc("createmultisig", [2, pubkeys])

    print(f"多签地址: {result['result']['address']}")
    print(f"赎回脚本: {result['result']['redeemScript']}")

    return result['result']

# 执行创建多签地址
multisig_info = create_multisig_address()

多签交易签名流程

def sign_multisig_transaction(raw_tx, private_keys, redeem_script):
    """
    对多签交易进行签名
    """

    # 1. 使用第一个私钥签名
    signed_tx1 = bitcoin_rpc("signrawtransaction", [raw_tx, [{"txid": "prev_txid", "vout": 0, "scriptPubKey": "script", "redeemScript": redeem_script}], [private_keys[0]]])

    # 2. 使用第二个私钥签名
    signed_tx2 = bitcoin_rpc("signrawtransaction", [signed_tx1['result']['hex'], [{"txid": "prev_txid", "vout": 0, "scriptPubKey": "script", "redeemScript": redeem_script}], [private_keys[1]]])

    return signed_tx2['result']['hex']

def broadcast_multisig_transaction(signed_tx):
    """
    广播多签交易
    """

    result = bitcoin_rpc("sendrawtransaction", [signed_tx])
    return result['result']

多签钱包管理工具

class MultiSigWallet:
    def __init__(self, pubkeys, required_signatures):
        self.pubkeys = pubkeys
        self.required_signatures = required_signatures
        self.address = None
        self.redeem_script = None

    def create_wallet(self):
        """创建多签钱包"""
        result = bitcoin_rpc("createmultisig", [self.required_signatures, self.pubkeys])
        self.address = result['result']['address']
        self.redeem_script = result['result']['redeemScript']
        return self.address

    def create_transaction(self, outputs):
        """创建多签交易"""
        inputs = [{"txid": "previous_utxo", "vout": 0}]
        raw_tx = bitcoin_rpc("createrawtransaction", [inputs, outputs])
        return raw_tx['result']

    def sign_transaction(self, raw_tx, private_key):
        """签名交易"""
        # 实现签名逻辑
        pass

    def broadcast_transaction(self, signed_tx):
        """广播交易"""
        return bitcoin_rpc("sendrawtransaction", [signed_tx])

# 使用示例
pubkeys = ["pubkey1", "pubkey2", "pubkey3"]
wallet = MultiSigWallet(pubkeys, 2)
address = wallet.create_wallet()
print(f"多签地址: {address}")

常见问题

❓ 多重签名的安全性如何?

多重签名比单签名更安全:

安全性对比:

单签名风险:
- 私钥丢失 → 资金永久丢失
- 私钥泄露 → 资金被盗

2-of-3多签安全性:
- 1个私钥丢失 → 仍可用其他2个
- 1个私钥泄露 → 攻击者仍需另1个私钥
- 需要攻击者同时获得2个私钥才能盗取资金

❓ 如何选择合适的多签配置?

场景 推荐配置 原因
个人备份 2-of-2 简单有效
家庭财务 2-of-2 需要双方同意
企业资金 2-of-3 或 3-of-5 平衡安全性和便利性
托管服务 2-of-3 用户+服务商+仲裁者
高安全性 3-of-5 或 4-of-7 更高的安全要求

❓ 多签交易的费用如何计算?

多签交易费用通常比单签交易高:

费用对比:
- 单签交易:~225字节
- 2-of-3多签:~400字节
- 3-of-5多签:~500字节

费用增加原因:
- 需要更多签名数据
- 赎回脚本占用空间
- 验证逻辑更复杂

❓ 如何恢复多签钱包?

多签钱包恢复需要:

  1. 收集必要信息

    • 赎回脚本
    • 足够的私钥
    • 交易历史
  2. 重建钱包

    def recover_multisig_wallet(redeem_script, private_keys):
        # 使用赎回脚本和私钥重建钱包
        pass
    
  3. 验证资金

    • 检查UTXO状态
    • 验证签名权限

❓ 多签钱包的隐私性如何?

多签钱包的隐私性:

优势

  • 地址格式统一(P2SH)
  • 脚本哈希隐藏真实逻辑

劣势

  • 交易大小较大,容易被识别
  • 签名数量暴露多签配置

改进方案

  • 使用Taproot多签(下一章介绍)
  • 混合使用不同地址类型

结语

通过本章的学习,你已经掌握了多重签名交易的核心概念和技术原理:

  • 基础概念:理解了多签的本质和优势
  • 技术原理:深入了解了多签的技术实现
  • 应用场景:学会了如何选择合适的多签配置
  • 实战操作:掌握了创建和管理多签钱包的方法

多重签名是比特币技术发展的重要里程碑,它不仅增强了安全性,还为企业和机构提供了更灵活的资金管理方案。

在下一章《隔离见证(SegWit)技术》中,我们将学习比特币的另一个重要升级:SegWit技术,它如何解决交易延展性问题并提升网络效率。

🌟 多重签名的意义:多签技术体现了比特币的一个重要理念:通过技术手段实现去中心化的信任机制,让多方协作变得安全可靠。


results matching ""

    No results matching ""