2016-05-07 6 views
2

Ich versuche, mit Hilfe dieser Anleitung Bitcoin-Adressen in Ruby zu generieren:Wie eine Bitcoin-Adresse in Ruby generieren

https://bhelx.simst.im/articles/generating-bitcoin-keys-from-scratch-with-ruby/

Aber etwas ist nicht ganz richtig, da die Adressen aren erzeugt werden‘ t kommt ganz richtig raus.

Hier ist die Klasse Ich verwende:

require 'openssl' 
require 'ecdsa' 
require 'securerandom' 
require 'base58' 

class BitcoinAddressGenerator 

    ADDRESS_VERSION = '00' 

    def self.generate_address 
    # Bitcoin uses the secp256k1 curve 
    curve = OpenSSL::PKey::EC.new('secp256k1') 

    # Now we generate the public and private key together 
    curve.generate_key 

    private_key_hex = curve.private_key.to_s(16) 
    puts "private_key_hex: #{private_key_hex}" 
    public_key_hex = curve.public_key.to_bn.to_s(16) 
    puts "public_key_hex: #{public_key_hex}" 

    pub_key_hash = public_key_hash(public_key_hex) 
    puts "pub_key_hash: #{pub_key_hash}" 

    address = generate_address_from_public_key_hash(public_key_hash(public_key_hex)) 

    puts "address: #{address}" 
    end 

    def self.generate_address_from_public_key_hash(pub_key_hash) 
    pk = ADDRESS_VERSION + pub_key_hash 
    encode_base58(pub_key_hash + checksum(pub_key_hash)) 
    end 

    def self.int_to_base58(int_val, leading_zero_bytes=0) 
    alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 
    base58_val, base = '', alpha.size 
    while int_val > 0 
     int_val, remainder = int_val.divmod(base) 
     base58_val = alpha[remainder] + base58_val 
    end 
    base58_val 
    end 

    def self.encode_base58(hex) 
    leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : '').size/2 
    ("1"*leading_zero_bytes) + int_to_base58(hex.to_i(16)) 
    end 

    def self.checksum(hex) 
    sha256(sha256(hex))[0...8] 
    end 

    # RIPEMD-160 (160 bit) hash 
    def self.rmd160(hex) 
    Digest::RMD160.hexdigest([hex].pack("H*")) 
    end 

    def self.sha256(hex) 
    Digest::SHA256.hexdigest([hex].pack("H*")) 
    end 

    # Turns public key into the 160 bit public key hash 
    def self.public_key_hash(hex) 
    rmd160(sha256(hex)) 
    end 

end 

Es gibt so etwas wie:

private_key_hex: C96DE079BAE4877E086288DEDD6F9F70B671862B7E6E4FC0EC401CADB81EDF45 
public_key_hex: 0422435DF80F62E643D3CFBA66194052EC9ED0DFB47A1B26A4731079A5FF84FBF98FF0A540B6981D75BA789E6192F3B38BABEF6B0286CAEB4CAFCB51BB96D97B46 
public_key_hash: db34927cc5ec0066411f366d9a95f9c6369c6e1d 
address: Lz3xnxx6Uh79PEzPpWSMMZJVWR36hJgVL 

Wenn ich diese Adresse in blockchain.info und ähnliche Werkzeuge stecken, sagt es, dass es eine ungültige Adresse ist .

Jede Hilfe würde sehr geschätzt werden.

Antwort

2

In Ihrer generate_address_from_public_key_hash Methode sollte die Prüfsumme über dem Hash einschließlich der Adresse Präfix sein. Sie verwenden die Variable pk derzeit überhaupt nicht, nachdem Sie sie zugewiesen haben. Der Code etwas aussehen sollte:

def self.generate_address_from_public_key_hash(pub_key_hash) 
    pk = ADDRESS_VERSION + pub_key_hash 
    encode_base58(pk + checksum(pk)) # Using pk here, not pub_key_hash 
end 

Der Fehler scheint auch auf der Seite Link zu Ihnen zu sein, ich denke, der Autor muss eine Kopie/Paste Fehler gemacht haben.


Als Nebenwirkung scheint zu halten alles in Hexstring und Decodierung hin und her eine seltsame Art und Weise, dies zu tun. Ich hätte gedacht, dass es einfacher wäre, rohe binäre Zeichenfolgen zu verwenden und beim Ausdrucken nur in Hexadezimalzahlen zu kodieren.