class Zilliqa::Account::Transaction

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).

Constants

ATTRIBUTES
GET_TX_ATTEMPTS
MAX_BIGINT_BYTES
TX_STATUSES

Attributes

provider[RW]
status[RW]

Public Class Methods

confirm(tx_params, provider) click to toggle source

constructs an already-confirmed transaction.

# File lib/zilliqa/account/transaction.rb, line 47
def self.confirm(tx_params, provider)
  Transaction.new(tx_params, provider, TX_STATUSES[:confirmed])
end
new(tx_params, provider, status = TX_STATUSES[:initialized], to_ds = false) click to toggle source
# File lib/zilliqa/account/transaction.rb, line 33
def initialize(tx_params, provider, status = TX_STATUSES[:initialized], to_ds = false)
  unless tx_params.nil?
    tx_params.each do |key, value|
      next unless ATTRIBUTES.include?(key)
      instance_variable_set("@#{key}", value)
    end
  end

  @provider = provider
  @status = status
  @to_ds = to_ds
end
reject(tx_params, provider) click to toggle source

constructs an already-rejected transaction.

# File lib/zilliqa/account/transaction.rb, line 52
def self.reject(tx_params, provider)
  Transaction.new(tx_params, provider, TX_STATUSES[:rejected])
end

Public Instance Methods

bytes() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 56
def bytes
  protocol = Zilliqa::Proto::ProtoTransactionCoreInfo.new
  protocol.version = version.to_i
  protocol.nonce = nonce.to_i
  protocol.toaddr = Util.decode_hex(Util::Bech32.to_checksum_address(to_addr).downcase.sub('0x', ''))
  protocol.senderpubkey = Zilliqa::Proto::ByteArray.new(data: Util.decode_hex(sender_pub_key))

  raise StandardLengthError if amount.to_i > MAX_BIGINT_BYTES

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

  Zilliqa::Proto::ProtoTransactionCoreInfo.encode(protocol)
end
confirm(tx_hash, max_attempts = GET_TX_ATTEMPTS, interval = 1) click to toggle source

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.

# File lib/zilliqa/account/transaction.rb, line 113
def confirm(tx_hash, max_attempts = GET_TX_ATTEMPTS, interval = 1)
  @status = TX_STATUSES[:pending]
  1.upto(max_attempts) do
    return self if track_tx(tx_hash)

    sleep(interval)
  end

  self.status = TX_STATUSES[:rejected]
  throw 'The transaction is still not confirmed after ${maxAttempts} attempts.'
end
confirmed?() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 97
def confirmed?
  @status == TX_STATUSES[:confirmed]
end
initialised?() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 93
def initialised?
  @status == TX_STATUSES[:initialized]
end
pending?() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 89
def pending?
  @status == TX_STATUSES[:pending]
end
rejected?() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 101
def rejected?
  @status == TX_STATUSES[:rejected]
end
submit!() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 143
def submit!
  provider.CreateTransaction(to_payload)
rescue TransactionError => e
  { error: e }
end
to_payload() click to toggle source
# File lib/zilliqa/account/transaction.rb, line 74
def to_payload
  {
    version: version.to_i,
    nonce: nonce.to_i,
    toAddr: Util::Bech32.to_checksum_address(to_addr),
    amount: amount.to_s,
    pubKey: sender_pub_key,
    gasPrice: gas_price.to_s,
    gasLimit: gas_limit.to_i,
    code: code,
    data: data,
    signature: signature
  }
end
track_tx(tx_hash) click to toggle source
# File lib/zilliqa/account/transaction.rb, line 125
def track_tx(tx_hash)
  begin
    response = @provider.GetTransaction(tx_hash)
  rescue TrackTxError
  end

  if response['error']
    return false
  end

  self.id = response['result']['ID']
  self.receipt = response['result']['receipt']
  receipt['cumulative_gas'] = response['result']['receipt']['cumulative_gas'].to_i
  self.status = receipt && receipt['success'] ? TX_STATUSES[:confirmed] : TX_STATUSES[:rejected]

  true
end

Private Instance Methods

bigint_to_bytes(value) click to toggle source
# File lib/zilliqa/account/transaction.rb, line 151
def bigint_to_bytes(value)
  raise StandardLengthError if value > MAX_BIGINT_BYTES

  bs = [value / (2**64), value % (2**64)].pack('Q>*')
end