Class: CashAddr::Address
- Inherits:
-
Object
- Object
- CashAddr::Address
- Defined in:
- lib/cash_addr/address.rb
Constant Summary collapse
- VERSION_MAP =
{ 'legacy' => [ ['P2SH', 5], ['P2PKH', 0], ['P2SHTestnet', 196], ['P2PKHTestnet', 111] ], 'cash' => [ ['P2SH', 8], ['P2PKH', 0], ['P2SHTestnet', 8], ['P2PKHTestnet', 0] ] }.freeze
- DEFAULT_PREFIX =
'bitcoincash'
Instance Attribute Summary collapse
-
#digest ⇒ Object
Returns the value of attribute digest.
-
#payload ⇒ Object
Returns the value of attribute payload.
-
#prefix ⇒ Object
Returns the value of attribute prefix.
-
#version ⇒ Object
Returns the value of attribute version.
Class Method Summary collapse
- .address_type(address_type, version) ⇒ Object
- .cash_string(address_string) ⇒ Object
- .code_list_to_string(code_list) ⇒ Object
- .from_string(address_string) ⇒ Object
- .legacy_string(address_string) ⇒ Object
Instance Method Summary collapse
- #cash_address ⇒ Object
-
#initialize(version, payload, prefix = nil, digest = nil) ⇒ Address
constructor
A new instance of Address.
- #legacy_address ⇒ Object
Constructor Details
#initialize(version, payload, prefix = nil, digest = nil) ⇒ Address
Returns a new instance of Address.
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/cash_addr/address.rb', line 26 def initialize(version, payload, prefix = nil, digest = nil) @version = version @payload = payload @digest = digest @prefix = prefix ? prefix : DEFAULT_PREFIX @version = 'P2SHTestnet' if prefix == 'bchtest' && version == 'P2SH' @version = 'P2PKHTestnet' if prefix == 'bchtest' && version == 'P2PKH' @prefix = 'bchtest' if %w[P2SHTestnet P2PKHTestnet].include?(@version) end |
Instance Attribute Details
#digest ⇒ Object
Returns the value of attribute digest.
8 9 10 |
# File 'lib/cash_addr/address.rb', line 8 def digest @digest end |
#payload ⇒ Object
Returns the value of attribute payload.
8 9 10 |
# File 'lib/cash_addr/address.rb', line 8 def payload @payload end |
#prefix ⇒ Object
Returns the value of attribute prefix.
8 9 10 |
# File 'lib/cash_addr/address.rb', line 8 def prefix @prefix end |
#version ⇒ Object
Returns the value of attribute version.
8 9 10 |
# File 'lib/cash_addr/address.rb', line 8 def version @version end |
Class Method Details
.address_type(address_type, version) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/cash_addr/address.rb', line 57 def self.address_type(address_type, version) VERSION_MAP[address_type].each do |mapping| return mapping if mapping.include?(version) end raise(CashAddr::InvalidAddress.new, 'Could not determine address version') end |
.cash_string(address_string) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/cash_addr/address.rb', line 85 def self.cash_string(address_string) if address_string.upcase != address_string && address_string.downcase != address_string raise(CashAddr::InvalidAddress.new, 'Cash address contains uppercase and lowercase characters') end address_string = address_string.downcase if !address_string.include?(':') address_string = DEFAULT_PREFIX + ':' + address_string end pre, base32string = address_string.split(':') decoded = CashAddr::Crypto.b32decode(base32string) if !CashAddr::Crypto.verify_checksum(pre, decoded) raise(CashAddr::InvalidAddress.new, 'Bad cash address checksum') end converted = CashAddr::Crypto.convertbits(decoded, 5, 8) ver = CashAddr::Address.address_type('cash', converted[0].to_i)[0] p = converted[1..-7] new(ver, p, pre, nil) end |
.code_list_to_string(code_list) ⇒ Object
53 54 55 |
# File 'lib/cash_addr/address.rb', line 53 def self.code_list_to_string(code_list) code_list.map { |i| Array(i).pack('C*') }.flatten.join end |
.from_string(address_string) ⇒ Object
65 66 67 68 69 |
# File 'lib/cash_addr/address.rb', line 65 def self.from_string(address_string) raise(CashAddr::InvalidAddress, 'Expected string as input') unless address_string.is_a?(String) return legacy_string(address_string) unless address_string.include?(':') cash_string(address_string) end |
.legacy_string(address_string) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/cash_addr/address.rb', line 71 def self.legacy_string(address_string) decoded = nil begin decoded = Base58.base58_to_binary(address_string, :bitcoin).bytes rescue StandardError raise(CashAddr::InvalidAddress.new, 'Could not decode legacy address') end ver = address_type('legacy', decoded[0].to_i)[0] payload = decoded[1..-5] digest = decoded[-4..-1] new(ver, payload, nil, digest) end |
Instance Method Details
#cash_address ⇒ Object
45 46 47 48 49 50 51 |
# File 'lib/cash_addr/address.rb', line 45 def cash_address version_int = self.class.address_type('cash', version)[1] p = [version_int] + payload p = CashAddr::Crypto.convertbits(p, 8, 5) checksum = CashAddr::Crypto.calculate_checksum(prefix, p) prefix + ':' + CashAddr::Crypto.b32encode(p + checksum) end |
#legacy_address ⇒ Object
38 39 40 41 42 43 |
# File 'lib/cash_addr/address.rb', line 38 def legacy_address version_int = self.class.address_type('legacy', version)[1] input = self.class.code_list_to_string([version_int] + payload + Array(digest)) input += Digest::SHA256.digest(Digest::SHA256.digest(input))[0..3] unless digest Base58.binary_to_base58(input, :bitcoin) end |