paint-brush
如何使用 Python 从私钥生成以太坊地址经过@rareskills
6,324 讀數
6,324 讀數

如何使用 Python 从私钥生成以太坊地址

经过 RareSkills4m2023/06/01
Read on Terminal Reader

太長; 讀書

以太坊地址是公钥 keccack256 的最后 20 个字节。公钥算法是 secp256k1,与比特币中使用的相同。 因为是椭圆曲线算法,公钥是一个(x,y)对对应椭圆曲线上的一个点。
featured image - 如何使用 Python 从私钥生成以太坊地址
RareSkills HackerNoon profile picture
0-item
1-item
2-item

以太坊地址是公钥 keccack256 的最后 20 个字节。公钥算法是 secp256k1,与比特币中使用的相同。


因为是椭圆曲线算法,公钥是一个(x,y)对对应椭圆曲线上的一个点。

生成椭圆曲线公钥。

公钥是 x 和 y 的串联,这就是我们对其进行哈希处理的内容。

下面提供了代码。


 from ecpy.curves import Curve from ecpy.keys import ECPublicKey, ECPrivateKey from sha3 import keccak_256 private_key = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 cv = Curve.get_curve('secp256k1') pv_key = ECPrivateKey(private_key, cv) pu_key = pv_key.get_public_key() # equivalent alternative for illustration: # concat_x_y = bytes.fromhex(hex(pu_key.Wx)[2:] + hex(pu_key.Wy)[2:]) concat_x_y = pu_key.Wxto_bytes(32, byteorder='big') + pu_key.Wyto_bytes(32, byteorder='big') eth_addr = '0x' + keccak_256(concat_x_y).digest()[-20:].hex() print('private key: ', hex(private_key)) print('eth_address: ', eth_addr)


ecpy 库在这里https://github.com/cslashm/ECPy 。这个库在 python 中实现了椭圆曲线数学,所以它不会像coincurve库使用的比特币 C 实现的包装器那么快。


但是,python 实现允许您逐步查看用于导出公钥的椭圆曲线数学。


您可以使用此代码通过暴力生成以太坊虚荣地址,但请注意,如果您的随机源不安全或随机性不足,您可能会成为类似于此的黑客攻击的受害者。

使用 python 和掷硬币或骰子生成私钥

您可以自己从私钥生成以太坊地址,方法是抛硬币 256 次并写入一个字符串,如果它是正面则为 1,如果它是反面则为 0。

假设您得到以下结果

result = b'1100001011001101010001001100101000001111101101111011001000110001101100011101101011010001011000101111100110010101001001101110111011001000100001010101111100001100100110010010111110110100000010011111100000110101001110000101100101011111001101010001100001000'


您可以使用以下 python 代码将其转换为私钥


# 2 means base 2 for binary private_key = hex(int(result, 2)) # private key is 0x1859a89941f6f646363b5a2c5f32a4ddd910abe19325f6813f06a70b2be6a308


然后,将该私钥插入上一节的代码中,您就可以随机生成地址了。


通过将 16 面骰子掷 64 次并逐个字符地写出产生的十六进制字符串,可以更快地完成同样的事情。请注意,大多数骰子都没有数字零的表示形式,因此您必须从每个结果中减去 1。


如果你只有传统的六边形,你可以写出一个以 6 为底的字符串(不要忘记从每个滚动中减去 1),然后将底数转换为二进制。您需要继续滚动,直到您的私钥至少有 256 位。如果您对随机性特别偏执,可以使用赌场级骰子。


请谨慎使用 Python 的内置随机数库。它不是为了加密安全。如果您不熟悉该主题,我们建议您熟悉加密安全随机性


通常,您不能使用此方法初始化硬件钱包,因为它们使用的 24 字恢复短语与用于签署交易的私钥不同。 24 字恢复短语用于为钱包持有的不同类型的加密派生多个私钥。

数学:关于 secp256k1:来自私钥的公钥

网上已经有很多资料描述了曲线加法在视觉上是什么样子的,所以我们在这里从较低的层次描述。

曲线的形状

secp256k1 定义椭圆曲线的形状 y^2 = x^3 + y (mod p) 其中 p 是素数115792089237316195423570985008687907853269984665640564039457584007908834671663

2^256 – 2^32 – 977


不应将素数p与曲线的阶数混淆。并非每个值 0 < n < p 都满足上面的等式。但是,保证曲线上的操作是封闭的。也就是说,如果两个有效点相加或相乘,结果将是曲线上的有效数字。

起点

secp256k1 中的另一个重要参数是起点 G。由于 G 是椭圆曲线上的一个点,因此它是二维的并且具有参数

x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 y = 32670510020758816978083085130507043184471273380659243275938904335757337482424


要查看 G 是有效点,我们可以将数字插入 python

 x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 p = 115792089237316195423570985008687907853269984665640564039457584007908834671663 assert pow(y, 2, p) == (pow(x, 3) + 7) % p

要创建公钥/私钥对,会创建一个随机数s (这是密钥)。点 G 与自身相加s次,新的点 (x, y) 就是公钥。从 G 导出s是不可行的。


将 G 与自身相加 s 次与乘以 s * G 相同。实际上,我们可以通过剥离库提供的一些抽象来在较低级别看到此操作。


 from ecpy.curves import Curve from sha3 import keccak_256 private_key = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 cv = Curve.get_curve('secp256k1') pu_key = private_key * cv.generator # just multiplying the private key by generator point (EC multiplication) concat_x_y = pu_key.x.to_bytes(32, byteorder='big') + pu_key.y.to_bytes(32, byteorder='big') eth_addr = '0x' + keccak_256(concat_x_y).digest()[-20:].hex() print('private key: ', hex(private_key)) print('eth_address: ', eth_addr)


公钥就是私钥乘以 secp256k1 椭圆曲线上的 G 点。就是这样。

了解更多

立即查看我们的高级区块链训练营,成为了解其他编码员不了解的硬知识的区块链开发人员。


也发布在这里