class Platon::Tx

Attributes

signature[W]

Public Class Methods

decode(data) click to toggle source
# File lib/platon/tx.rb, line 21
def self.decode(data)
  data = Utils.hex_to_bin(data) if data.match(/\A(?:0x)?\h+\Z/)
  txh = deserialize(RLP.decode data).to_h

  txh[:chain_id] = Platon.chain_id_from_signature(txh)

  self.new txh
end
new(params) click to toggle source
# File lib/platon/tx.rb, line 30
def initialize(params)
  fields = {v: 0, r: 0, s: 0}.merge params
  fields[:to] = Utils.normalize_address(fields[:to])

  self.chain_id = (params[:chain_id]) ? params.delete(:chain_id) : nil

  if params[:data]
    self.data = params.delete(:data)
    fields[:data_bin] = data_bin
  end
  serializable_initialize fields

  check_transaction_validity
end

Public Instance Methods

chain_id() click to toggle source
# File lib/platon/tx.rb, line 130
def chain_id
  @chain_id
end
chain_id=(cid) click to toggle source
# File lib/platon/tx.rb, line 134
def chain_id=(cid)
  if cid != @chain_id
    self.v = 0
    self.r = 0
    self.s = 0

    clear_signature
  end

  @chain_id = (cid == 0) ? nil : cid
end
data() click to toggle source
# File lib/platon/tx.rb, line 118
def data
  true ? data_hex : data_bin
  # Platon.tx_data_hex? ? data_hex : data_bin

end
data=(string) click to toggle source
# File lib/platon/tx.rb, line 124
def data=(string)
  true ? self.data_hex=(string) : self.data_bin=(string)
  # Platon.tx_data_hex? ? self.data_hex=(string) : self.data_bin=(string)

end
data_hex() click to toggle source
# File lib/platon/tx.rb, line 110
def data_hex
  Utils.bin_to_prefixed_hex data_bin
end
data_hex=(hex) click to toggle source
# File lib/platon/tx.rb, line 114
def data_hex=(hex)
  self.data_bin = Utils.hex_to_bin(hex)
end
ecdsa_signature() click to toggle source
# File lib/platon/tx.rb, line 92
def ecdsa_signature
  return @ecdsa_signature if @ecdsa_signature

  if [v, r, s].all? && (v > 0)
    s_v = (self.chain_id) ? (v - (self.chain_id * 2) - 8) : v
    @ecdsa_signature = [
      Utils.int_to_base256(s_v),
      Utils.zpad_int(r),
      Utils.zpad_int(s),
    ].join
  end
end
encoded() click to toggle source
# File lib/platon/tx.rb, line 54
def encoded
  RLP.encode self
end
from() click to toggle source
# File lib/platon/tx.rb, line 80
def from
  if ecdsa_signature
    public_key = OpenSsl.recover_compact(signature_hash, ecdsa_signature)
    Utils.public_key_to_address(public_key) if public_key
  end
end
hash() click to toggle source
# File lib/platon/tx.rb, line 105
def hash
  "0x#{Utils.bin_to_hex Utils.keccak256_rlp(self)}"
end
Also aliased as: id
hex() click to toggle source
# File lib/platon/tx.rb, line 58
def hex
  Utils.bin_to_prefixed_hex encoded
end
id()
Alias for: hash
prevent_replays?() click to toggle source
# File lib/platon/tx.rb, line 146
def prevent_replays?
  !self.chain_id.nil?
end
sign(key) click to toggle source
# File lib/platon/tx.rb, line 62
def sign(key)
  sig = key.sign(unsigned_encoded)
  vrs = Utils.v_r_s_for sig
  self.v = self.chain_id ? ((self.chain_id * 2) + vrs[0] + 8) : vrs[0]
  self.r = vrs[1]
  self.s = vrs[2]

  clear_signature
  self
end
signature() click to toggle source
# File lib/platon/tx.rb, line 87
def signature
  return @signature if @signature
  @signature = { v: v, r: r, s: s } if [v, r, s].all? && (v > 0)
end
signing_data() click to toggle source
# File lib/platon/tx.rb, line 50
def signing_data
  Utils.bin_to_prefixed_hex unsigned_encoded
end
to_h() click to toggle source
# File lib/platon/tx.rb, line 73
def to_h
  hash_keys.inject({}) do |hash, field|
    hash[field] = send field
    hash
  end
end
unsigned_encoded() click to toggle source
# File lib/platon/tx.rb, line 45
def unsigned_encoded
  us = unsigned
  RLP.encode(us, sedes: us.sedes)
end

Protected Instance Methods

sedes() click to toggle source
# File lib/platon/tx.rb, line 190
def sedes
  if self.prevent_replays? && !(Platon.replayable_v? v)
    self.class
  else
    UnsignedTx
  end
end

Private Instance Methods

check_transaction_validity() click to toggle source
# File lib/platon/tx.rb, line 163
def check_transaction_validity
  if [gas_price, gas_limit, value, nonce].max > UINT_MAX
    raise InvalidTransaction, "Values way too high!"
  elsif gas_limit < intrinsic_gas_used
    raise InvalidTransaction, "Gas limit too low"
  end
end
clear_signature() click to toggle source
# File lib/platon/tx.rb, line 152
def clear_signature
  @signature = nil
  @ecdsa_signature = nil
end
hash_keys() click to toggle source
# File lib/platon/tx.rb, line 157
def hash_keys
  keys = self.class.serializable_fields.keys
  keys.delete(:data_bin)
  keys + [:data, :chain_id]
end
intrinsic_gas_used() click to toggle source
# File lib/platon/tx.rb, line 171
def intrinsic_gas_used
  num_zero_bytes = data_bin.count(BYTE_ZERO)
  num_non_zero_bytes = data_bin.size - num_zero_bytes

  Gas::GTXCOST +
    Gas::GTXDATAZERO * num_zero_bytes +
    Gas::GTXDATANONZERO * num_non_zero_bytes
end
signature_hash() click to toggle source
# File lib/platon/tx.rb, line 180
def signature_hash
  Utils.keccak256 unsigned_encoded
end
unsigned() click to toggle source
# File lib/platon/tx.rb, line 184
def unsigned
  Tx.new to_h.merge(v: (self.chain_id) ? self.chain_id : 0, r: 0, s: 0)
end