0

我有这个 ts 功能:

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;
}

调用此方法时,它会给出如下结果:

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

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

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

如何在 Ruby 中实现这个方法?

请不要急于为这个问题投票,我花了几个小时来做​​这个,得到了这个:

# 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

上面的 ruby​​ 代码给了我这个错误:

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

因为Digest::Keccak256.new.hexdigest只接受 String ,而不是 Array。

有任何想法吗?

多谢!

4

2 回答 2

1

在这里,您将返回array而不是string随后将其传递给Digest::Keccak256.new.hexdigest
Change this:

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

return result

对此:

return result.join

同样可以通过以下方式实现:

result = []
"abcd".split("").each_with_index {|letter, idx|
  if idx % 2 == 1
    result << letter.hex
  end
}
于 2022-01-11T12:28:38.370 回答
0

好的,我的队友给了我另一个答案。

# 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
于 2022-01-12T01:28:11.087 回答