清楚几个要点:
1.密码学货币不同于传统的银行,你有很多工具可以生成一把私钥来持有密码学货币,既不需要向银行申请,也不需要给谁报备,没有任何人能阻止你拥有自己的私钥和钱包;
2.公钥和用来接收转账的地址都是由私钥使用单向的数学运算推导出来的,如果不信任现有的工具,你完全可以自己使用这些数学运算来生成地址;同时,公开地址不会产生安全问题,因为地址无法反推出公钥,也无法反推出私钥;
3.使用第三方提供的服务时,弄清楚服务的性质,不要向任何人暴露自己的私钥,并且定期备份。
1
在本系列文章的篇中,我们得到了如下的比特币私钥:
这里没有写出私钥的生成过程。简单来说,私钥就是一串随机的十六进制字符串,为了安全(私钥不暴露、不被他人重现出来),这串随机数的生成环境应尽可能满足随机性、不可预测性、不可重现性。所以,不要自己写一串数字来当私钥,因为你自以为的“随机”往往并不怎么随机,很不安全。(理论上来说你确实可以自己连抛256次硬币产生符合长度要求(64位)的随机数,但还是很不推荐。)
在本文中,我们会演示使用这个私钥来获得公开地址,以及与该私钥对应的以太坊钱包地址。
通过私钥来获得比特币钱包地址的具体流程有些复杂,因此我们会描述简化后的版本。我们需要使用一个哈希函数去获得公钥,还需要使用另一个函数去获得地址。
现在,让我们开始吧。
公钥
这部分内容和之前讨论比特币的文章中所说的相同,所以如果你已经读完了,那么就可以跳过(除非你想要复习一下)。
首先,我们需要在私钥上使用ECDSA,即椭圆曲线数字签名算法。椭圆曲线是通过y²=x³+ax+b公式得出的,其中a和b可以自定义。椭圆曲线家族有很多并且广泛应用的案例。比特币使用了secp256k1曲线,关于椭圆曲线密码学,如果你想了解更多,可以参考此文章。
以太坊使用了同样的椭圆曲线,secp256k1,因此对于比特币和以太坊来说,获得公钥的流程是相同的。
对私钥作了ECDSA运算之后,我们得到了64字节的整数,这是由两个32字节的整数串联组成,代表了椭圆曲线上某个点的X值和Y值。
在Python程序中,代码显示如下:
private_key_bytes=codecs.decode(private_key,‘hex’)
#GetECDSApublickey
key=ecdsa.SigningKey.from_string(private_key_bytes,curve=ecdsa.SECP256k1).verifying_key
key_bytes=key.to_string()
key_hex=codecs.encode(key_bytes,‘hex’)
注意:从上面的代码可以看出,我使用了ecdsa模块并通过编码器解码了私钥。这样写更多是因为Python的关系,而与算法本身无关,为免误解,让我来好好解释一下。
Python语言中,至少有两种数据类型可以保存私钥和公钥:“str”和“bytes”。前者对应的是string(字符串),后者则是bytearray(数值)。Python语言中的密码学运算只能对“bytes”类操作,将byte型数据作为输入,并且将输出作为结果。
但是,这里面有个小问题:作为字符串的“4f3c”和作为bytearray的4f3c是不等同的,string等于bytearray和两个元素O<的结合。codecs.decode方法就是将字符串转换为bytearray。本文中使用的密码学操作都要进行这一步骤。
钱包地址
一旦获得公钥,我们就可以计算出钱包地址,和比特币不同,以太坊在主网和所有测试网都有相同的地址。当用户发起转账和签名的时候,他们需要选择相应的网络。
为了通过公钥得出地址,我们需要做的就是在公钥上应用Keccak-256加密算法,然后拿出结果的后20个字节,这样就可以了。整个过程不需要其他的哈希函数,无需Base58编码,也不用其他任何转换,你唯一需要做的事情就是在地址的开头添加“0x”。