Class: Laksa::Account::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/laksa/account/transaction.rb

Overview

Transaction

Transaction is a functor. Its purpose is to encode the possible states a Transaction can be in: Confirmed, Rejected, Pending, or Initialised (i.e., not broadcasted).

Constant Summary collapse

GET_TX_ATTEMPTS =
33

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tx_params, provider, status = TxStatus::INITIALIZED, to_ds = false) ⇒ Transaction

Returns a new instance of Transaction.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/laksa/account/transaction.rb', line 14

def initialize(tx_params, provider, status = TxStatus::INITIALIZED, to_ds = false)
  if tx_params
    @version = tx_params.version;
    @nonce = tx_params.nonce
    @amount = tx_params.amount
    @gas_price = tx_params.gas_price
    @gas_limit = tx_params.gas_limit
    @signature = tx_params.signature
    @receipt = tx_params.receipt
    @sender_pub_key = tx_params.sender_pub_key
    @to_addr = tx_params.to_addr.downcase
    @code = tx_params.code
    @data = tx_params.data
  end

  @provider = provider
  @status = status
  @to_ds = to_ds
end

Instance Attribute Details

#amountObject

Returns the value of attribute amount.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def amount
  @amount
end

#codeObject

Returns the value of attribute code.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def code
  @code
end

#dataObject

Returns the value of attribute data.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def data
  @data
end

#gas_limitObject

Returns the value of attribute gas_limit.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def gas_limit
  @gas_limit
end

#gas_priceObject

Returns the value of attribute gas_price.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def gas_price
  @gas_price
end

#idObject

Returns the value of attribute id.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def id
  @id
end

#nonceObject

Returns the value of attribute nonce.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def nonce
  @nonce
end

#providerObject

Returns the value of attribute provider.



10
11
12
# File 'lib/laksa/account/transaction.rb', line 10

def provider
  @provider
end

#receiptObject

Returns the value of attribute receipt.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def receipt
  @receipt
end

#sender_pub_keyObject

Returns the value of attribute sender_pub_key.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def sender_pub_key
  @sender_pub_key
end

#signatureObject

Returns the value of attribute signature.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def signature
  @signature
end

#statusObject

Returns the value of attribute status.



10
11
12
# File 'lib/laksa/account/transaction.rb', line 10

def status
  @status
end

#to_addrObject

Returns the value of attribute to_addr.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def to_addr
  @to_addr
end

#to_dsObject

Returns the value of attribute to_ds.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def to_ds
  @to_ds
end

#versionObject

Returns the value of attribute version.



9
10
11
# File 'lib/laksa/account/transaction.rb', line 9

def version
  @version
end

Class Method Details

.confirm(tx_params, provider) ⇒ Object

constructs an already-confirmed transaction.



35
36
37
# File 'lib/laksa/account/transaction.rb', line 35

def self.confirm(tx_params, provider)
  Transaction.new(tx_params, provider, TxStatus::CONFIRMED)
end

.reject(tx_params, provider) ⇒ Object

constructs an already-rejected transaction.



40
41
42
# File 'lib/laksa/account/transaction.rb', line 40

def self.reject(tx_params, provider) 
  Transaction.new(tx_params, provider, TxStatus::REJECTED)
end

Instance Method Details

#bytesObject



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/laksa/account/transaction.rb', line 44

def bytes
  protocol = Laksa::Proto::ProtoTransactionCoreInfo.new
  protocol.version = self.version
  protocol.nonce = self.nonce
  protocol.toaddr =  Util.decode_hex(self.to_addr.downcase.sub('0x',''))
  protocol.senderpubkey = Laksa::Proto::ByteArray.new(data: Util.decode_hex(self.sender_pub_key))

  raise 'standard length exceeded for value' if self.amount.to_i > 2 ** 128 - 1

  protocol.amount = Laksa::Proto::ByteArray.new(data: bigint_to_bytes(self.amount.to_i))
  protocol.gasprice = Laksa::Proto::ByteArray.new(data: bigint_to_bytes(self.gas_price.to_i))
  protocol.gaslimit = self.gas_limit
  protocol.code = self.code if self.code
  protocol.data = self.data if self.data

  Laksa::Proto::ProtoTransactionCoreInfo.encode(protocol)
end

#confirm(tx_hash, max_attempts = GET_TX_ATTEMPTS, interval = 1) ⇒ Object

This sets the Transaction instance to a state of pending. Calling this function kicks off a passive loop that polls the lookup node for confirmation on the txHash.

The polls are performed with a linear backoff:

This is a low-level method that you should generally not have to use directly.



120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/laksa/account/transaction.rb', line 120

def confirm(tx_hash, max_attempts = GET_TX_ATTEMPTS, interval = 1)
  @status = TxStatus::PENDING
  1.upto(max_attempts) do 
    if self.track_tx(tx_hash)
      return self
    else
      sleep(interval)
    end
  end

  self.status = TxStatus::REJECTED
  throw 'The transaction is still not confirmed after ${maxAttempts} attempts.'
end

#confirmed?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/laksa/account/transaction.rb', line 104

def confirmed?
  @status === TxStatus::CONFIRMED;
end

#initialised?Boolean

Returns:

  • (Boolean)


100
101
102
# File 'lib/laksa/account/transaction.rb', line 100

def initialised?
  @status === TxStatus::INITIALIZED
end

#pending?Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/laksa/account/transaction.rb', line 96

def pending?
  @status == TxStatus::PENDING
end

#rejected?Boolean

Returns:

  • (Boolean)


108
109
110
# File 'lib/laksa/account/transaction.rb', line 108

def rejected?
  @status === TxStatus::REJECTED;
end

#to_payloadObject



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/laksa/account/transaction.rb', line 81

def to_payload
  {
    version: self.version.to_i,
    nonce: self.nonce.to_i,
    toAddr: Wallet.to_checksum_address(self.to_addr),
    amount: self.amount,
    pubKey: self.sender_pub_key,
    gasPrice: self.gas_price,
    gasLimit: self.gas_limit,
    code: self.code,
    data: self.data,
    signature: self.signature
  }
end

#track_tx(tx_hash) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/laksa/account/transaction.rb', line 134

def track_tx(tx_hash) 
  puts "tracking transaction: #{tx_hash}"

  begin
    response = @provider.GetTransaction(tx_hash)
  rescue Exception => e
    puts "transaction not confirmed yet"
    puts e
  end

  if response['error']
    puts "transaction not confirmed yet"
    return false;
  end

  self.id = response['result']['ID']
  self.receipt = response['result']['receipt']
  self.receipt['cumulative_gas'] = response['result']['receipt']['cumulative_gas'].to_i

  if self.receipt && self.receipt['success']
    puts "Transaction confirmed!"
    self.status = TxStatus::CONFIRMED
  else
    puts "Transaction rejected!"
    self.status = TxStatus::REJECTED
  end

  true
end

#tx_paramsObject



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/laksa/account/transaction.rb', line 62

def tx_params
  tx_params = TxParams.new

  tx_params.id = self.id
  tx_params.version = self.version
  tx_params.nonce = self.nonce
  tx_params.amount = self.amount
  tx_params.gas_price = self.gas_price
  tx_params.gas_limit = self.gas_limit
  tx_params.signature = self.signature
  tx_params.receipt = self.receipt
  tx_params.sender_pub_key = self.sender_pub_key
  tx_params.to_addr = Wallet.to_checksum_address(self.to_addr)
  tx_params.code = self.code
  tx_params.data = self.data

  tx_params
end