How to implement this method in Ruby? or is there third party lib to do this?
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!
Solution 1:
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
}