从私钥创建比特币钱包地址有点复杂。在这里,我们会使过程更加简单化。我们需要应用一个哈希函数来获取公钥,另一个哈希函数来获取地址。让我们开始吧。
公钥
我们需要做的第一件事是将ECDSA或椭圆曲线数字签名算法应用于我们的私钥。椭圆曲线是由等式 y²=x³+ax+b 定义的曲线,选择a和b。有一整套这样的曲线是公认并在使用的。比特币使用secp256k1曲线。
以太坊使用相同的椭圆曲线secp256k1,因此获取公钥的过程在两种加密货币中都是相同的。
通过将ECDSA应用于私钥 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2 ,我们得到一个64字节的整数,它是两个32字节的整数,表示椭圆曲线上的点的X和Y,连接在一起。
对于我们的例子,我们得到了 1e7bcc70c72770dbb72fea022e8a6d07f814d2ebe4de9ae3f7af75bf706902a7b73ff919898c836396a6b0c96812c3213b99372050853bd1678da0ead14487d7 。
在Python中,它看起来像这样:
<pre spellcheck="false" style="box-sizing: border-box; margin: 5px 0px; padding: 5px 10px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; font-size: 16px; line-height: inherit; font-family: inherit; vertical-align: baseline; cursor: text; counter-reset: list-1 0 list-2 0 list-3 0 list-4 0 list-5 0 list-6 0 list-7 0 list-8 0 list-9 0; background-color: rgb(240, 240, 240); border-radius: 3px; white-space: pre-wrap; color: rgb(34, 34, 34); letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">private_key_bytes = codecs.decode(private_key, ‘hex’)
Get ECDSA public key
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’)
</pre>
注意:正如你从上面的代码中看到的,我使用了 ecdsa 模块中的方法,并使用 codecs 解码了私钥。这与Python相关,而不是算法本身,但我将解释我们在这里做了什么来消除可能的混淆。
在Python中,至少有两个类可以保留私钥和公钥:“str”和“bytes”。第一个是字符串,第二个是字节数组。Python中的加密方法使用“bytes”类,将其作为输入并将其作为结果返回。Python学习交流群:1004391443
现在,有一个小问题:一个字符串,比方说, 4f3c 不等于字节数组 4f3c 。相反,它等于具有两个元素的字节数组, O& lt;。这就是 codecs.decode 方法所做的:它将字符串转换为字节数组。对于我们将在本文中进行的所有加密操作,这都是相同的。
钱包地址
一旦我们获得了公钥,我们就可以计算出地址。现在,与比特币不同,以太坊在主要和所有测试网络上都有相同的地址。用户在制作和签署交易时指定他们希望在过程中稍后使用的网络。
要从公钥创建地址,我们需要做的就是将Keccak-256应用于密钥,然后获取结果的最后20个字节。就是这样。没有其他哈希函数,没有Base58或任何其他转换。你唯一需要的是在地址的开头添加“0x”。
这是Python代码:
<pre spellcheck="false" style="box-sizing: border-box; margin: 5px 0px; padding: 5px 10px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; font-size: 16px; line-height: inherit; font-family: inherit; vertical-align: baseline; cursor: text; counter-reset: list-1 0 list-2 0 list-3 0 list-4 0 list-5 0 list-6 0 list-7 0 list-8 0 list-9 0; background-color: rgb(240, 240, 240); border-radius: 3px; white-space: pre-wrap; color: rgb(34, 34, 34); letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public_key_bytes = codecs.decode(public_key, ‘hex’)
keccak_hash = keccak.new(digest_bits=256)
keccak_hash.update(public_key_bytes)
keccak_digest = keccak_hash.hexdigest()
Take the last 20 bytes
wallet_len = 40
wallet = ‘0x’ + keccak_digest[-wallet_len:]
</pre>
校验
现在,你可能还记得,比特币通过哈希公钥并获取结果的前4个字节来创建校验和。对于所有比特币地址都是如此,因此如果不添加校验和字节,则无法获得有效地址。
在以太坊,这不是事情的运作方式。最初,没有校验和机制来验证密钥的完整性。然而,在2016年,Vitalik Buterin 引入了校验和机制,后来被钱包和交易所采用。
将校验和添加到以太坊钱包地址会使其区分大小写。
首先,你需要获取地址的Keccak-256哈希值。请注意,此地址应传递给没有 0x 部分的哈希函数。
其次,迭代初始地址的字符。如果哈希的第i个字节大于或等于8,则将第i个地址的字符转换为大写,否则将其保留为小写。
最后,在结果字符串的开头添加 0x 。如果忽略大小写,则校验和地址与初始地址相同。但大写字母让任何人都检查地址是否确实有效。你可以在此处链接的页面上找到校验和验证的算法。
正如你将在提案中读到的,对于此校验和方案,“平均每个地址将有15个校验位,如果错误输入,随机生成的地址将意外通过检查的净概率为0.0247%。”
这是将校验和添加到以太坊地址的代码:
<pre spellcheck="false" style="box-sizing: border-box; margin: 5px 0px; padding: 5px 10px; border: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-weight: 400; font-stretch: inherit; font-size: 16px; line-height: inherit; font-family: inherit; vertical-align: baseline; cursor: text; counter-reset: list-1 0 list-2 0 list-3 0 list-4 0 list-5 0 list-6 0 list-7 0 list-8 0 list-9 0; background-color: rgb(240, 240, 240); border-radius: 3px; white-space: pre-wrap; color: rgb(34, 34, 34); letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">checksum = ‘0x’
Remove ‘0x’ from the address
address = address[2:]
address_byte_array = address.encode(‘utf-8’)
keccak_hash = keccak.new(digest_bits=256)
keccak_hash.update(address_byte_array)
keccak_digest = keccak_hash.hexdigest()
for i in range(len(address)):
address_char = address[i]
keccak_char = keccak_digest[i]
if int(keccak_char, 16) >= 8:
checksum += address_char.upper()
else:
checksum += str(address_char)
</pre>
结论
如你所见,为以太坊创建地址比比特币简单得多。我们需要做的就是将ECDSA应用于公钥,然后应用Keccak-256,最后获取该哈希的最后20个字节。
<tt-image data-tteditor-tag="tteditorTag" contenteditable="false" class="syl1561968754660" data-render-status="finished" data-syl-blot="image" style="box-sizing: border-box; cursor: text; color: rgb(34, 34, 34); font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", "Helvetica Neue", Arial, sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial; display: block;"> image<input class="pgc-img-caption-ipt" placeholder="图片描述(最多50字)" value="" style="box-sizing: border-box; outline: 0px; color: rgb(102, 102, 102); position: absolute; left: 187.5px; transform: translateX(-50%); padding: 6px 7px; max-width: 100%; width: 375px; text-align: center; cursor: text; font-size: 12px; line-height: 1.5; background-color: rgb(255, 255, 255); background-image: none; border: 0px solid rgb(217, 217, 217); border-radius: 4px; transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1) 0s;"></tt-image>
如果你想使用代码,我将其发布到 GitHub存储库 。
======================================================================
分享一些比特币、以太坊、EOS、Fabric等区块链相关的交互式在线编程实战教程:
- java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
- php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
- c#比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。
- java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
- python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
- php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
- 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
- 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
- ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
- C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
- EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
- 深入浅出玩转EOS钱包开发 ,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
- Hyperledger Fabric 区块链开发详解 ,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
- Hyperledger Fabric java 区块链开发详解 ,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。
- tendermint区块链开发详解 ,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。
网友评论