class Eth::Tx
def self.decode(data)
def self.decode(data) data = Utils.hex_to_bin(data) if data.match(/\A(?:0x)?\h+\Z/) deserialize(RLP.decode data) end
def check_transaction_validity
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
def data
def data Eth.tx_data_hex? ? data_hex : data_bin end
def data=(string)
def data=(string) Eth.tx_data_hex? ? self.data_hex=(string) : self.data_bin=(string) end
def data_hex
def data_hex Utils.bin_to_prefixed_hex data_bin end
def data_hex=(hex)
def data_hex=(hex) self.data_bin = Utils.hex_to_bin(hex) end
def encoded
def encoded RLP.encode self end
def from
def from if signature public_key = OpenSsl.recover_compact(signature_hash, signature) Utils.public_key_to_address(public_key) if public_key end end
def hash
def hash "0x#{Utils.bin_to_hex Utils.keccak256_rlp(self)}" end
def hash_keys
def hash_keys keys = self.class.serializable_fields.keys keys.delete(:data_bin) keys + [:data] end
def hex
def hex Utils.bin_to_prefixed_hex encoded end
def initialize(params)
def initialize(params) fields = {v: 0, r: 0, s: 0}.merge params fields[:to] = Utils.normalize_address(fields[:to]) if params[:data] self.data = params.delete(:data) fields[:data_bin] = data_bin end serializable_initialize fields check_transaction_validity end
def intrinsic_gas_used
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
def sedes
def sedes if Eth.prevent_replays? && !(Eth.replayable_v? v) self.class else UnsignedTx end end
def sign(key)
def sign(key) self.signature = key.sign(unsigned_encoded) vrs = Utils.v_r_s_for signature self.v = vrs[0] self.r = vrs[1] self.s = vrs[2] self end
def signature
def signature return @signature if @signature self.signature = [ Utils.int_to_base256(v), Utils.zpad_int(r), Utils.zpad_int(s), ].join if [v, r, s].all? end
def signature_hash
def signature_hash Utils.keccak256 unsigned_encoded end
def signing_data
def signing_data Utils.bin_to_prefixed_hex unsigned_encoded end
def to_h
def to_h hash_keys.inject({}) do |hash, field| hash[field] = send field hash end end
def unsigned
def unsigned Tx.new to_h.merge(v: Eth.chain_id, r: 0, s: 0) end
def unsigned_encoded
def unsigned_encoded RLP.encode(unsigned, sedes: sedes) end