ECDSA 사용, 实现多签(二)

昨天留下多签的代码还没写,今天还是写了一会会儿,前文在这里: ECDSA使用,实现多签 (一) | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)
这篇文章有参考一个老外的文章,但是做了一些优化,思路一致.
Signature Replay | Hack Solidity #13 | by Zuhaib Mohammed | Jan, 2022 | CoinsBench (medium.com)

一个简单的多签,运用到一个转账业务中就是,一个老板小李建立了一个多签合约,初始化公司股东,小张,小王作,小陈,有马几人个,小马几个个个个人同意,就可以通过多签合约给其他人转钱.

首先初始化合约,最多5个操作人,最少3个人同意就可以转:

constructor(address[] memory _operators) public payable {
        owner = msg.sender;
        require(_operators.length <= 5, "Too many operators");
        for (uint8 i = 0; i < _operators.length; i++) {
            operators[i] = _operators[i];
        }
    }


转账函数定义:

function transfer(
        address _to,
        uint256 _amount,
        bytes[] memory sigs
    ) external {
        bytes32 txHash = getTxHash(_to, _amount);

        require(_checkSigs(txHash, sigs, 2), "Only operators can transfer");
        (bool sender, ) = _to.call{value: _amount}("");
        require(sender, "sender failed");
    }


_checkSigs是我们的关键函数,检查签名是不是这个人签出来的.

function _checkSigs(
        bytes32 txhash,
        bytes[] memory sigs,
        uint8 numSigs //
    ) private view returns (bool) {
        uint8 c = 0;
        //emit log_named_uint("sigs len", sigs.length);
        bool[] memory bops = new bool[](operators.length);
        for (uint8 i = 0; i < sigs.length; i++) {
            //emit log_named_bytes("txHash", txHash);
            if (!_findOpt(txhash.recover(sigs[i]), bops)) {
                return false;
            }
            c++;
        }
        //emit log_named_uint("c", c);
        if (c > numSigs) {
            return true;
        } else {
            return false;
        }
    }



function _findOpt(address sigaddr, bool[] memory bops)
        private
        view
        returns (
            bool
        )
    {
        for (uint8 i = 0; i < operators.length; i++) {
            //emit log_named_address("operators", operators[i]);
            if (operators[i] != address(0x0)) {
                if (bops[i] == false) {
                    if (operators[i] == sigaddr) {
                        //emit log_named_address("find", operators[i]);
                        bops[i] = true;
                        //emit log("set true");
                        return true;
                    }
                }
            } else {
                break;
            }
        }
        return false;
    }


为什么这样就可以?
检查签名是不是这个人签出来的,看我前面的ECDSA用法讲解. ECDSA使用,实现多签 (一) | 登链社区 | 深入浅出区块链技术 (learnblockchain.cn)
相对于老外的代码,我做了一些升级,操作人变成5个,转账时候的签名,可以不按照顺序进行签名对比.
对比 对比 上 上 网站 人 的 文章 文章 文章 文章 这个 更 更 像 像 一 一 个 技术 原型 原型 原型 原型 原型 原型 原型 原型 继续 继续 更新 更新 更新 弄 弄 一 个 个 更 更 偏向 业务 的 的 合约.. 测试 用 例 的 的 的 都 在 在 Github 上, 看 用例 用例 用例 怎么 能 理解 是 是 是 是 是 怎么 怎么 更 更 更 更 应该 应该 应该 应该 都 都 都 的 的 例일.
更详细的,看我github上的仓库:
SimpleMultiSig

좋은 웹페이지 즐겨찾기