Class: Zold::Txn

Inherits:
Object
  • Object
show all
Defined in:
lib/zold/txn.rb

Overview

A single transaction

Defined Under Namespace

Classes: CantParse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, date, amount, prefix, bnf, details) ⇒ Txn

Returns a new instance of Txn.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/zold/txn.rb', line 58

def initialize(id, date, amount, prefix, bnf, details)
  raise 'The ID can\'t be NIL' if id.nil?
  raise "ID of transaction can't be negative: #{id}" if id < 1
  @id = id
  raise 'The time can\'t be NIL' if date.nil?
  raise 'Time have to be of type Time' unless date.is_a?(Time)
  raise "Time can't be in the future: #{date}" if date > Time.now
  @date = date
  raise 'The amount can\'t be NIL' if amount.nil?
  raise 'The amount has to be of type Amount' unless amount.is_a?(Amount)
  raise 'The amount can\'t be zero' if amount.zero?
  @amount = amount
  raise 'The bnf can\'t be NIL' if bnf.nil?
  raise 'The bnf has to be of type Id' unless bnf.is_a?(Id)
  @bnf = bnf
  raise 'Prefix can\'t be NIL' if prefix.nil?
  raise "Prefix is too short: \"#{prefix}\"" if prefix.length < 8
  raise "Prefix is too long: \"#{prefix}\"" if prefix.length > 32
  raise "Prefix is wrong: \"#{prefix}\" (#{RE_PREFIX})" unless REGEX_PREFIX.match?(prefix)
  @prefix = prefix
  raise 'Details can\'t be NIL' if details.nil?
  raise 'Details can\'t be empty' if details.empty?
  raise "Details are too long: \"#{details}\"" if details.length > 512
  raise "Wrong details \"#{details}\" (#{RE_DETAILS})" unless REGEX_DETAILS.match?(details)
  @details = details
end

Instance Attribute Details

#amountObject

Returns the value of attribute amount.



56
57
58
# File 'lib/zold/txn.rb', line 56

def amount
  @amount
end

#bnfObject

Returns the value of attribute bnf.



56
57
58
# File 'lib/zold/txn.rb', line 56

def bnf
  @bnf
end

#dateObject (readonly)

Returns the value of attribute date.



56
57
58
# File 'lib/zold/txn.rb', line 56

def date
  @date
end

#detailsObject (readonly)

Returns the value of attribute details.



56
57
58
# File 'lib/zold/txn.rb', line 56

def details
  @details
end

#idObject (readonly)

Returns the value of attribute id.



56
57
58
# File 'lib/zold/txn.rb', line 56

def id
  @id
end

#prefixObject (readonly)

Returns the value of attribute prefix.



56
57
58
# File 'lib/zold/txn.rb', line 56

def prefix
  @prefix
end

#signObject

Returns the value of attribute sign.



56
57
58
# File 'lib/zold/txn.rb', line 56

def sign
  @sign
end

Class Method Details

.parse(line, idx = 0) ⇒ Object

Raises:



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/zold/txn.rb', line 157

def self.parse(line, idx = 0)
  clean = line.strip
  parts = PTN.match(clean)
  raise CantParse, "Invalid line ##{idx}: #{line.inspect} (doesn't match #{PTN})" unless parts
  txn = Txn.new(
    Hexnum.parse(parts[:id]).to_i,
    parse_time(parts[:date]),
    Amount.new(zents: Hexnum.parse(parts[:amount]).to_i),
    parts[:prefix],
    Id.new(parts[:bnf]),
    parts[:details]
  )
  txn.sign = parts[:sign]
  txn
end

.parse_time(iso) ⇒ Object



185
186
187
188
189
190
191
192
# File 'lib/zold/txn.rb', line 185

def self.parse_time(iso)
  parts = ISO8601.match(iso)
  raise "Invalid ISO 8601 date \"#{iso}\"" if parts.nil?
  Time.gm(
    parts[:year].to_i, parts[:month].to_i, parts[:day].to_i,
    parts[:hours].to_i, parts[:minutes].to_i, parts[:seconds].to_i
  )
end

Instance Method Details

#<=>(other) ⇒ Object



91
92
93
94
# File 'lib/zold/txn.rb', line 91

def <=>(other)
  raise 'Can only compare with Txn' unless other.is_a?(Txn)
  [date, amount * -1, id, bnf] <=> [other.date, other.amount * -1, other.id, other.bnf]
end

#==(other) ⇒ Object



85
86
87
88
89
# File 'lib/zold/txn.rb', line 85

def ==(other)
  id == other.id && date == other.date && amount == other.amount &&
    prefix == other.prefix && bnf == other.bnf &&
    details == other.details && sign == other.sign
end

#inverse(bnf) ⇒ Object



125
126
127
128
129
130
131
132
# File 'lib/zold/txn.rb', line 125

def inverse(bnf)
  raise 'You can\'t reverse a positive transaction' unless amount.negative?
  t = clone
  t.amount = amount * -1
  t.bnf = bnf
  t.sign = ''
  t
end

#signed(pvt, id) ⇒ Object

Sign the transaction and add RSA signature to it

pvt

The private RSA key of the paying wallet

id

Paying wallet ID



137
138
139
140
141
# File 'lib/zold/txn.rb', line 137

def signed(pvt, id)
  t = clone
  t.sign = Signature.new.sign(pvt, id, self)
  t
end

#to_jsonObject



108
109
110
111
112
113
114
115
116
117
118
# File 'lib/zold/txn.rb', line 108

def to_json
  {
    id: @id,
    date: @date.utc.iso8601,
    amount: @amount.to_i,
    prefix: @prefix,
    bnf: @bnf.to_s,
    details: @details,
    sign: @sign
  }
end

#to_sObject



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/zold/txn.rb', line 96

def to_s
  [
    Hexnum.new(@id, 4).to_s,
    @date.utc.iso8601,
    Hexnum.new(@amount.to_i, 16),
    @prefix,
    @bnf,
    @details,
    @sign
  ].join(';')
end

#to_textObject



120
121
122
123
# File 'lib/zold/txn.rb', line 120

def to_text
  start = @amount.negative? ? "##{@id}" : '-'
  "#{start} #{@date.utc.iso8601} #{@amount} #{@bnf} #{@details}"
end