以太坊私钥介绍及生成与验证

1)私钥格式

Bitcoin私钥(或其他加密货币私钥)有32 bytes,(或256个bit),或者其他形式表示,Base64 string、a WIF key、助记词

以太坊私钥介绍及生成与验证_第1张图片

2)为什么是32bytes

比特币使用 ECDSA 或椭圆曲线数字签名算法。更具体地说,它使用称为 secp256k1 的特定曲线。这条曲线的阶数为 256 位,以 256 位为输入,输出 256 位整数。而 256 位正好是 32 字节。对私钥有额外的要求。因为我们使用ECDSA,所以key应该是正数,并且应该小于曲线的阶数

3)生成方法

3.1)原生方法

import random
bits = random.getrandbits(256) #返回具有指定位数的整数,返回的是十进制
# 30848827712021293731208415302456569301499384654877289245795786476741155372082
bits_hex = hex(bits)  # 字符串格式
# 0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32
private_key = bits_hex[2:]  # 去掉字符串的0x
# 4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32

该方法不适合用于加密货币,因为该方法不安全;该方法基于随机数种子生成,如果知道生成时的时间,容易被暴力破解。

3.2)加强版RNG

import secrets
bits = secrets.randbits(256)
# 46518555179467323509970270980993648640987722172281263586388328188640792550961
bits_hex = hex(bits)
# 0x66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31
private_key = bits_hex[2:]
# 66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31

3.3)有些网站会为您生成随机数

一个是 random.org,一个著名的通用随机数生成器。另一个是 bitaddress.org,它是专门为比特币私钥生成而设计的。

3.4)完整代码

私钥 ——> 公钥 ——> 钱包地址

import codecs
import ecdsa
from Crypto.Hash import keccak

class EthereumWallet:
    @staticmethod
    def generate_address(private_key):
        public_key = EthereumWallet.__private_to_public(private_key)
        address = EthereumWallet.__public_to_address(public_key)
        return address
    
    @staticmethod
    def checksum_address(address):
        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)
        return checksum
    
    @staticmethod
    def __private_to_public(private_key):
        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()
        public_key = codecs.encode(key_bytes, 'hex')
        return public_key
    
    @staticmethod
    def __public_to_address(public_key):
        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 last 20 bytes
        wallet_len = 40
        wallet = '0x' + keccak_digest[-wallet_len:]
        return wallet
# 使用
import blocksmith

key = '7077da4a47f6c85a21fe6c6cf1285c0fa06915871744ab1e5a5b741027884d00'

address = blocksmith.EthereumWallet.generate_address(key)
print(address)
# 0x1269645a46a3e86c1a3c3de8447092d90f6f04ed

checksum_address = blocksmith.EthereumWallet.checksum_address(address)
print(checksum_address)
# 0x1269645a46A3e86c1a3C3De8447092D90f6F04ED

参考github链接

经过测试,结果正确!

Note: 如有侵权,请联系删除

你可能感兴趣的:(以太坊,比特币,区块链)