主页 > imtoken钱包官网版最新 > 以太坊地址是怎么来的? 以太坊地址生成过程

以太坊地址是怎么来的? 以太坊地址生成过程

imtoken钱包官网版最新 2023-03-13 05:58:39

以太坊地址是怎么来的 以太坊地址生成过程

以太坊地址是怎么来的

生成私钥的过程依赖于伪随机数生成器 (PRNG) 和足够的熵。 私钥最重要的是它是一个随机选择的整数以太坊私钥生成过程,范围从 1 到 2²⁵⁶-1。 此范围内的任何数字都可以用作私钥。

以太坊地址是怎么来的 以太坊地址生成过程

现在我们已经了解了私钥背后的数学原理,我们可以自己生成有效的私钥。 我们不妨把私钥的生成过程想象成一个78位的横向数字组合锁(可能的组合数恰好等于2²⁵⁶-1),然后我们把这个组合锁分成3行,每行26位. 您可以将 PRNG 函数视为随机打乱数字以创建数字组合的东西:开始时每一位都是 0,然后为每一位随机选择一个特定的数字。 假设我们使用PRNG函数生成数字的随机组合,得到如下三行数字:

(1) 04406941321102621719184878;

(2) 43014596507006094171646853;

(3) 06780198554267270848908554;

以太坊地址是怎么来的 以太坊地址生成过程

- 浏览器使用 Web Cryptography API(提供加密原语,如 Crypto.getRandomValues(32),或等效的 32 字节缓冲区)作为 PRNG。 此 PRNG 使用您计算机的熵源作为随机种子来生成随机数。 生成随机数时,请务必使用电子熵源,因为有研究表明,人类不善于选择随机数(人自己选择的数字是有规律的,不符合伪随机要求)——

恭喜!您现在是私钥

44069413211026217191848784301459650700609417164685306780198554267270848908554 的所有者。

我们可以使用这个私钥生成比特币或以太坊地址,或者任何区块链上的地址,私钥范围从 1 到 2²⁵⁶-1。

要从这个私钥生成以太坊地址,我们需要用到椭圆曲线点积算法(需要专门的文章来说明)。 因此,为简单起见,我们将其留给计算机。 为此,我们需要将这个私钥“告诉”计算机。 问题是,计算机不处理十进制形式的信息,它只理解二进制代码。 目前,我们只有十进制形式的私钥。 因此,我们首先需要将私钥从十进制数形式转换为计算机可以理解的位(bit,又译为“位”或“位”)和字节(byte,一个字节等于8位)。

在继续之前,我们需要了解什么是位和字节。 任何数字设备只能理解由 0 和 1 组成的信息,通常称为位。 位是“二进制数字”,即仅使用 1 和 0 表示的数字。 虽然我们的智能手机和电脑可以显示汉字和图片,可以播放歌曲,但它们都是代表和处理这些信息的比特。 比特越多代表的信息越多,但最终也不过是一堆0和1而已。

根据上下文,多个位可以表示一个字符(例如,字母a在使用ASCII编码时定义为01100001)或一个数字(01100001也可以用来表示十进制数97)。 当您将十进制整数转换为二进制形式时,您将其转换为以 2 为底的幂的总和,其中每次幂的指数都会增加。 例如,我们通常以十进制形式计数,即以 10 为底数的幂和。 因此,在使用二进制时,我们可以用n位来表示和存储2的N次方以内的整数。

以太坊地址是怎么来的 以太坊地址生成过程

- 8 位视频游戏机可以表示的最高十进制数是 255,因为它们使用的中央处理器(CPU)最多只能对 8 位进行运算(译者注:上图左侧解释为什么N位可以表示2的N次方以内的数——因为数的组合有2的N次方可能;右边演示一个二进制数代表多少个整数,即相互转换的计算规则——

虽然我们可以用二进制的形式来表示任何数,但是二进制的形式太“笨重”了。 要表示 97,我们需要 8 个二进制数字。 二进制数对计算机来说很容易处理,但对人类来说却很难阅读。 出于这个原因,计算机通常以十六进制而不是二进制表示数据:位置数字系统表示以 16 为基数的数字。一个十六进制数可以表示四个二进制数。 我们可以用十六进制数61来表示二进制数01100001或者十进制数97,比二进制少6位。 十六进制数用ABCDEF表示10到15,常用来缩减数据。

回到私钥,我们知道私钥的取值范围是1到2²⁵⁶-1。 我们如何用位来表示它? 需要多少位? 如上所述,将十进制整数转换为二进制形式时,将其转换为以 2 为底的幂的和。使用 8 位二进制数时,我们可以表示的最大数是 2⁷ + 2⁶ + 2⁵ + 2⁴ + 2³ + 2² + 2¹ + 2⁰,整数255。可见,要表达2^n以内的数,需要n位。 由此可以推断,我们需要 256 位,或 32 字节(256/8)来表示我们的私钥。

以太坊地址是怎么来的 以太坊地址生成过程

- 十六进制数据表示旨在减少表示数字所需的位数。 然而,计算机仍然只使用二进制来处理数据——

如果我们同意我们需要32个字节来表示我们在[1, 2²⁵⁶-1]范围内的私钥,那么在十六进制中我们需要64个数字来表示私钥。现在,我们可以取原始私钥

44069413211026217191848784301459650700609417164685306780198554267270848908554

转换为十六进制形式:

616E6769652E6A6A706572657A616775696E6167612E6574682E6C696E6B0D0A

看到十六进制私钥中多出的字母A、B、C、D、E了吗? 看到这些字母,我们很容易看出这个数字是十六进制的。

现在,我们可以将这个十六进制私钥告诉我们的计算机。 我们可以使用 JavaScript 之类的编程语言轻松导入此十六进制私钥,以供以后乘法使用。 在下面的代码中,将前面得到的十六进制数导入为私钥(“sk”是secret_key的缩写,是密码学中的标准表示法)。 十六进制数以 16 为底。

以太坊地址是怎么来的 以太坊地址生成过程

- 通过使用 BigNumber 库,我们可以确保在转换过程中不会丢失任何小数。 这些数字通常表示为指数(例如,4.406941321102622e+76),如果我们将它们直接解析为十六进制,则会失去精度。如果不使用 BigNumber 库,我们得到的十六进制私钥将变为

616e6769652e6c000000000000000000000000000000000000000000000000000 –

导入私钥后,下一步就是创建公钥。 你可能还记得我们在第一篇文章中提到,在获得以太坊地址之前,我们需要从私钥生成公钥。 根据以太坊黄皮书,公钥生成过程遵循标准的ECDSA公钥生成算法,其中我们将私钥乘以生成点得到一个坐标,并将坐标的x和y值放在一起它是公钥。 我们的公钥(在密码学中表示为“pk”)可用于生成我们的以太坊地址。

以太坊地址是怎么来的 以太坊地址生成过程

- x 和 y 是使用椭圆曲线上的点乘以我们的私钥 (sk) 获得的。 虽然私钥在任何区块链中都可以作为地址的唯一生成器,但以太坊独家使用椭圆曲线secp256k1来生成公钥; 因此,私钥的签名操作也与这条曲线有关——

终于到了最后一步。 有了公钥在手,我们执行黄皮书最后的操作:

给定私钥,以太坊地址 A 是相应 ECDSA 公钥的 Keccak 散列的最右边的 160 位。

鉴于我们已经有了 ECDSA 公钥,剩下的唯一事情就是对我们的公钥执行 Keccak 哈希函数,取结果的最右边的 160 位。 当我们将这些操作的结果存储在“缓冲区”(就像一个存储信息的小盒子)中时,我们可以“扔掉”(切片)前 24 个十六进制数,只留下最后 40 个十六进制数,或者更准确地说, 20 字节(这是以太坊地址的长度)。

以太坊地址是怎么来的 以太坊地址生成过程

- 以太坊地址设计为 20 字节。 有人建议删除一些字节(具体为 12 个字节)可能会导致冲突,从而导致两个私钥生成相同的以太坊地址。 不过,到目前为止,这还没有发生——

可以看到,只需一个数字(虽然很长)就可以生成一个以太坊地址来存储各种资产:从代表虚拟猫、磁带、袜子和门票等物品的 NFT,到具有增值功能的加密资产潜力等。 你的以太坊地址是公开的以太坊私钥生成过程,就像你的家庭住址一样,但只能用钥匙打开。 如果您不想自己处理所有这些流程,您可以在 Portis 上注册一个帐户。 Portis 会自动为你创建一个私钥(这个私钥只有你自己知道,因为它采用了端到端的加密架构)和一个对应的以太坊地址,供你在 100 多个 dApp 中使用。

以太坊地址生成过程

以太坊地址生成过程如下:

1、生成一个256位的随机数作为私钥。

2.将私钥转换为secp256k1未压缩格式的公钥,即512位公钥。

3、使用哈希算法Keccak256计算出公钥的哈希值,并转换成十六进制字符串。

4、取十六进制字符串的最后40个字母,在开头加上0x作为地址。

以太坊地址生成示例

生成以太坊地址流程实例数据:

私钥:1f2b77e3a4b50120692912c94b204540ad44404386b10c615786a7efaa065d20

公钥:04dfa13518ff965498743f3a01439dd86bc34ff9969c7a3f0430bbf8865734252953c9884af787b2cadd45f92dff2b81e21cfdf98873e492e5fdc07e9eb67ca74d

地址:0xabcd68033A72978C1084E2d44D1Fa06DdC4A2d57

生成一个 256 位的随机数:

>>> import random
>>> r = random.randint(0, 2**256)
>>> r
14098500174935566811277058424286341448580475958153633347646702637404947635488
>>> r.to_bytes(32, byteorder='big').hex()
'1f2b77e3a4b50120692912c94b204540ad44404386b10c615786a7efaa065d20'

以太坊使用的椭圆曲线算法是secp256k1。 从私钥生成对应的公钥有两种方式:比特币工具bx和secp256k1-py包。

Mac 用户可以使用 brew 安装 bx 工具:

$ brew install bx

将1f2b77e3a4b50120692912c94b204540ad44404386b10c615786a7efaa065d20作为私钥,然后使用bx工具将私钥转换成secp256k1未压缩的公钥:

$ bx ec-to-public 1f2b77e3a4b50120692912c94b204540ad44404386b10c615786a7efaa065d20 -u
04dfa13518ff965498743f3a01439dd86bc34ff9969c7a3f0430bbf8865734252953c9884af787b2cadd45f92dff2b81e21cfdf98873e492e5fdc07e9eb67ca74d

使用 pip 安装:

$ pip install secp256k1

然后将私钥转换为公钥:

>>> import secp256k1
>>> private_key = '1f2b77e3a4b50120692912c94b204540ad44404386b10c615786a7efaa065d20'
>>> private_key = bytes.fromhex(private_key)
>>> privkey = secp256k1.PrivateKey(private_key)
>>> privkey.pubkey.serialize(compressed=False).hex()
'04dfa13518ff965498743f3a01439dd86bc34ff9969c7a3f0430bbf8865734252953c9884af787b2cadd45f92dff2b81e21cfdf98873e492e5fdc07e9eb67ca74d'

要使用 keccak256 哈希算法,您可以使用 PyCryptodome 工具,使用 pip 安装:

$ pip install pycryptodome

把公钥开头的04去掉,剩下的部分转成字节串,用keccak256算法哈希:

>>> from Crypto.Hash import keccak
>>> keccak_hash = keccak.new(digest_bits=256)
>>> public_key = '04dfa13518ff965498743f3a01439dd86bc34ff9969c7a3f0430bbf8865734252953c9884af787b2cadd45f92dff2b81e21cfdf98873e492e5fdc07e9eb67ca74d'[2:]
>>> public_key = bytes.fromhex(public_key)
>>> keccak_hash.update(public_key)

>>> keccak_hash.hexdigest()
'39c0eb3b26d4838930b1f34babcd68033a72978c1084e2d44d1fa06ddc4a2d57'

取哈希值十六进制字符串的最后40个字母,在开头加上0x,生成最终的以太坊地址:

>>> '0x' + '39c0eb3b26d4838930b1f34babcd68033a72978c1084e2d44d1fa06ddc4a2d57'[-40:]
'0xabcd68033a72978c1084e2d44d1fa06ddc4a2d57'

使用Python3实现以太坊地址生成:

import secp256k1
from Crypto.Hash import keccak
def get_eth_addr(private_key_str=None):
    if private_key_str is None:
        private_key = secp256k1.PrivateKey()
        private_key_str = private_key.serialize()
    else:
        private_key_bytes = bytes.fromhex(private_key_str)
        private_key = secp256k1.PrivateKey(private_key_bytes)
    public_key_bytes = private_key.pubkey.serialize(compressed=False)
    public_key_str = public_key_bytes.hex()
    keccak_hash = keccak.new(digest_bits=256)
    keccak_hash.update(public_key_bytes[1:])
    h = keccak_hash.hexdigest()
    address = '0x' + h[-40:]
    return {
        "private_key": private_key_str,
        "public_key": public_key_str,
        "address": address
    }

:可以作为生成以太坊号地址的工具,代码开源:。

: Keccak python 工具。

: Python2环境下使用的Keccak,这是源码,本地使用需要clone。

: secp256k1 的 Python 库。