Categories
Bitcoin

Building Bitcoin: Wallet import format in Ruby

Today I got nowhere near as much done as I wanted. Still have client work! So I knocked out an easy element – built the WIF encoding part.

This was fairly straightforward, since I restructured the code from yesterday and used a lot of the code to help generate encoding.

This is the basic code.

class BitcoinAddress
  ...

  def wif_conversion
    pk = "80" + @private_key
    sha_hash = sha256_hash(sha256_hash(pk))
    checksum = return_checksum(sha256_hash(sha256_hash(pk)))
    sha_hash = sha_hash + checksum
    return generate_base58_address(sha_hash)
  end

  ...
end

Honestly, I just followed this guide from the Wiki. The wiki is so amazing! Very helpful.

Overall code that I wrote:

class BitcoinAddress
  attr_accessor :private_key
  @private_key

  def initialize()
    @private_key = self.generate_private_key
  end

  def generate_private_key
    key = OpenSSL::PKey::EC.new("secp256k1").generate_key.private_key.to_s(16)
    @private_key = key
  end

  def wif_conversion
    pk = "80" + @private_key
    sha_hash = sha256_hash(sha256_hash(pk))
    checksum = return_checksum(sha256_hash(sha256_hash(pk)))
    sha_hash = sha_hash + checksum
    return generate_base58_address(sha_hash)
  end

  def generate_public_key(private_key)
    public_key = private_key.public_key.to_bn.to_s(16)
    return public_key
  end

  def generate_address
    public_key = generate_public_key(@private_key)
    ripmd_hash = ripmd160_hash((sha256_hash(public_key)))
    rip_generate_address = ripmd160_hash((sha256_hash(public_key)))

    ripmd_hash = "00" + ripmd_hash
    rip_generate_address = "00" + rip_generate_address

    ripmd_hash = return_checksum(sha256_hash(sha256_hash(ripmd_hash)))
    return "1" + generate_base58_address(rip_generate_address + ripmd_hash)
  end

  def sha256_hash(key)
    return Digest::SHA2.new(256).hexdigest([key].pack("H*"))
  end

  def ripmd160_hash(key)
    return Digest::RMD160.new.hexdigest([key].pack("H*"))
  end

  def return_checksum(data)
    return data[0..7]
  end

  def generate_base58_address(key)
    return Base58.encode(key.hex(), :bitcoin)
  end

end

That’s all for today. I think tomorrow I will attempt to actually build some critical part of the code. So far, all I have an eighth of a wallet. If I keep it up, I’ll just have built a Bitcoin wallet.

Leave a Reply