Ruby Quiz - Challenge #15 - Generate the Bitcoin (Base58) Address from the (Elliptic Curve) Public Key

Hello,

  I've posted a new ruby quiz:

   Challenge #15 - Generate the Bitcoin (Base58) Address from the
(Elliptic Curve) Public Key [1].

   Start from scratch or, yes, use any library / gem you can find.

   To qualify for solving the code challenge / puzzle you must pass
the test [2]:

   require 'minitest/autorun'

   class RubyQuizTest < MiniTest::Test

     def test_addr
       pubkey =
'0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352'

       pkh = pk_to_pkh( pubkey )
       assert_equal 'f54a5851e9372b87810a8e60cdd2e7cfd80b6e31', pkh

       prefix = '00'    ## version prefix
       h = checksum( prefix + pkh )
       assert_equal
'c7f18fe8fcbed6396741e58ad259b5cb16b7fd7f041904147ba1dcffabf747fd', h
       assert_equal 'c7f18fe8', h[0..7]

       addr = base58( prefix + pkh + h[0..7] )
       assert_equal '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs', addr
     end # method test_addr
   end # class RubyQuizTest

   Post your code snippets on the "official" Ruby Quiz Channel,
   that is, the ruby-talk mailing list right here.

   Happy hacking and crypto hashing with Ruby. Cheers. Prost.

[1] https://github.com/planetruby/quiz/tree/master/015
[2] https://github.com/planetruby/quiz/blob/master/015/test.rb

Hello,

   A little hint (spoiler alert) for hashing - you have to convert
the hex string to a binary string before hashing.
  See the fantastic (free) Learn Me A Bitcoin website by Greg Walker
  with, yes (!), ruby code samples and unmatched "fun" learn
me-a-style illustrated in-depth explanations [1].

  Happy hacking and crypto hashing with Ruby. Cheers. Prost.

[1] https://learnmeabitcoin.com/glossary/public-key-hash160#code

Hello Ruby Quiz Friends,

    Continuing talking to myself. Just for the record - spoiler alert
(!) - I posted my little test (reference) answer / solution [1] for
the code challenge / quiz #15 - Generate the Bitcoin (Base58)
Address from the
(Elliptic Curve) Public Key..

require 'digest'

module Base58
  ALPHABET = %w[
        1 2 3 4 5 6 7 8 9
      A B C D E F G H J K L M N P Q R S T U V W X Y Z
      a b c d e f g h i j k m n o p q r s t u v w x y z
  ]
  BASE = 58 # note: ALPHABET.length == 58

  def self.encode( hex )
    num = hex.to_i(16)

    buf = String.new
    while num > 0
      remainder = num % BASE
      buf = ALPHABET[remainder] + buf
      num = num / BASE
    end

    # Note: Leading zeros (in bytes, that is, 00 in hex)
    ## need to get preserved and added up front (0 in base58 is 1)
    leading_zero_bytes = (hex.match( /^(0+)/ ) ? $1 : '').size / 2

    (ALPHABET[0]*leading_zero_bytes) + buf
  end
end # module Base58

def base58( hex ) Base58.encode( hex ); end

def hash160( pubkey )
  binary = [pubkey].pack( "H*" ) # Convert to binary (string)
first before hashing
  sha256 = Digest::SHA256.digest( binary )
  ripemd160 = Digest::RMD160.digest( sha256 )
              ripemd160.unpack( "H*" )[0] # Convert back to hex
(string) from binary (string)
end

def hash256( hex )
  binary = [hex].pack( "H*" ) # Convert to binary (string) first
before hashing
  step1 = Digest::SHA256.digest( binary )
  step2 = Digest::SHA256.digest( step1 )
           step2.unpack( "H*" )[0] # Convert back to hex (string)
from binary (string)
end

   Happy crypto hashing with ruby. Cheers. Prost.

[1] https://github.com/planetruby/quiz/blob/master/015/solution.rb