Generiert man so eine Bitcoin-Adresse mit Python?

Ich habe also bereits den öffentlichen Schlüssel. Meine Frage ist, ob ich die b58-Codierung korrekt anwende, da Bitcoin b58check verwendet und auch das Präfix x00 hinzufügt. Kann mir das jemand erklären? Vielen Dank.

import hashlib
import base58

# ECDSA Public Key
base64_str = 'MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE7P0EE5amecnYKMlq96RUL3Q+mZJCQrta6iHyjQWtsbbgcBMayhR/CTzDi5j4Fb/wD9EclHt3dpYRyJcl9Rtmug=='

hex_str = base64_str.decode('base64').encode('hex')

sha = hashlib.sha256()
rip = hashlib.new('ripemd160')

sha.update(base64_str.decode('base64'))

rip.update(sha.hexdigest())

# Get address
print base58.b58encode(rip.hexdigest())

Antworten (2)

Wenn der öffentliche Schlüssel korrekt war (siehe Antwort von Mark), ist der Code nicht vollständig (fehlt der Signatur) und enthält einen Hash eines ASCII-Hexdigest, der nicht korrekt ist.
Ich möchte zu dieser Implementierung der Bitcoin-Adresse aus dem öffentlichen Schlüssel beitragen.
Es deckt sowohl den Fall von unkomprimierten als auch von komprimierten Bitcoin-Adressen ab (nur das Ändern des booleschen Werts compress_pubkey).

#!/usr/bin/env python2
# https://en.bitcoin.it/wiki/Protocol_documentation#Addresses

import hashlib
import base58

# ECDSA bitcoin Public Key
pubkey = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b23522cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6'
# See 'compressed form' at https://en.bitcoin.it/wiki/Protocol_documentation#Signatures
compress_pubkey = False


def hash160(hex_str):
    sha = hashlib.sha256()
    rip = hashlib.new('ripemd160')
    sha.update(hex_str)
    rip.update( sha.digest() )
    print ( "key_hash = \t" + rip.hexdigest() )
    return rip.hexdigest()  # .hexdigest() is hex ASCII


if (compress_pubkey):
    if (ord(pubkey[-2:].decode('hex')) % 2 == 0):
        pubkey_compressed = '02'
    else:
        pubkey_compressed = '03'
    pubkey_compressed += pubkey[2:66]
    hex_str = pubkey_compressed.decode('hex')
else:
    hex_str = pubkey.decode('hex')

# Obtain key:

key_hash = '00' + hash160(hex_str)

# Obtain signature:

sha = hashlib.sha256()
sha.update( key_hash.decode('hex') )
checksum = sha.digest()
sha = hashlib.sha256()
sha.update(checksum)
checksum = sha.hexdigest()[0:8]

print ( "checksum = \t" + sha.hexdigest() )
print ( "key_hash + checksum = \t" + key_hash + ' ' + checksum )
print ( "bitcoin address = \t" + base58.b58encode( (key_hash + checksum).decode('hex') ) )
AttributeError: 'str'-Objekt hat kein Attribut 'decode'
Leider ist das Skript nur mit Python 2 gültig , um dem Code in der Frage zu entsprechen - für Python 2&3-Skripte können Sie Folgendes überprüfen: github.com/circulosmeos/bitcoin-in-tiny-pieces

Nein.

Ein öffentlicher Schlüssel (die Daten, die Sie hashen werden) sieht so aus:

04 xx xx xx xx xx ... (uncompressed, 65 hex bytes)

oder

(02 or 03) xx xx xx xx xx ... (compressed, 33 hex bytes)

Es ist kein öffentlicher Schlüssel im DER-Format.

"Es ist kein öffentlicher Schlüssel im DER-Format." Es ist eine base64-Zeichenfolge, die aus einem PEM-Zertifikat extrahiert wurde, das mit generiert wurde: openssl ec -in private_key.pem -pubout -out pub_key.pem Hilft also das Decodieren der base64-Zeichenfolge mit base64_str.decode('base64') nicht? Wie kann ich in diesem Fall mit openssl einen für Bitcoin geeigneten privaten/öffentlichen Schlüssel generieren?
Ich habe keine Referenz gefunden, die erklärt, wie man tatsächlich ein ECDSA-Schlüsselpaar ohne das PEM-Format generiert.
Dies beinhaltet das Rollen Ihrer eigenen Krypto, was Sie nicht sollten. Möglicherweise möchten Sie pyecdsa verwenden, und Sie benötigen keine externen Bibliotheken, um es zu verwenden. In der Dokumentation heißt es, dass VerifyingKey.to_string() die x- und y-Koordinaten als Hex-String zurückgibt. Sie stellen ihm einfach "04" voran und dekodieren es von hex. Außerdem möchten Sie vielleicht pybitcointools sehen, aber diese Bibliothek ist fehlerhaft und ich empfehle nicht, sie zu verwenden.
(1) der komprimierte Punkt beginnt bei 02 oder 03. (2) der Punkt ist genau der 'Wert' (nach dem Entfernen von unbenutzten_Bits) des BIT STRING am Ende der DER-codierten SubjectPublicKeyInfo; Da der AlgorithmIdentifier für EC,secp256k1 immer gleich ist, können Sie einfach die Basis von 64 aufheben, die ersten 23 Oktetts löschen und den Rest behalten, was in Python einfach ist. ...
... @JohnSmith: openssl ecoder openssl pkeykann sowohl binäres DER als auch PEM erstellen, wodurch das Trim-and-Unbase64 gespeichert wird, aber es ist immer noch SPKI und nicht wirklich das, was Sie wollen. openssl asn1parse <pubkey.pem -strparse 20 -out point.binmeldet Fehler 0D07207B, schreibt aber trotz Fehler den gewünschten Wert. (Beachten Sie, dass asn1parse 20 für das Tag des BIT STRING benötigt, während 23 der 'gestrippte' Wert ist.)