Найти - Пользователи
Полная версия: ECDSA генерирование btc адреса по приватному ключу
Начало » Python для новичков » ECDSA генерирование btc адреса по приватному ключу
1
taxol
Всем доброго времени суток!
На Python 3.6 прекрасно отрабатывает скрипт:
 from ecdsa import SigningKey, SECP256k1
import sha3, random, binascii
private_key = ''.join(['%x' % random.randrange(16) for x in range(0, 64)])
print(private_key)
private_key = bytes(private_key, 'utf-8')
private_key = binascii.unhexlify(private_key)
priv = SigningKey.from_string(private_key, curve=SECP256k1)
pub = priv.get_verifying_key().to_string()
keccak = sha3.keccak_256()
keccak.update(pub)
address = keccak.hexdigest()[24:]
print(address, priv.to_string().hex())
Имеется ключ, теперь уже не рандомный: 0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c, которому необходимо сопоставить адрес.
В коде меняю: private_key = ''.join() на следующую строку: private_key = hex(0x0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c)
И получаю ошибку: TypeError: argument should be bytes, buffer or ASCII string, not ‘int’
  from ecdsa import SigningKey, SECP256k1
>>> import sha3, random, binascii
>>> private_key = binascii.unhexlify(0x0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: argument should be bytes, buffer or ASCII string, not 'int'
>>> private_key = bytes(private_key, 'utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: encoding without a string argument
>>> private_key = binascii.unhexlify(private_key)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
binascii.Error: Odd-length string
>>> priv = SigningKey.from_string(private_key, curve=SECP256k1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\HP\AppData\Local\Programs\Python\Python36\lib\site-packages\ecdsa\keys.py", line 885, in from_string
    "expected {1}".format(len(string), curve.baselen)
ecdsa.keys.MalformedPointError: Invalid length of private key, received 65, expected 32
>>> pub = priv.get_verifying_key().to_string()
>>> keccak = sha3.keccak_256()
>>> keccak.update(pub)
>>> address = keccak.hexdigest()[24:]
>>> print(address, priv.to_string().hex())
c33933da59315d4f0a24d7bfa8925b4fd7d676d7 e826c7c6ea00a8aee357eb87287fd5e1028c26ec06dc479700d884121a23bd82

Несколько иная реализация на Python 3.8, т.к. sha3 (pysha3) не адаптирован для работы с питоном выше 3.6:
 import ecdsa
import hashlib
import base58
with open("C:\Users\HP\Desktop\btc\python scripts\file.txt", "r") as f:    #Input file path
 data=f.readline()
 for line in data:
                  #Convert hex private key to bytes
  private_key = bytes.fromhex(data)      
                  #Derivation of the private key
  signing_key = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
  verifying_key = signing_key.get_verifying_key()
  public_key = bytes.fromhex("04") + verifying_key.to_string()
                 #Hashes of public key
  sha256_1 = hashlib.sha256(public_key)
  ripemd160 = hashlib.new("ripemd160")
  ripemd160.update(sha256_1.digest())
                 #Adding prefix to identify Network
  hashed_public_key = bytes.fromhex("00") + ripemd160.digest()
                 #Checksum calculation
  checksum_full = hashlib.sha256(hashlib.sha256(hashed_public_key).digest()).digest()
  checksum = checksum_full[:4]
                 #Adding checksum to hashpubkey         
  bin_addr = hashed_public_key + checksum
                 #Encoding to address
  address = str(base58.b58encode(bin_addr))
  final_address = address[2:-1]
  print(final_address)
  with open("my_addresses.txt", "a") as i:
   i.write(final_address)
По указанному адресу находится число 0009c863300f9028d2c988168edb4922aadba80f9af71ffb715
Однако возникает аналогичная ошибка
 >>> import ecdsa
>>> import hashlib
>>> import base58
>>>
>>>
>>> with open(r"C:\Users\HP\Desktop\btc\python_scripts\file.txt", "r") as f:    #Input file path
...  data=f.readline()
...  for line in data:
...                   #Convert hex private key to bytes
...   private_key = bytes.fromhex(data)
...                   #Derivation of the private key
...   signing_key = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
...   verifying_key = signing_key.get_verifying_key()
...   public_key = bytes.fromhex("04") + verifying_key.to_string()
...                  #Hashes of public key
...   sha256_1 = hashlib.sha256(public_key)
...   ripemd160 = hashlib.new("ripemd160")
...   ripemd160.update(sha256_1.digest())
...                  #Adding prefix to identify Network
...   hashed_public_key = bytes.fromhex("00") + ripemd160.digest()
...                  #Checksum calculation
...   checksum_full = hashlib.sha256(hashlib.sha256(hashed_public_key).digest()).digest()
...   checksum = checksum_full[:4]
...                  #Adding checksum to hashpubkey
...   bin_addr = hashed_public_key + checksum
...                  #Encoding to address
...   address = str(base58.b58encode(bin_addr))
...   final_address = address[2:-1]
...   print(final_address)
...   with open("my_addresses.txt", "a") as i:
...    i.write(final_address)
...
Traceback (most recent call last):
  File "<stdin>", line 5, in <module>
ValueError: non-hexadecimal number found in fromhex() arg at position 51
>>>
>>>

Насколько могу полагать, проблема в представлении числа, которое в одном случае питон распознает как строковое значение, в другом int и т.д.

В целом система работает, если вручную ввести ключ. Проблемы возникают при экспорте из .txt



Заранее благодарен за содействие.

py.user.next
taxol
В коде меняю: private_key = ''.join() на следующую строку: private_key = hex(0x0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c)
Там вообще все строки по созданию ключа можно заменить на
  
>>> private_key = bytes.fromhex('0ffe1abd1a08215353c233d6e009613e95eec4253832a761af28ff37ac5a150c')
>>> private_key
b'\x0f\xfe\x1a\xbd\x1a\x08!SS\xc23\xd6\xe0\ta>\x95\xee\xc4%82\xa7a\xaf(\xff7\xacZ\x15\x0c'
>>>
taxol
Заключительный аккорд, подскажите, при чтении ключей (записаны построчно в file.txt) отрабатывает только по первому ключу, при этом многократно повторяется:
 >>> import ecdsa
>>> import hashlib
>>> import base58
>>>
>>>
>>> with open(r"C:\Users\HP\Desktop\btc\python_scripts\file.txt", "r") as f:    #Input file path
...  data=f.readline()
...  for line in data:
...                   #Convert hex private key to bytes
...   private_key = bytes.fromhex(data)
...                   #Derivation of the private key
...   signing_key = ecdsa.SigningKey.from_string(private_key, curve=ecdsa.SECP256k1)
...   verifying_key = signing_key.get_verifying_key()
...   public_key = bytes.fromhex("04") + verifying_key.to_string()
...                  #Hashes of public key
...   sha256_1 = hashlib.sha256(public_key)
...   ripemd160 = hashlib.new("ripemd160")
...   ripemd160.update(sha256_1.digest())
...                  #Adding prefix to identify Network
...   hashed_public_key = bytes.fromhex("00") + ripemd160.digest()
...                  #Checksum calculation
...   checksum_full = hashlib.sha256(hashlib.sha256(hashed_public_key).digest()).digest()
...   checksum = checksum_full[:4]
...                  #Adding checksum to hashpubkey
...   bin_addr = hashed_public_key + checksum
...                  #Encoding to address
...   address = str(base58.b58encode(bin_addr))
...   final_address = address[2:-1]
...   print(final_address)
...
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
1CC3X2gu58d6wXUWMffpuzN9JAfTUWu4Kj
py.user.next
taxol
Заключительный аккорд, подскажите, при чтении ключей (записаны построчно в file.txt) отрабатывает только по первому ключу, при этом многократно повторяется:
taxol
  
with open(r"C:\Users\HP\Desktop\btc\python_scripts\file.txt", "r") as f:    #Input file path
    data = f.readline()
    for line in data:
  
with open(r"C:\Users\HP\Desktop\btc\python_scripts\file.txt", "r") as f:    #Input file path
    for line in f:
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB