# 第 04 讲：多重签名交易

![status](https://img.shields.io/badge/状态-已完成-success)
![author](https://img.shields.io/badge/作者-beihaili-blue)
![date](https://img.shields.io/badge/日期-2025--06-orange)
![difficulty](https://img.shields.io/badge/难度-中级-yellow)

> 💡 自学入门 `Web3` 不是一件容易的事，作为一个刚刚入门 Web3 的新人，梳理一下最简单直观的 `Web3` 小白入门教程。整合开源社区优质资源，为大家从入门到精通 Web3 指路。每周更新 1-3 讲。
> 
> 欢迎关注我的推特：[@bhbtc1337](https://twitter.com/bhbtc1337)
> 
> 进入微信交流群请填表：[表格链接](https://forms.gle/QMBwL6LwZyQew1tX8)
> 
> 文章开源在 GitHub：[Get-Started-with-Web3](https://github.com/beihaili/Get-Started-with-Web3)
> 
> 购买 BTC / ETH / USDT 等加密货币推荐 [币安](https://www.binance.com/zh-CN)[注册链接](https://www.bsmkweb.cc/register?ref=39797374)

## 目录

- [前言](# 前言)
- [多重签名基础概念](# 多重签名基础概念)
- [多重签名技术原理](# 多重签名技术原理)
- [P2SH 多重签名](#p2sh 多重签名)
- [企业级应用场景](# 企业级应用场景)
- [实战演练：创建多签钱包](# 实战演练创建多签钱包)
- [常见问题](# 常见问题)
- [结语](# 结语)

## 前言

在前一章《比特币交易基础》中，我们学习了比特币交易的基本组成、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？

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

**📖 历史背景 **

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

```javascript
// 比特币源码中的多签验证逻辑（简化版）
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：多重签名交易输入
```json
{
  "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 输出（支持复杂脚本）
```json
{
  "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

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

## 实战演练：创建多签钱包

### 创建多重签名地址

```python
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 ()
```

### 多签交易签名流程

```python
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']
```

### 多签钱包管理工具

```python
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. ** 重建钱包 **：
   ```python
   def recover_multisig_wallet (redeem_script, private_keys):
       # 使用赎回脚本和私钥重建钱包
       pass
   ```

3. ** 验证资金 **：
   - 检查 UTXO 状态
   - 验证签名权限

### ❓ 多签钱包的隐私性如何？

多签钱包的隐私性：

** 优势 **：
- 地址格式统一 (P2SH)
- 脚本哈希隐藏真实逻辑

** 劣势 **：
- 交易大小较大，容易被识别
- 签名数量暴露多签配置

** 改进方案 **：
- 使用 Taproot 多签（下一章介绍）
- 混合使用不同地址类型

## 结语

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

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

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

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

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

---

<div align="center">
<a href="https://github.com/beihaili/Get-Started-with-Web3">🏠 返回主页 </a> | 
<a href="https://twitter.com/bhbtc1337">🐦 关注作者 </a> | 
<a href="https://forms.gle/QMBwL6LwZyQew1tX8">📝 加入交流群 </a>
</div>
