import * as env from "./env"; import { U128 } from "./bignum"; import { VarUint32, calcPackedVarUint32Length } from "./varint"; import { TimePointSec } from "./time"; import { currentTimeSec } from "./system"; import { Action } from "./action"; import { Packer, Encoder, Decoder } from "./serializer"; import { Name } from "./name" export function sendDeferred(sender_id: U128, payer: Name, serialized_transaction: u8[], replace_existing: bool): void { let arr = new Array(2); arr[0] = sender_id.lo; arr[1] = sender_id.hi; env.send_deferred(arr.dataStart, payer.N, serialized_transaction.dataStart, serialized_transaction.length, replace_existing) } export function cancelDeferred(sender_id: U128): i32 { let arr = new Array(2); arr[0] = sender_id.lo; arr[1] = sender_id.hi; return env.cancel_deferred(arr.dataStart); } export function readTransaction(buffer: u8[]): usize { return env.read_transaction(buffer.dataStart, buffer.length); } export function transactionSize(): usize { return env.transaction_size(); } export function taposBlockNum(): u32 { return env.tapos_block_num(); } export function taposBlockPrefix(): u32 { return env.tapos_block_prefix(); } export function transactionExpiration(): u32 { return env.expiration(); } export function getAction(type: u32, index: u32): Action { let size = env.get_action(type, index, 0, 0); let buff = new Array(size); env.get_action(type, index, buff.dataStart, buff.length); const action = new Action() action.unpack(buff) return action; } export function getContextFreeData(index: u32): u8[] { let size = env.get_context_free_data(index, 0, 0); let buff = new Array(size); env.get_context_free_data(index, buff.dataStart, buff.length); return buff; } export class TransactionExtension implements Packer { type: u16; data!: u8[]; pack(enc: Encoder): usize { let oldPos = enc.getPos(); enc.packNumber(this.type); enc.packNumberArray(this.data) return enc.getPos() - oldPos; } unpack(data: u8[]): usize { let dec = new Decoder(data); this.type = dec.unpackNumber(); this.data = dec.unpackNumberArray(); return dec.getPos(); } getSize(): usize { let size: usize = 0; size += sizeof(); size += calcPackedVarUint32Length(this.data.length); size += sizeof()*this.data.length; return size; } } export class Transaction implements Packer { expiration: TimePointSec; refBlockNum: u16; refBlockPrefix: u32; //[VLQ or Base-128 encoding](https://en.wikipedia.org/wiki/Variable-length_quantity) //unsigned_int vaint (eosio.cdt/libraries/eosiolib/core/eosio/varint.hpp) maxNetUsageWords: VarUint32; /// number of 8 byte words this transaction can serialize into after compressions maxCpuUsageMs: u8; /// number of CPU usage units to bill transaction for delaySec: VarUint32; /// number of seconds to delay transaction, default: 0 contextFreeActions: Action[]; actions: Action[]; extention: TransactionExtension[]; constructor(delaySec: u32 = 0) { this.expiration = new TimePointSec(currentTimeSec() + 60*60); this.refBlockNum = taposBlockNum(); this.refBlockPrefix = taposBlockPrefix(); this.maxNetUsageWords = new VarUint32(0); this.maxCpuUsageMs = 0; this.delaySec = new VarUint32(delaySec); this.actions = new Array(); this.contextFreeActions = new Array(); this.extention = new Array(); } addAction(action: Action): void { this.actions.push(action); } addContextFreeActions(action: Action): void { this.contextFreeActions.push(action); } addTransactionExtension(ext: TransactionExtension): void { this.extention.push(ext); } send(senderId: U128, replaceExisting: bool, payer: Name): void { sendDeferred(senderId, payer, Encoder.pack(this), replaceExisting); } pack(enc: Encoder): usize { let oldPos = enc.getPos(); enc.pack(this.expiration); enc.packNumber(this.refBlockNum); enc.packNumber(this.refBlockPrefix); enc.pack(this.maxNetUsageWords); enc.packNumber(this.maxCpuUsageMs); enc.pack(this.delaySec); enc.packObjectArray(this.contextFreeActions); enc.packObjectArray(this.actions); enc.packObjectArray(this.extention); return enc.getPos() - oldPos; } unpack(data: u8[]): usize { let dec = new Decoder(data); this.expiration = new TimePointSec(); dec.unpack(this.expiration); this.refBlockNum = dec.unpackNumber(); this.refBlockPrefix = dec.unpackNumber(); this.maxNetUsageWords = new VarUint32(); dec.unpack(this.maxNetUsageWords); this.maxCpuUsageMs = dec.unpackNumber(); this.delaySec = new VarUint32(); dec.unpack(this.delaySec); { let length = dec.unpackLength(); this.contextFreeActions = new Array(length) for (let i=0; idec.unpackLength(); this.actions = new Array(length) for (let i=0; idec.unpackLength(); this.extention = new Array(length) for (let i=0; i(); size += sizeof(); size += this.maxNetUsageWords.getSize(); size += sizeof(); size += this.delaySec.getSize(); size += calcPackedVarUint32Length(this.contextFreeActions.length); for (let i=0; i