多重签名(Multi-Signature)是一种需要多个私钥签名才能执行交易的账户类型,大大提高了资金安全性。本文详细介绍多重签名的原理、实现方式、使用场景和最佳实践,帮助开发者理解和使用这一重要的安全机制。

Multi-Signature


一、什么是多重签名

一、1 基本概念

多重签名(Multi-Signature,简称Multisig)是一种需要多个私钥签名才能执行交易的账户类型。与普通账户只需要一个私钥不同,多重签名账户需要多个授权者(通常是多个私钥持有者)中的一定数量同意,才能执行交易。

二、2 工作原理

1
签名要求:
  • 设置N个授权者
  • 要求M个签名(M ≤ N)
  • 例如:3个授权者中需要2个签名(2/3)
  • 只有达到要求的签名数,交易才能执行
1
安全优势:
  • 单点故障风险降低
  • 需要多人协作才能操作
  • 防止单个私钥泄露导致资金损失
  • 适合企业和高价值账户

三、3 常见配置

1
2/3多重签名:
  • 3个授权者,需要2个签名
  • 平衡安全性和便利性
  • 适合大多数场景
1
3/5多重签名:
  • 5个授权者,需要3个签名
  • 更高安全性
  • 适合重要资金管理
1
自定义配置:
  • 根据需求灵活配置
  • 可以随时修改
  • 适应不同场景

二、如何实现多重签名

四、1 使用智能合约实现

1
基础多重签名合约:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
pragma solidity ^0.8.0;

contract MultiSigWallet {
address[] public owners;
uint public required;

struct Transaction {
address to;
uint value;
bytes data;
bool executed;
}

Transaction[] public transactions;
mapping(uint => mapping(address => bool)) public confirmations;

event Submission(uint indexed transactionId);
event Confirmation(address indexed sender, uint indexed transactionId);
event Execution(uint indexed transactionId);
event Deposit(address indexed sender, uint value);

modifier onlyOwner() {
require(isOwner(msg.sender), "Not owner");
_;
}

modifier validRequirement(uint ownerCount, uint _required) {
require(_required > 0 && _required <= ownerCount, "Invalid requirement");
_;
}

constructor(address[] memory _owners, uint _required)
validRequirement(_owners.length, _required)
{
owners = _owners;
required = _required;
}

function isOwner(address addr) public view returns (bool) {
for (uint i = 0; i < owners.length; i++) {
if (owners[i] == addr) return true;
}
return false;
}

function submitTransaction(address _to, uint _value, bytes memory _data)
public
onlyOwner
returns (uint)
{
uint txIndex = transactions.length;
transactions.push(Transaction({
to: _to,
value: _value,
data: _data,
executed: false
}));
emit Submission(txIndex);
confirmTransaction(txIndex);
return txIndex;
}

function confirmTransaction(uint _txIndex) public onlyOwner {
require(!confirmations[_txIndex][msg.sender], "Already confirmed");
require(!transactions[_txIndex].executed, "Already executed");

confirmations[_txIndex][msg.sender] = true;
emit Confirmation(msg.sender, _txIndex);

if (getConfirmationCount(_txIndex) >= required) {
executeTransaction(_txIndex);
}

function executeTransaction(uint _txIndex) public {
require(getConfirmationCount(_txIndex) >= required, "Not enough confirmations");

Transaction storage txn = transactions[_txIndex];
txn.executed = true;

(bool success, ) = txn.to.call{value: txn.value}(txn.data);
require(success, "Transaction failed");

emit Execution(_txIndex);
}

function getConfirmationCount(uint _txIndex) public view returns (uint) {
uint count = 0;
if (confirmations[_txIndex][owners[i]]) {
count++;
}
return count;
}

function getTransactionCount(bool pending, bool executed)
view
{
for (uint i = 0; i < transactions.length; i++) {
if (pending && !transactions[i].executed) count++;
if (executed && transactions[i].executed) count++;
}
}

receive() external payable {
if (msg.value > 0) {
emit Deposit(msg.sender, msg.value);
}

五、2 部署和使用

1
部署合约:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 使用Truffle或Hardhat部署
const owners = [
'0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
'0x8ba1f109551bD432803012645Hac136c22C9e8c',
'0x1234567890123456789012345678901234567890'
];
const required = 2;

const MultiSigWallet = artifacts.require("MultiSigWallet");
const wallet = await MultiSigWallet.new(owners, required);
`提交交易:```javascript
// 所有者1提交交易
await wallet.submitTransaction(
recipientAddress,
web3.utils.toWei('1', 'ether'),
'0x',
{ from: owners[0] }
);
`确认交易:```javascript
// 所有者2确认交易
await wallet.confirmTransaction(0, { from: owners[1] });
// 如果达到required数量,交易自动执行

六、3 使用Gnosis Safe

1
Gnosis Safe简介:
  • 成熟的多重签名钱包解决方案
  • 提供友好的用户界面
  • 支持多种功能
  • 经过安全审计
1
创建Safe钱包:
  1. 访问 https://gnosis-safe.io/
  2. 连接钱包
  3. 设置所有者列表
  4. 设置确认数量
  5. 创建钱包
1
使用Safe:
  • 通过Web界面管理
  • 支持多种操作
  • 可以添加/移除所有者
  • 修改确认要求

三、如何使用多重签名

七、1 创建多重签名钱包

1
2
使用合约创建:
const { ethers } = require('ethers');
1
// 准备所有者地址

];

1
2
3
4
// 部署合约
const MultiSigWalletFactory = await ethers.getContractFactory('MultiSigWallet');
const wallet = await MultiSigWalletFactory.deploy(owners, 2); // 2/3
await wallet.deployed();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

使用Gnosis Safe:
1. 访问Gnosis Safe网站
2. 连接MetaMask

3. 添加所有者

### 八、2 执行交易

提交交易:
// 所有者1提交转账交易
const tx = await wallet.submitTransaction(
ethers.utils.parseEther('1.0'),
'0x',
{ from: owner1 }
);
// 所有者2确认
await wallet.confirmTransaction(0, { from: owner2 });

// 否则需要更多确认
`查看状态:```javascript
// 查看交易详情
const transaction = await wallet.transactions(0);
console.log('To:', transaction.to);
console.log('Value:', transaction.value.toString());
console.log('Executed:', transaction.executed);

// 查看确认数
const count = await wallet.getConfirmationCount(0);
console.log('Confirmations:', count.toString());

九、3 管理所有者

1
2
3
4
5
添加所有者(需要修改合约):
function addOwner(address owner) public onlyOwner {
require(!isOwner(owner), "Already owner");
owners.push(owner);
emit OwnerAddition(owner);

}
移除所有者:solidity

1
2
3
function removeOwner(address owner) public onlyOwner {
require(isOwner(owner), "Not owner");
require(owners.length > required, "Cannot remove owner");
1
2
3
4
if (owners[i] == owner) {
owners[i] = owners[owners.length - 1];
owners.pop();
break;
    }
1
emit OwnerRemoval(owner);

}


## 四、应用场景

### 十、1 企业钱包

资金管理:
- 公司资金需要多人审批
- 防止单点故障
- 审计追踪
- 合规要求

权限控制:
- 不同级别权限
- 大额交易需要更多确认
- 定期审查权限
- 角色分离

### 十一、2 项目资金

ICO/IDO资金:
- 众筹资金安全保管
- 需要团队多人同意才能使用
- 透明化管理
- 社区信任

DAO资金:
- 去中心化组织资金
- 社区投票决定使用
- 自动执行
- 透明审计

### 十二、3 个人高价值账户

大额资产:
- 个人大额资金保护
- 家人共同管理
- 遗产规划

冷钱包:
- 多重签名冷钱包
- 离线签名
- 最高安全性
- 长期存储

### 十三、4 智能合约管理

合约升级:
- 需要多人同意
- 防止恶意升级
- 透明化决策
- 社区参与

参数调整:
- 重要参数修改
- 需要多重确认
- 降低风险
- 提高安全性

## 五、最佳实践

### 十四、1 配置建议

所有者选择:
- 选择可信的授权者
- 分散风险
- 避免单点故障
- 定期审查

确认数量:
- 2/3适合大多数场景
- 3/5适合重要资金
- 根据需求调整

### 十五、2 安全实践

私钥管理:
- 每个所有者独立管理私钥
- 使用硬件钱包
- 多重备份

操作流程:
- 建立标准操作流程
- 记录所有操作
- 定期审计
- 应急方案

### 十六、3 使用建议

测试环境:
- 先在测试网测试
- 熟悉操作流程
- 验证功能
- 培训团队成员

生产环境:
- 使用经过审计的合约
- 或使用Gnosis Safe
- 定期更新
- 监控异常

## 六、常见问题

### 十七、1 所有者丢失私钥

解决方案:
- 如果还有足够的所有者,可以继续操作
- 可以添加新所有者
- 移除丢失私钥的所有者
- 需要其他所有者同意

### 十八、2 确认数量不足

情况:
- 如果所有者数量减少
- 可能导致无法达到确认要求
- 需要调整配置

解决:
- 添加新所有者
- 或降低确认要求
- 需要现有所有者同意

### 十九、3 Gas费用

考虑因素:
- 多重签名交易需要更多Gas
- 每次确认都需要Gas
- 执行也需要Gas
- 成本较高

优化:
- 批量操作
- 合理设置Gas价格
- 使用Layer 2
- 优化合约代码

## 七、总结

多重签名是提高区块链账户安全性的重要机制,特别适合企业、项目和高价值账户。关键要点:

安全性:
- 需要多人协作
- 降低单点故障风险
- 防止私钥泄露
- 提高资金安全

适用场景:
- 企业资金管理
- 项目资金保管
- 高价值账户
- 智能合约管理

最佳实践:
- 合理配置
- 安全存储私钥
- 建立操作流程

通过正确使用多重签名,可以大大提高资金安全性,适合各种需要高安全性的场景。建议使用经过审计的解决方案如Gnosis Safe,或自己实现时进行充分的安全审计。

本文标题: 多重签名账户

本文作者: 狂欢马克思

发布时间: 2023年01月25日 00:00

最后更新: 2025年12月30日 08:54

原始链接: https://haoxiang.eu.org/446721c5/

版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

× 喜欢就赞赏一下呗!
打赏二维码