Class: WalletValidator::Btc

Inherits:
Object
  • Object
show all
Defined in:
lib/wallet_validator/btc.rb

Direct Known Subclasses

Ada, Bcd, Bchsv, Bnb, Doge, Ltc, Trx

Constant Summary collapse

ALPHA =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".freeze
CURRENCY_ATTR =
{
  "main" => {
    "filter" => "13",
    "addrv" => %w[00 05],
    "bech32" => {
      "hrp" => "bc",
      "separator" => "1",
    },
  },
  "testnet" => {
    "filter" => "2mn", # 2Mzje457jS8ejm5B2vHemUBB6zBCn2M98MG , mhWkz6E1k6BNXc7Z5vaYWXhHjN3Tdg9Uk2 , tb1qx0zejt77yudv2rhgdcm228xal5hfwduahfweft
    "addrv" => %w[c4 6f],
    "bech32" => {
      "hrp" => "tb",
      "separator" => "1"
    }
  }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(address, is_testnet) ⇒ Btc

Returns a new instance of Btc.



30
31
32
33
# File 'lib/wallet_validator/btc.rb', line 30

def initialize(address, is_testnet)
  @address = address
  @is_testnet = is_testnet
end

Instance Attribute Details

#addressObject (readonly)

Returns the value of attribute address.



28
29
30
# File 'lib/wallet_validator/btc.rb', line 28

def address
  @address
end

#is_testnetObject (readonly)

Returns the value of attribute is_testnet.



28
29
30
# File 'lib/wallet_validator/btc.rb', line 28

def is_testnet
  @is_testnet
end

Instance Method Details

#valid?Boolean

Returns:

  • (Boolean)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/wallet_validator/btc.rb', line 35

def valid?
  filter_def = attribute["bech32"]

  if filter_def
    # false時繼續往下
    return true if Crypto::Bech32.valid?(address, filter_def["hrp"], filter_def["separator"])
  end

  filter = attribute["filter"]
  addrv = attribute["addrv"]
  return false if !address.match?(/^[#{filter}][#{ALPHA}]{25,34}$/)

  # 此處不同於Base58 gem,必須獨立使用
  int_val = 0
  address.to_s.split(//).reverse.each_with_index do |char, index|
    int_val += ALPHA.index(char) * (58**index)
  end

  hex = int_val.to_s(16)
  hex = "0#{hex}" if hex.length.odd? # is_odd

  if match = address.match(/^([1]+)/)
    hex = ("00" * match[1].length) + hex
  end

  return false unless hex.length == 50
  return false unless addrv.include?(hex[0...2])

  Digest::SHA256.hexdigest(
    Digest::SHA256.digest(
      [hex[0...42]].pack("H*")
    )
  )[0...8] == hex[-8..-1]
end