科普 | Eth2 Staking 指南 #4:密钥

衷心感谢 Sacha Yves Saint-Leger 和 Danny Ryan 对本文的审核。

权益证明系统的核心是其签名方案。签名用于验证发出操作的验证者的身份,即确定哪个操作是由哪个验证者发出的(不论是 “好” 的操作还是 “坏” 的操作)。

我们既可以根据一个验证者签过名的消息来确认 TA 遵守了协议,也可以通过展示触犯了共识规则的消息来证明某个验证者的恶意。

实际上,在 Eth2 系统中,验证者的身份是根据其公钥(public key)来确定的。每个验证者都有两组密钥:签名密钥对和取款密钥对。

签名密钥对

所谓 “签名密钥”,是指一个验证者在签名见证消息和提议区块的时候要用到的密钥。因为验证者每一个时段(epoch)都要签署至少一条消息,客户端软件必须托管签名密钥。

取款密钥对

因为客户端软件总是联网的,因此必然有签名密钥丢失、被盗的可能。为降低此类事件会造成的影响,验证者可以执行的操作被分成由两套不同的密钥来发起。

签名密钥,如上所述,用于履行验证者责任。另一方,“取款密钥” 则用于控制验证者的资金。

在验证者的整个生命周期中,验证者仅在极少数时候需要用到取款密钥。这意味着取款密钥可以放到冷钱包了,(离线)存储在足够安全的地方。

注意:验证者资金转账和取款功能都要等 Phase 1 之后才会上线。

(译者注:这里的签名密钥和取款密钥,作者在原文中常用单数形态 “a signing key” “a withdrawal key”,但在这里我翻成 “签名密钥对” 和 “取款密钥对”。因为根据我们对密码学的理解,要保证身份同一性,少不了要用到公钥密码学(公私钥对):验证者提前使用签名私钥和取款私钥对应的两把公钥在注册表中注册,然后在其生命周期中,使用其私钥来签名消息时,其身份才能得到确认。取款过程也是同理,也跟我们当前使用以太坊账户的方法并无二致)

密钥怎么这么多!

如果每要质押 32 ETH,用户就要保存和使用两套互不关联的密钥,那这也太麻烦了

在 Eth2 中,我们可以用 EIP-2333EIP-2334 来解决这个问题:这两个 EIP 提出了一套标准,描述了签名密钥和取款密钥可以如何关联起来,以及这两组密钥如何可以从同一个 Mnemonic (助记词)中推导出来。

助记词

助记词是另一种用编码来保护密码的办法,也是普通用户存储和备份私钥的最简单办法。

简而言之,就是把 0x1e9f2afcc0737f4502e8d4238e4fe82d45077b2a549902b61d65367acecbccba 这样的私钥,转化成 sausage solution loud isolate focus glide frame door clown million shuffle impulse 这样的可读单词,然后记下或者写下来,这样就更容易保存、更不容易出错了。

从一把密钥推导出其它密钥

在使用钱包时,您可能会遇到形如 m/44'/60'/0'/0/0 这样看起来像路径的东西。这个路径是用来描述密钥之间的关系的。

根据 EIP 2333 ,用一把密钥(也即一组助记词)中推导出其它密钥所形成的体系就像一棵树一样,而被推导出来的密钥是根据树的 “种子”(即最初那个密钥)和树的路径来决定的。

我们使用种子计算出树根,根据树根和树分支来推导密钥、一层一层地建构出整棵密钥树。因此,可以认为,整棵密钥树都完全是根据树的分支与树根之间的关系来决定的。(译者注:根据这个描述也可以看出,整棵密钥树是无限大的,因为可以无限推导下去。在使用时只需记好哪些分支上的那些密钥是用过的、有资金的就好。)

在使用过程中,这种推导密钥的方法让我们可以找出我们要用的任意密钥:只需从树根开始、按分支计算中间密钥,最终算出我们要用的那个密钥(叶子)即可。

一个有趣的结果就是,我们可以从单个随机数(比如一组助记词)开始,推导出无限多的密钥。

用在 Eth2 中,一组助记词就可以产生出验证者需要的任意多的密钥。举个例子,如果你需要用一组助记词产生出 3 个取款私钥,那么可以像这样推导:

[m / 0] 
     /        
    /           
[m] - [m / 1] 
    \
     \
      [m / 2]

每个分支都用 “/” 来标记,所以 “m/2” 表示的是从主密钥推导出的第 2 分支。

EIP 2334 指出,验证者的签名密钥可以使用取款私钥的第 0 个子分支。在实践中这意味着,只要遵循这个标准,只要你知道取款私钥,你就可以计算出相应的用于签名的私钥。

计算过程也如上例所示:

[m / 0] - [m / 0 / 0]
     /        
    /           
[m] - [m / 1] - [m / 1 / 0]
    \
     \
      [m / 2] - [m / 2 / 0]

这里我们是为了尽可能简化才举这样的例子的,实际上的路径会更长一点(比如 EIP 2334 就要求使用 m/12381/3600/i/0m/12381/3600/i/0/0 这样长的路径用于推导取款私钥和签名私钥)。不过,逻辑还是完全一样的。

谨记:如果你知道自己的助记词,就可以推导出取款私钥,然后再推导出签名私钥。

存储密钥

验证者客户端使用 Keystore 文件来交换密钥。

Keystore 是一种文件格式,包含了用户用口令(password)加密后的私钥,因此可以安全地存储以及在计算机之间安全地传播(只要口令没有存在同一台计算机上就好)。

如果你已经准备好要开始验证了,你可以把 Keystore 导入客户端(当然,你还需要输入口令,好让客户端能导出私钥)。

成为验证者

成为验证者的第一步是生成密钥。请保证在安全的环境中使用安全的软件来生成私钥,生成后请写下来。

因为 Phase 0 阶段没有取款功能也转不了账,你不需要用 Keystore 来存储取款私钥,保证你的助记词是安全的就够了

如果你的验证者客户端需要你的签名私钥,那么在你输入私钥之后你可以得到相应的一个 Keystore 文件(加密的口令也是你自己输入的)。你跑多少个验证者,就会拿到多少个 Keystore。

为了注册成为验证者,你需要给每个验证者准备 32 ETH 的保证金,加上你的 保证金数据 (包含着你的验证者公钥),发送给 Eth1 链上的保证金合约。

保证金数据会被记录在保证金合约中。Eth2 的节点可以观察到这个合约,因此可以获得其中的保证金数据。你的保证金数据被 Eth2 链接受以后,你就正式成为验证者了。

最简单的方法

我们一直在开发一个友好的界面来帮助验证者完成注册过程。我们接下来的更新会介绍 Eth2 Lauchpad 以及如何使用它。

(完)

原文链接: https://blog.ethereum.org/2020/05/21/keys/

作者:Carl Beekhuizen

翻译:阿剑

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章