Search code examples
rubybase58

Ruby Base58 for Waves platform


I want to implement Wavesplatform wrapper on ruby for my project. I'm stuck right in the beginning, trying to implement example from Docs with Base58 and Bitcoin alphabet.

The string "teststring" are coded into the bytes [5, 83, 9, -20, 82, -65, 120, -11]. The bytes [1, 2, 3, 4, 5] are coded into the string "7bWpTW".

I use BaseX gem

num = BaseX.string_to_integer("7bWpTW", numerals: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
puts bytes = [num].pack("i").inspect

=> "\x05\x04\x03\x02"

The output somewhat similar to [1, 2, 3, 4, 5] bytes array from example, but I'm not really sure how to properly manipulate bytes.


Solution

  • pack/unpack won’t much help here: the size is undetermined and the integer you get might contain (and in most cases contains) many bytes. One should code a bit here:

    byte_calculator = ->(input, acc = []) do
      rem, val = input.divmod(256)
      acc << (val > 128 ? val - 256 : val)
      rem <= 0 ? acc : byte_calculator.(rem, acc)
    end
    
    byte_calculator.
      (BaseX::Base58.string_to_integer("teststring")).
      reverse
    #⇒ [
    #  [0] 5,
    #  [1] 83,
    #  [2] 9,
    #  [3] -20,
    #  [4] 82,
    #  [5] -65,
    #  [6] 120,
    #  [7] -11
    # ]
    

    The same way one should operate with the reverse conversion:

    BaseX::Base58.integer_to_string([1, 2, 3, 4, 5].
          reverse.
          each_with_index.
          reduce(0) do |acc, (e, idx)| 
      acc + e * (256 ** idx)
    end)
    #⇒ "7bWpTW"