3

Hello Dear EOSIO Community,

I have following transaction on mainnet that I want to unpack. I get its data using curl:

curl https://api.tokenika.io/v1/history/get_transaction -d'{"id": "474157059f407274020d9c498c3a02b07bce36a3229838677de8947efe153ed0"}'
[...]
"packed_trx":"4936395b23cae0baad75000000000100a6823403ea3055000000572d3ccdcd0180a92206baa920cd00000000a8ed32322b80a92206baa920cdc0d52406baa920cd102700000000000004454f53000000000a756e7061636b206d652100"
[...]
"trx":{
  "expiration":"2018-07-01T20:15:05",
  "ref_block_num":51747,
  "ref_block_prefix":1974319840,
  "max_net_usage_words":0,
  "max_cpu_usage_ms":0,
  "delay_sec":0,
  "context_free_actions":[],
  "actions":[
    {
      "account":"eosio.token",
      "name":"transfer",
      "authorization":[{
        "actor":"tokenika4eos",
        "permission":"active"
      }],
[...]

I try to unpack packed_trx using struct defined in transaction.hpp

time_point_sec         expiration;   ///< the time at which a transaction expires
uint16_t               ref_block_num       = 0U; ///< specifies a block num in the last 2^16 blocks.
uint32_t               ref_block_prefix    = 0UL; ///< specifies the lower 32 bits of the blockid at get_ref_blocknum
fc::unsigned_int       max_net_usage_words = 0UL; /// upper limit on total network bandwidth (in 8 byte words) billed for this transaction
uint8_t                max_cpu_usage_ms    = 0; /// upper limit on the total CPU time billed for this transaction
fc::unsigned_int delay_sec = 0UL;

After few source code checks, I've found that both time_point_sec and fc::unsigned_int should be uint32.

So I try to read first field of that struct, expiration. I read first 8 characters from packed_trx string (32 input bits/8 bits per byte = 4 bytes, *2 hex numbers per byte = 8 hex numbers) that's 4936395b and cast that to integer using little-endian format getting 1530476105 at the end, which is Unix timestamp date 07/01/2018 @ 8:15pm (UTC) which is cool because it matches my expiration date from transaction.

When I repeat whole process to rest of the data, I get:

expiration = 1530476105
ref_block_num = 51747
ref_block_prefix = 1974319840
max_net_usage_words = 0
max_cpu_usage_ms = 1
delay_sec = 880977408

This would be really nice, but it isn't true since this transaction is defined to have all three values max_net_usage_words, max_cpu_usage_ms, delay_sec set to 0.

Is there anything obvious that I'm doing wrong? How to correctly unpack "packed_trx" from transaction?

2 Answers 2

2

An unsigned_int is stored locally as uint32_t, but it is serialized as varuint32.

See for example: https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/varint.hpp and there's something similar in https://github.com/EOSIO/fc/blob/9a0ed1f85e38adc6ace8c944b5f5f725f4829ba2/include/fc/io/varint.hpp which is the packing lib.

0
0

Okay, way simpler,

//rpc/api stuff see here https://github.com/EOSIO/eosjs
const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });

const info = await rpc.get_table_rows({
        code: "eosio.msig",
        index_position: 1,
        json: true,
        limit: 1,
        lower_bound: proposal.proposal_name,
        reverse: false,
        scope: proposal.proposer,
        show_payer: false,
        table: "proposal"
    });
    console.log(info.rows[0])
    const resss = api.deserializeTransaction(hexToUint8Array(info.rows[0].packed_transaction));
    console.log(resss)

deserializeTransaction

{
  proposal_name: 'dappgovernorb',
  packed_transaction: 'f76d5c6000000000000000000000010000000000ea30550040cbdaa86c52d50170e9bc6a5356ab490000000080ab26a7a50370e9bc6a5356ab490000000080ab26a700000000000000000b0000000015400fe7179ebcee4100000000a8ed32320100308d4bd768a6124500000000a8ed3232010010f0a42ed25cfd450000000000003665010000e1a53cab59ab4900000000a8ed323201007055729bde5aab4900000000a8ed32320100c0d58c862977284d00000000a8ed3232010050ab49eaaa56315500000000a8ed3232010080a962b3657fd55600000000a8ed3232010040ddc554e1782973000000d3b8748d660100a0b7792a19b54d7300000000a8ed32320100900c67d365acf67400000000a8ed32320100600fbed9e37bb98100000000a8ed32320100603cbd66aae30f8500000000a8ed3232010060a099742a4caf8900000000a8ed32320100a0d08c26badbb29300000000a8ed3232010020c2342e5da3199700000000a8ed32320100a0a1ee2cbfefdfad00000000a8ed3232010080a98a06622da3c900000000a8ed323201006076b18c2d270ae900000000a8ed3232010020d81a798f6157eb00000000a8ed32320100b05d6238fd8639fc00000000a8ed3232010002803a0900040080f40300020000',
  earliest_exec_time: '2021-03-24T11:13:53.000'
}

To:

{
  expiration: '2021-03-25T11:03:19.000',
  ref_block_num: 0,
  ref_block_prefix: 0,
  max_net_usage_words: 0,
  max_cpu_usage_ms: 0,
  delay_sec: 0,
  context_free_actions: [],
  actions: [
    {
      account: 'eosio',
      name: 'updateauth',
      authorization: [Array],
      data: '70E9BC6A5356AB490000000080AB26A700000000000000000B0000000015400FE7179EBCEE4100000000A8ED32320100308D4BD768A6124500000000A8ED3232010010F0A42ED25CFD450000000000003665010000E1A53CAB59AB4900000000A8ED323201007055729BDE5AAB4900000000A8ED32320100C0D58C862977284D00000000A8ED3232010050AB49EAAA56315500000000A8ED3232010080A962B3657FD55600000000A8ED3232010040DDC554E1782973000000D3B8748D660100A0B7792A19B54D7300000000A8ED32320100900C67D365ACF67400000000A8ED32320100600FBED9E37BB98100000000A8ED32320100603CBD66AAE30F8500000000A8ED3232010060A099742A4CAF8900000000A8ED32320100A0D08C26BADBB29300000000A8ED3232010020C2342E5DA3199700000000A8ED32320100A0A1EE2CBFEFDFAD00000000A8ED3232010080A98A06622DA3C900000000A8ED323201006076B18C2D270AE900000000A8ED3232010020D81A798F6157EB00000000A8ED32320100B05D6238FD8639FC00000000A8ED3232010002803A0900040080F403000200'
    }
  ],
  transaction_extensions: []
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.