什么是多签钱包

多签钱包,也称为多重签名钱包,是一种加密钱包,它需要多个私钥才能签署并发送交易。这种钱包的主要优点是提供了额外的安全层,因为即使一个私钥被盗,也无法进行交易,除非有其他私钥的授权。

多签钱包的工作原理是基于一个简单的数学原理,即“M-of-N”或“M/N”。这意味着如果你有N个私钥,那么至少需要M个私钥才能签署并发送交易。例如,如果你有一个3/5的多签钱包,那么你有5个私钥,但至少需要3个私钥才能签署交易。

这种设置在多人共享钱包或企业环境中非常有用,因为它可以确保资金的使用需要多个成员的批准。这不仅增加了安全性,而且还提供了一种透明的方式来管理和审计资金的使用。

在以太坊上,多签钱包通常是通过智能合约来实现的。这个智能合约会记录所有的所有者和需要的签名数量,然后只有当足够数量的所有者签署了交易,才会执行该交易。

示例

当然,以下是带有详细注释的代码:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

// 定义多签钱包合约
contract MultiSigWallet {
    // 所有者地址数组
    address[] public owners;
    // 地址到所有者状态的映射
    mapping(address => bool) public isOwner;
    // 执行交易所需的确认数量
    uint public numConfirmationsRequired;

    // 定义交易结构体
    struct Transaction {
        address destination; // 交易目的地
        uint value; // 交易金额
        bytes data; // 交易数据
        bool executed; // 交易是否已执行
        uint numConfirmations; // 交易的确认数量
    }

    // 交易数组
    Transaction[] public transactions;
    // 交易索引到地址的确认状态的映射
    mapping(uint => mapping(address => bool)) public isConfirmed;

    // 构造函数,设置所有者和所需确认数量
    constructor(address[] memory _owners, uint _numConfirmationsRequired) public {
        require(_owners.length > 0, "owners required");
        require(
            _numConfirmationsRequired > 0 && _numConfirmationsRequired <= _owners.length,
            "invalid number of required confirmations"
        );

        for (uint i = 0; i < _owners.length; i++) {
            address owner = _owners[i];
            require(!isOwner[owner], "owner not unique");

            isOwner[owner] = true;
            owners.push(owner);
        }

        numConfirmationsRequired = _numConfirmationsRequired;
    }

    // 提交新的交易
    function submitTransaction(address destination, uint value, bytes memory data)
        public
        onlyOwner
    {
        uint txIndex = transactions.length;
        transactions.push(Transaction({
            destination: destination,
            value: value,
            data: data,
            executed: false,
            numConfirmations: 0
        }));

        isConfirmed[txIndex][msg.sender] = true;
    }

    // 确认交易
    function confirmTransaction(uint txIndex) public onlyOwner {
        Transaction storage transaction = transactions[txIndex];
        require(!transaction.executed, "transaction already executed");
        require(!isConfirmed[txIndex][msg.sender], "transaction already confirmed");

        transaction.numConfirmations += 1;
        isConfirmed[txIndex][msg.sender] = true;
    }

    // 执行交易
    function executeTransaction(uint txIndex) public onlyOwner {
        Transaction storage transaction = transactions[txIndex];
        require(!transaction.executed, "transaction already executed");
        require(transaction.numConfirmations >= numConfirmationsRequired, "cannot execute transaction yet");

        transaction.executed = true;
        (bool success, ) = transaction.destination.call.value(transaction.value)(transaction.data);
        require(success, "transaction failed");
    }

    // 修饰符,只允许所有者调用
    modifier onlyOwner() {
        require(isOwner[msg.sender], "not owner");
        _;
    }
}

这个合约的主要功能如下:

  • submitTransaction:所有者可以提交新的交易。
  • confirmTransaction:所有者可以确认已提交的交易。
  • executeTransaction:如果一个交易已经得到了足够的确认,任何所有者都可以执行它。

工作流程

这个多签钱包合约的工作原理如下:

  1. 初始化:在部署合约时,会通过构造函数设置所有者和所需的确认数量。所有者是一个地址数组,每个地址都是一个所有者。所需的确认数量是一个整数,表示执行交易所需的最少确认数量。
  2. 提交交易:所有者可以调用submitTransaction函数来提交新的交易。这个函数接收三个参数:目标地址、值(以wei为单位的以太币数量)和数据(可选)。提交的交易会被添加到交易数组中,并且提交者会自动确认这个交易。
  3. 确认交易:所有者可以调用confirmTransaction函数来确认已提交的交易。这个函数接收一个参数:交易的索引。只有未执行的交易才能被确认,而且每个所有者只能确认一次。每次确认,交易的确认数量都会增加。
  4. 执行交易:所有者可以调用executeTransaction函数来执行已确认的交易。这个函数接收一个参数:交易的索引。只有已经得到足够确认的交易才能被执行。执行交易时,会向目标地址发送指定数量的以太币,并调用目标地址的函数(如果提供了数据)。如果交易执行成功,交易的状态会被标记为已执行。

这个合约的关键是,它允许多个所有者共同控制资金,并且需要多个所有者的签名才能执行交易。这为资金提供了额外的安全层,因为即使一个所有者的私钥被盗,也无法执行交易,除非有其他所有者的授权。

请注意,这只是一个基础的示例,实际的多签钱包可能会有更多的功能和安全措施。在使用或开发多签钱包时,你应该确保理解其工作原理,并考虑到可能的安全风险。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特