Class: Zold::Txn

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

Overview

A single transaction

Defined Under Namespace

Classes: CantParse, CantParseTime

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Make a new object of this class (you must read the White Paper in order to understand this class).

id

is the ID of the transaction, an integer

date

is the date/time of the transaction

amount

is the amount, an instance of class Amount

prefix

is the prefix from the Invoice (read the WP)

bnf

is the wallet ID of the paying or receiving wallet

details

is the details, in plain text



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/zold/txn.rb', line 68

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.utc.iso8601}" 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.inspect}" if prefix.length < 8
  raise "Prefix is too long: #{prefix.inspect}" if prefix.length > 32
  raise "Prefix is wrong: #{prefix.inspect} (#{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.inspect}" if details.length > 512
  raise "Wrong details #{details.inspect} (#{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:



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/zold/txn.rb', line 167

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

Raises:



198
199
200
201
202
203
204
205
# File 'lib/zold/txn.rb', line 198

def self.parse_time(iso)
  parts = ISO8601.match(iso)
  raise CantParseTime, "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



101
102
103
104
# File 'lib/zold/txn.rb', line 101

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



95
96
97
98
99
# File 'lib/zold/txn.rb', line 95

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



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

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



147
148
149
150
151
# File 'lib/zold/txn.rb', line 147

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

#to_jsonObject



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/zold/txn.rb', line 118

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



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

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



130
131
132
133
# File 'lib/zold/txn.rb', line 130

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