前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ECDSA使用,实现多签 (一)

ECDSA使用,实现多签 (一)

作者头像
Tiny熊
发布2022-02-22 18:19:32
7380
发布2022-02-22 18:19:32
举报

本文作者:auok007[1]

ECDSA 在前面的文章已经提到,尝试爆破 NFT 奖励时间限制 (二)[2]这方面的原理,以及实现我就不讨论了,文章比较多,程序员嘛,除了自己写的代码,就是关注接口,学会要会使用。

文档

我这里使用的openzeppelin[3]的实现,大家可以看看这里的文档。

代码语言:javascript
复制
FUNCTIONS
    tryRecover(hash, signature)
    recover(hash, signature)
    tryRecover(hash, r, vs)
    recover(hash, r, vs)
    tryRecover(hash, v, r, s)
    recover(hash, v, r, s)
    toEthSignedMessageHash(hash)
    toEthSignedMessageHash(s)
    toTypedDataHash(domainSeparator, structHash)

加密中比较重要的,私钥,公钥,信息

签名:

  1. 钱包用私钥,
  2. 信息 hash,
  3. 生成签名。

验证签名:

  1. 信息生成公钥 hash
  2. 信息 hash recover 签名,得到签名的公钥地址
  3. 比较公钥地址一致,说明是这个地址签名的

代码

直接来个测试用例,说明这个过程,里面的私钥都来自 Ganache 公开的私钥,测试使用环境用的 forge,不会用 forge,看这里forge 入门[4]

代码语言:javascript
复制
function testSign() public {
        address alice = address(0x9BEF5148fD530244a14830f4984f2B76BCa0dC58); //alice的公钥
        address bob = address(0x8Aa8b0D84cf523923A459a6974C9499581d1F93D); //bob的公钥
        bytes32 hash = keccak256("Signed by Alice"); //信息hash值
        (uint8 v, bytes32 r, bytes32 s) = sign(
            0x18ef5d5e78aa58a63503bcb48a563de61ffe7665d73ee22b4ab66ef15248be5a,
            hash
        ); //使用的alice的私钥、hash进行签名
        bytes memory sig = abi.encodePacked(r, s, v); //打包成测试需要的格式
        address signer = hash.recover(sig); //使用的ECDSA recover 函数得到签名地址
        emit log_named_address("address", signer);
        assertEq(alice, signer);
        (uint8 v2, bytes32 r2, bytes32 s2) = sign(
            0x4e1518672e45fb2746ec5a217330ed24d815d44537da647e973c06d0b0069053,
            hash
        ); //bob的私钥
        bytes memory sig2 = abi.encodePacked(r2, s2, v2);
        address signer2 = hash.recover(sig2);
        emit log_named_address("address", signer2);
        assertEq(bob, signer2);
    }

就这样,做多签的基础就有了。

下一篇就讲讲怎么做到多签名确认,才能转账。上面的代码对forge-std[5]加了一个小函数。

代码语言:javascript
复制
function sign(uint256 pri, bytes32 msg)
        public
        returns (
            uint8,
            bytes32,
            bytes32
        )
    {
        return vm_std_cheats.sign(pri, msg);
    }

更详细的,看我 github 上的仓库,后面的多签,也会提交到这里:SimpleMultiSig[6]

参考资料

[1]

auok007: https://learnblockchain.cn/people/6025

[2]

尝试爆破NFT奖励时间限制 (二): https://learnblockchain.cn/article/3518

[3]

openzeppelin: https://docs.openzeppelin.com/contracts/4.x/api/utils#ECDSA

[4]

forge 入门: https://learnblockchain.cn/article/3502

[5]

forge-std: https://github.com/brockelmore/forge-std

[6]

SimpleMultiSig: https://github.com/daodao2007/SimpleMultiSig

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文档
    • 签名:
      • 验证签名:
      • 代码
        • 参考资料
        相关产品与服务
        区块链
        云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档