Home > Back-end >  How to implement this method in Ruby? or is there third party lib to do this?
How to implement this method in Ruby? or is there third party lib to do this?

Time:01-12

I have this ts function:

import { keccak_256 } from "js-sha3";
import { Buffer } from "buffer/";


export function getNamehash(name: string) {
  let node = "0000000000000000000000000000000000000000000000000000000000000000";

  if (name) {
    let labels = name.split(".");

    for (let i = labels.length - 1; i >= 0; i--) {
      let labelSha = keccak_256(labels[i]);
      node = keccak_256(Buffer.from(node   labelSha, "hex"));
    }   
  }

  return "0x"   node;
}

and when calling this method, it gives results like:

getNamehash("a")
// "0xc3025f6c23b9ab4d91adbcccf350072ec880c65db9a3f42e802fe4ceed56e728"

getNamehash("a.b")
// "0xa57dcb7e802753630ec035bae538ca332465791509b1375525fe8b3b0bada7ef"

getNamehash("abc.def")
// "0xc3025f6c23b9ab4d91adbcccf350072ec880c65db9a3f42e802fe4ceed56e728"

How to implement this method in Ruby?

please don't hurry to vote close for this question, I have spent several hours to do this, and got this:

# gem install keccak256   , website: https://github.com/evtaylor/keccak256
require 'keccak256'

  def _nodejs_buffer_to_hex origin_string
    #origin_string = "ce159cf3"

    i = 0 
    result = []
    temp = ""
    loop do
      break if i == origin_string.length
      temp  = origin_string[i]
      if i % 2 == 1
        result << temp
        temp = ""
      end 
      i  = 1
    end

    result = result.map do |e| 
      "0x#{e}".hex
    end 
    return result
  end 

  def get_name_hash name
    node = "0" * 64

    if (name)
      labels = name.split(".")
      i = labels.size - 1 
      while i >= 0
        labelSha = Digest::Keccak256.new.hexdigest(labels[i])
        # here will throw the exception: 
        node = Digest::Keccak256.new.hexdigest(_nodejs_buffer_to_hex(node   labelSha))
        i -= 1
      end
    end

    return "0x"   node;
  end

the ruby code above gives me this error:

    TypeError:
       no implicit conversion of Array into String
     # ./sdk.rb:160:in `hexdigest'

since the Digest::Keccak256.new.hexdigest only accept String , not Array.

any ideas?

thanks a lot!

CodePudding user response:

Here you are returning array instead of string which is then being passed to Digest::Keccak256.new.hexdigest
Change this:

result = result.map do |e| 
  "0x#{e}".hex
end

return result

To this:

return result.join

Same can be achieved with:

result = []
"abcd".split("").each_with_index {|letter, idx|
  if idx % 2 == 1
    result << letter.hex
  end
}

CodePudding user response:

OK, my teammate gives me another answer.

# gem 'keccak', '~> 1.3'

require 'digest/keccak'

def sha3raw(str)
  Digest::Keccak.digest(str, 256)
end

def tohex(binary)
  binary.unpack('H*').first
end

def get_namehash(str)
  node = "\x0" * 32
  labels = str.split(".").reverse
  while labels.length > 0
    label = labels.shift
    labelhash = sha3raw(label)
    p 'labelhash', tohex(labelhash)
    node = sha3raw(node labelhash)
  end

  "0x"   tohex(node)
end
  •  Tags:  
  • Related