如何将私钥转换为以太坊地址

本文介绍了如何从以太坊私钥派生出公钥和公有地址。文章解释了以太坊中使用的椭圆曲线加密(ECC)secp256k1,展示了通过私钥生成公钥并进一步生成公有地址的步骤,并提供了一个Python代码示例,演示了如何使用私钥计算出相应的公有地址。

将私钥转换为以太坊上的地址

我最近做了大量的以太坊开发工作,并且非常喜欢它的一切,尤其是任何人都可以随时创建数字钱包的能力。以太坊的一个基本要素是私钥的使用,它存储在数字钱包中。然后,我们可以从这个私钥中导出一个公开的标识符。我们已经创建了这样一个安全和可信的基础设施,并且不受任何实体的控制。

在以太坊中,我们使用 ECC(椭圆曲线密码学)来创建一个公钥和一个私钥。私钥被安全地保存起来,然后公钥被用来导出以太坊地址。当我们签署交易时,我们使用我们的私钥来创建一个 ECDSA 签名,这个签名会自动针对我们的以太坊地址进行检查。

以太坊密钥

以太坊公钥(pub)是使用 secp256k1 曲线从私钥(sk)导出的。总的来说,私钥是一个 256 位的随机值,而公钥是曲线上一个 512 位的公钥点。有了这个 pub = skG,其中 G 是 secp256k1 曲线上的基点。然后,我们通过对公钥进行 Keccak 哈希,并使用前 40 个字节来生成一个公共钱包地址。在这种情况下,我们将使用一个私钥,然后生成公钥和公共地址。

在创建密钥(为我们的钱包)时,我们生成一个 256 位的私钥,然后公钥是 secp256k1 ECDSA 曲线上的一个点(x,y 点)。然后,这个密钥使用 Keccak-256(又名 SHA-3)进行哈希,并且低 160 位成为公共以太坊地址:

私钥应该是完全随机的,并且可以生成 2²⁵⁶ 个不同的密钥,因此我们将一个私钥匹配到一个公钥的机会是:

1 in 1,550 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 … 000 (75 zeros — 1.55 quattuorvigintillion)

创建一个以太坊账户

作为一个例子,让我们在 Metamask 钱包上创建一个新账户:

对于这个,我们可以看到钱包的公开地址是:

0xA53E8c5ABa180DC39E2B2319521fbb517a13ae19

如果我们想,我们可以在 Etherscan 上查看 [here]:

这将是某人发送以太币的地址。在 Metamask 中,我们可以查看账户并显示公钥:

接下来,我们可以显示私钥(注意,你不应该向任何人显示你的私钥):

这给出了一个私钥“0x3289cccbc9c65fb424a36e726c48ecb7a0f8d8e61dfdff1dc869107978e53ec9”。现在让我们看看我们是否可以从这个密钥中恢复公有地址。

代码

用 Python 将一个私钥转换成一个公有地址的代码是 [here]:

import binascii
import sha3
import os
import sys
from ecdsa import SigningKey, SECP256k1

s='3289cccbc9c65fb424a36e726c48ecb7a0f8d8e61dfdff1dc869107978e53ec9'

if (len(sys.argv)>1):
        s=str(sys.argv[1])

if (len(s)!=64):
 print("Private key must be 32 bytes long") # 私钥长度必须为 32 字节
 sys.Exit(0)

private_key = binascii.unhexlify(s)
priv = SigningKey.from_string(private_key, curve=SECP256k1)
pub = priv.get_verifying_key().to_string()

keccak_hash = sha3.keccak_256()
keccak_hash.update(pub)
address = keccak_hash.hexdigest()[-40:]

print(f"Private key: {priv.to_string().hex()}\n") # 私钥
print(f"Public key (x,y): {pub.hex()[:64]},{pub.hex()[64:]}\n") # 公钥
print(f"Public address: {address}\n") # 公有地址

你可以看到我们将 hex 地址转换为所需的私钥格式 (priv),然后从中生成公钥 (pub)。然后,我们对公钥进行 Keccak 哈希,然后只取前 20 个字节(40 个十六进制字符)作为公共以太坊地址。

一个例子运行是 [here]:

Private key: 3289cccbc9c65fb424a36e726c48ecb7a0f8d8e61dfdff1dc869107978e53ec9

Public key: 2f3f3f37879e38eb0a4029236452f28996473e93dd816f70fac3df35ab274185,26b92294b0d2c7644152622d5029ef35066ded78c0adc1349a8b642c819c5d65

Public address: a53e8c5aba180dc39e2b2319521fbb517a13ae19

我们看到我们有钱包的正确公共地址。然后我们可以用以下方法检查签名:

signature = priv.sign(message.encode())

print(f"Message: {message}\n") # 消息
print(f"Private key: {priv.to_string().hex()}\n") # 私钥
print(f"Public key (x,y): {pub.to_string().hex()[:64]},{pub.to_string().hex()[64:]}\n") # 公钥
print(f"Public address: {address}\n") # 公有地址

print(f"\nSignature: r={binascii.b2a_hex(signature)[:64].decode()}, s={binascii.b2a_hex(signature)[64:].decode()}")# 签名
print("Verify signature: ",pub.verify(signature, message.encode())) # 验证签名
  • 原文链接: billatnapier.medium.com/...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
billatnapier
billatnapier
江湖只有他的大名,没有他的介绍。