http://www.7klian.com

科普|以太坊地址

免责声明:本文中涉及的所有私钥仅用于教育目的。请勿使用本文中共享的任何代码、密钥或地址来持有任何类型或数量的加密资产。

私钥作为原材料

正如的第一篇文章“了解私钥”中提到的,生成私钥的过程依赖于伪随机数生成器(PRNG)和足够大的熵。关于私钥,需要记住的最重要的一点是,它是从 1 到?2???-1?的范围内随机选出的整数。只要是在这个范围内的数,都可以用作私钥。

既然我们已经了解了私钥背后的一些数学原理,我们就可以继续生成我们自己的有效私钥了。我们不妨将私钥生成过程想象成一个长达 78 位的水平数字组合锁(其可能组合数量恰好等于?2???-1),然后我们把这个密码锁分成 3 排,每排有 26 位。

你可以把 PRNG 函数想象成一个会随机打乱数字,打乱出一个数字组合的东西:从 0 开始,然后选择一个没有任何可区分模式的数字。假设我们使用 PRNG 函数生成乱序的数字组合,得到以下三排数字:

(1)04406941321102621719184878;(2)43014596507006094171646853;(3)06780198554267270848908554;

浏览器使用 Web Cryptoography API,这是一种现代的API,它为我们提供 Crypto.getRandomValues(32)等加密原语(或相当于创建一个32字节的缓冲区)作为 PRNG,它与您的计算机熵源一起播种以生成随机数。正如一些研究表明的那样,你应该总是使用数字源来生成随机数,因为人类比较不擅长选择随机数字。

恭喜!您现在是私钥的合法所有者:

44069413211026217191848784301459650700609417164685306780198554267270848908554

我们现在可以使用它来生成比特币或以太坊地址,或者任何以 1 至?2???-1?为私钥范围的区块链的地址。

要从这个私钥生成一个以太坊地址,我们需要进行椭圆曲线点乘法,这可能是一篇单独的文章。所以,为了方便起见,我们将使用一台计算机,并让它为我们做这件事。

要做到这一点,我们需要“告诉”计算机这个私钥。但不幸的是,计算机不处理十进制格式的信息。计算机只理解二进制码,到目前为止,我们只有十进制数字形式的私钥。

因此,要使用我们的私钥,我们需要首先将十进制数值转换成计算机可以理解的东西:位和字节。

位和字节

在继续使用私钥之前,我们需要了解位和字节。任何数字设备都只能使用数字 0 和 1(通常称为位)来理解信息。位是“二进制数字”,即表示为 1 或 0 的数字。

虽然我们的智能手机和计算机可以显示字符、图像、歌曲等,但计算机最终将所有内容表示和处理为比特。更直截了当地说,位组代表更大的事物,但它们始终只是一堆 0 和 1。

根据使用的上下文,多个位可以表示字符(例如,字母a可以使用ASCII码定义为01100001)或数字(即,相同的值01100001表示十进制格式的数字97)。在将十进制整数转换为二进制形式时,就是将其转换成以 2 为底数的幂之和,其中每个幂的指数递增。

例如,我们通常以十进制格式计数,其中数字表示为使用的所有数字的幂的和,使用数字 10 作为基数。然而,使用二进制时,我们可以将数字表示为2 的 N 次方,其中“n”是在计算机中表示和存储该信息所需的位数。

8 位电子游戏最高能够表达的十进制数是 255,因为其中使用的计算机处理单元(CPU)只能执行最多 8 位的操作。

虽然我们可以用二进制格式表示任何数字,但二进制格式相当“繁冗”。仅表示97,我们就需要 8 个二进制数字。二进制数对计算机来说很容易处理,但是不方便人类阅读。

因此,计算机通常不使用二进制格式来表示数据,而是使用十六进制格式:位置数字系统以 16 为底数来表示数字。与二进制格式不同,我们可以用十六进制格式在单个字母中表示 4 位。

我们可以用十六进制数 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 等编程语言,我们可以轻松地以可用于进一步乘法的格式导入私钥。

在下面的代码中,我们定义了我们的私钥(SECRET_KEY的“SK”,这是密码学中使用的一种标准表示法),以导入前面定义的十六进制值。我们使用 16 的底数来提供十六进制格式。

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

616e6769652e6c00000000000000000000000000000000000000000000000000

导入私钥之后,下一步是创建公钥。您可能还记得我们的第一篇文章,我们需要从在获取以太坊地址之前,我们先要通过私钥来生成公钥。

按照以太坊的黄皮书中的所述,公钥生成过程遵循的是标准的 ECDSA 公钥生成算法,其中,我们将私钥乘以生成器点得到一个坐标,将该坐标的 x 值和 y 值前后拼在一起就是公钥。我们的公钥(在密码学中记为“pk”)可以用来生成我们的以太坊地址。

x 和 y 的值由我们的私钥(sk)乘椭圆曲线点得到。尽管私钥可以在任何区块链中用作地址的唯一生成器,但以太坊在使用椭圆曲线 secp256k1 生成公钥;因此,私钥的签名操作也跟这条曲线有关。

最后一步。定义了公钥后,我们可以执行黄皮书中的最后一条指令,定义如下:

对于给定的私钥,以太坊地址 A 被定义为对应的 ECDSA 公钥的 Keccak 哈希值的最右 160 位。

鉴于我们已经有了我们的 ECDSA 公钥,剩下的唯一事情就是对我们的公钥运行 Keccak 哈希函数,并从这个操作中获得最右边的 160 位。

当我们将这些操作存储在“缓冲区”中时(想想我们用来存储字节信息的小盒子),我们可以简单地“删除”(切片)前 24 个十六进制数,只留下 40 个十六进制数,或者更具体地说,20 个字节,相当于一个以太坊地址的大小。

以太网地址设计为 20 字节。通过删除一些字节(准确地说是12个字节),可能会发生冲突,即两个私钥最终生成相同的以太坊地址。然而,到今天为止,这还没有发生。

你的个人专属钱包

正如您所看到的,从单个数字(尽管很长),您可以获得一个以太地址,您可以在其中持有各种资产:从代表小猫、磁带、袜子、门票等的 NFT 到具有增值潜力的密码学资产等等。

您的以太坊地址是公开的,而且像您的家庭住址一样,它将您连接到唯一的私钥。

在本系列下一篇中,我们将介绍如何使用私钥来创建并广播交易、签署消息,以及这些签名在以太坊生态中有什么影响。

End

非常感谢您对 IPFS&Filecoin 项目的持续支持。我们很高兴继续与您一起,为人类信息建立一个强大的,去中心化和高效的基础。

FilCloud 帮你迅速了解 IPFS 领域的热点技术和应用公众号:filcloud

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。