第04讲:多重签名交易
💡 自学入门
Web3
不是一件容易的事,作为一个刚刚入门 Web3 的新人,梳理一下最简单直观的Web3
小白入门教程。整合开源社区优质资源,为大家从入门到精通 Web3 指路。每周更新 1-3 讲。欢迎关注我的推特:@bhbtc1337
进入微信交流群请填表:表格链接
文章开源在 GitHub:Get-Started-with-Web3
目录
前言
在前一章《比特币交易基础》中,我们学习了比特币交易的基本组成、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?
- 向后兼容性:修复会导致所有历史多签交易失效
- 共识规则:所有节点必须保持相同的验证逻辑
- 历史成本:修复的风险远大于收益
💭 有趣的事实:这个 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字节
费用增加原因:
- 需要更多签名数据
- 赎回脚本占用空间
- 验证逻辑更复杂
❓ 如何恢复多签钱包?
多签钱包恢复需要:
收集必要信息:
- 赎回脚本
- 足够的私钥
- 交易历史
重建钱包:
def recover_multisig_wallet(redeem_script, private_keys): # 使用赎回脚本和私钥重建钱包 pass
验证资金:
- 检查UTXO状态
- 验证签名权限
❓ 多签钱包的隐私性如何?
多签钱包的隐私性:
优势:
- 地址格式统一(P2SH)
- 脚本哈希隐藏真实逻辑
劣势:
- 交易大小较大,容易被识别
- 签名数量暴露多签配置
改进方案:
- 使用Taproot多签(下一章介绍)
- 混合使用不同地址类型
结语
通过本章的学习,你已经掌握了多重签名交易的核心概念和技术原理:
- 基础概念:理解了多签的本质和优势
- 技术原理:深入了解了多签的技术实现
- 应用场景:学会了如何选择合适的多签配置
- 实战操作:掌握了创建和管理多签钱包的方法
多重签名是比特币技术发展的重要里程碑,它不仅增强了安全性,还为企业和机构提供了更灵活的资金管理方案。
在下一章《隔离见证(SegWit)技术》中,我们将学习比特币的另一个重要升级:SegWit技术,它如何解决交易延展性问题并提升网络效率。
🌟 多重签名的意义:多签技术体现了比特币的一个重要理念:通过技术手段实现去中心化的信任机制,让多方协作变得安全可靠。