温故而知新:从私钥计算出公钥

Words
761
Reading
4 min
Listen
Play
5y

在昨天的帖子中,我提及元旦的时候因为Linode机房物理机的故障,导致我见证人节点崩溃,我一方面将节点切换到其它VPS,另外一方面去修复受损的block_log文件并replay。

image.png
(图源 :pixabay)

在切换见证人节点时,我遇到一个问题,就是我两组见证人(出块)私钥,搞不清楚和公钥的对应关系了。情急之下,只好翻遍电脑,总算找到一组公私钥对了,但是这个方法是超级蠢的。

复盘一下这个事,完美的做法应该是在配置文件中的私钥处,用注释标准上对应的公钥(后几位就行);次一点的办法是用出块私钥计算出对应的公钥,或者重新省成公私钥对。

标注的事,没啥可说的,就是一个良好的习惯,我们来说说从私钥计算的公钥的事。

要说明这个事,我们需要先知道公钥私钥咋来的,其实我以前一系列文章没少进行这方面的探索(只是一着急全忘了),所以复习一下,毕竟温故可以知新。

其实HIVE区块链中的私钥,说白了就是一组256位二进制随机数。

当然直接用随机数表示不便于使用,还容易出错,所以加了前缀(0x80)和校验码,并用Base58编码,这个过程就是Base58CheckEncode。

而公钥,说起来比较复杂,简单来讲就是:

公钥(K)是通过私钥(k)乘以生成点(G)得到的,并且是椭圆曲线上的一个点P(x, y),将点P(x, y)表示成公钥其实就是加上前缀04并把x和y连接起来。

同私钥一样,这样的公钥无论事看起来还是用起来都不方便,所以也加个校验码,并且用Base58进行编码,在石墨烯系统中这个过程叫做gphBase58CheckEncode。

所以说,HIVE中公钥是从私钥计算得来的,知道了上述过程,如何从私钥计算出公钥也就清楚了:

  • 将私钥(WIF)还原成256位二进制随机数:base58CheckDecode, unhexlify
  • 使用ecdsa.SigningKey.from_string导入上述随机数获取sk
  • 使用sk.get_verifying_key()获取VerifyingKey
  • 使用gphBase58CheckEncode(hexlify(vk.to_string("compressed")).decode('ascii'))获取编码后的公钥
  • 加上“STM前缀”

我们来测试一下,首先生产一组公私钥对:

{'pubk': 'STM67PuP8KfwDmT2xAa3kDDDT9tbjpvmoYVXgoQFq1893R1CmkFqM', 'wif': '5Kd3wZ56H7kjfaY55Wgda1qzQEvabuP5k27zkizdF8jqLJf9Fnf'}

然后用wif来重新计算公钥:

image.png

发现计算出来的公钥和原来的一模一样。

这次再也不怕私钥公钥对不上号了,不过还是好习惯更重要一些,毕竟注释一目了然,还是要比计算简单好多呢。

相关链接

温故而知新:从私钥计算出公钥 | Ecency