从原理到代码一次性搞定 多签名钱包(Multi-Sig Wallet)核心逻辑,任何时候都能基于 Gnosis Safe 思想,快速手搓最小可行版本。
数字资产的终极敌人只有一个:单点失败。只要一把私钥丢失或者泄漏,钱包就等于裸奔。多签钱包通过把“签名权”拆成多条钥匙,天然消除这种单一失效面。下面用200行 solidity 还原一个可跑在本地测试网的最简 Gnosis Safe,并穿插 5 个关键技术点,方便你日后扩展成商业级方案。
多签钱包如何保证“资产更安全”?
- 多个授权方共同治理
任何一笔对外转账或合约调用都必须收集预先设定的threshold个签名方可执行。 设定门限值减少单点风险
如 3 人共同管理,阈值设为 2:- 单人作恶无法得逞
- 一人丢失私钥资产依旧安全
- 链下签名 + 链上验证,Gas 更省
签名阶段可在链下完成,链上仅做一次校验与执行,一笔交易节省 30%–50% Gas。 - 即插即用的智能合约
纯 solidity 实现,无任何授权或白名单后门,部署后即可按需集成分账、托管、DAO 治理场景。
智能合约的「骨架」:只需 4 个核心参数
只要把这两个数据结构放进合约,就能跑通多签流程:
uint8 public constant MAX_SIGNEE = 3; // 最多 3 位多签人
uint8 public constant threshold = 2; // 最少 2 个签名
address[MAX_SIGNEE] public owners; // 白名单地址别小看它们,后面的所有逻辑——校验、聚合、执行——围绕这两行展开。
👉 这里有一份开源样例代码,把关键路径都跑通了,可直接 fork 测试。
手搓一个安全多签钱包的 5 个步骤
Step 1 链下构建 messageHash
以太坊签名格式要求先计算一次链外哈希,再附加标准前缀进行二次哈希,防止重放攻击。
bytes32 dataHash = keccak256(abi.encode(to, value, keccak256(data)));
bytes32 messageHash = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)
);核心关键词:消息哈希、以太坊签名格式、keccak256。
Step 2 逐个离线签名
Common dialogs:
A:咱们转账 1 ETH → 0x123 怎么样?
B:行,我来签名。
他们用各自的私钥对 messageHash 分别签出 (v, r, s),组成 65 字节的 sig。
Foundry & Hardhat 提供vm.sign()或web3.eth.accounts.sign(),一分钟就能跑通模拟签名。
Step 3 聚合签名为 130 字节
门限 2 ⇒ 把 2 份 65 字节简单拼接即可。链上直接当一整个 signatures 传进去,代码短到一句话:
bytes memory signatures = abi.encodePacked(sig1, sig2);Step 4 链上三步验签
合约函数 executeTransaction(..., signatures),内部执行:
- 用与 Step 1 相同的函数生成一次
messageHash,防止篡改。 - 遍历
signatures,每 65 字节切一段,ECDSA.recover找回地址。 - 确认恢复地址在
owners白名单,且数量 ≥threshold,否则 revert。
核心关键词:ECDSA 恢复地址、签名长度校验、授权列表检查。
Step 5 通过 call() 触发目标交易
一切校验通过,就用 solidity 原生调用把 ETH 或任意函数转出去:
(bool success,) = to.call{value: value}(data);压阵的是 ExecutionSuccess / ExecutionFailure 事件,使前端、后端或监控服务都可用日志监听结果。
完整代码仓库快速上手
1. 克隆仓库
git clone <仓库地址>
cd hello-foundry2. 安装依赖 & 编译
forge install
forge build3. 运行测试
forge test --match-path test/multiSignature/multiSignatureTest.t.sol -vvv如终端输出 ExecutionSuccess,恭喜,你已经在本地复刻了 Gnosis Safe 核心流程!
FAQ:新手常见疑问一次性解答
Q1:为什么本示例没有 nonce?
A:演示目的追求最小可行版本。生产环境必须引入 nonce 及 chainId,防止重放攻击跨链复用签名。
Q2:如何替换成 5/7 多签?
A:把 MAX_SIGNEE 改为 7,threshold 改为 5,签名聚合长度变为 325 字节(7×65)即可。
Q3:能动态增删多签人吗?
A:本示例为静态数组版,需添加“提案-投票-执行”三阶段才能支持增删。可参考 Gnosis Safe 官方模块 OwnerManager.sol。
Q4:和普通硬件钱包配合吗?
A:完全兼容。只需将硬件钱包地址写入 owners,用钱包官方工具做 EIP-712 或标准签名即可。
Q5:能不能在一笔交易里同时执行多笔转账?
A:可以的。将 data 参数换成 MultiCall 打包后的 calldata,或在 Sign Message 里执行 delegateCall 扩展即可。
小结:把安全做到极致,只需 200 行
之所以说“更安全的多链钱包”,是因为多签思想本身就是为“永不妥协”而生:
- 单点私钥失效不再致命;
- 所有人实时透明、链上审计;
- 代码极简,可插拔、可审计、可 fork。
动手把上文示例 fork 下来,把 owners 换成你和两位好友的地址,门限 2/3,就能立即体验到链上 DAO 级资金托管。别忘了,简单不简陋,安全更可靠。祝你编码愉快、资产常青!