Steemit Dev Portal: Document Transaction Polling Recipe

Repository

https://github.com/steemit/devportal

Site

https://developers.steem.io/

Issue

  • What was the issue(s)?
    As an application developer using the Steem blockchain, I'd like to know how (and why) I can compute a transaction id or get the transaction id some other way, so that I can use the solution described in issue #361.
  • What was the solution?
    The Steemit Dev Portal has several recipes that describe processes while being relatively agnostic about the programming language.

Once this PR is approved, the devportal site will have the following recipe:

title: Understanding Transaction Status
position: 1
description: How to use the Steem API to check the status of a transaction for a given `trx_id` value.
exclude: true
layout: full

The overarching goal is to stop using condenser_api.broadcast_transaction_synchronous but we still want the benefits.

Why Client-side Computation?

The primary reason to compute the trx_id before broadcast is to track the transaction when quality of service is impacted. If the trx_id is known before condenser_api.broadcast_transaction, but the response times out, we can still track the transaction.

Why After Broadcast?

Assuming quality of service has not been impacted, solely relying on the condenser_api.broadcast_transaction response should not be a problem.

Why In General?

Whichever method we use above to get trx_id, we can track it if anything goes wrong while we wait for it to be included in a block. Then, even after it's included, we can still track a transaction while we wait for 2/3rds of the witnesses to verify (thus irreversable). We can poll transaction_status_api until we're satisfied that the trx_id has been included.

Client-side Computation

First, create a transaction, for example:

{
   "ref_block_num":20,
   "ref_block_prefix":2890012981,
   "expiration":"2018-10-15T19:52:09",
   "operations":[
      {
         "type":"transfer_to_vesting_operation",
         "value":{
            "from":"alice",
            "to":"bob",
            "amount":{"amount":"8204", "precision":3, "nai":"@@000000021"}
         }
      }
   ],
   "extensions":[]
}

From this, we create a serialization, call it hex:

1400351942ace9efc45b010305616c69636503626f620c2000000000000003535445454d00000

Next, we convert hex to binary, call it bytes and digest bytes, with sha256, call it digest:

eba610257ad6c60d89f84ce54d3e10b52c18d4cce5547867e2450aeac80d9530

Last, we truncate digest to 20 bytes / 40 hex digits:

eba610257ad6c60d89f84ce54d3e10b52c18d4cc

This is the computed trx_id.

After Broadcast

If your client does not support client-side id computation, you can still get the trx_id from the result of condenser_api.broadcast_transaction.

The combination of condenser_api.broadcast_transaction and transaction_status_api.find_transaction, described below, allows us to avoid using condenser_api.broadcast_transaction_synchronous, which is being deprecated.

Polling

Now that we have trx_id, we can poll transaction_status_api.find_transaction, for example:

curl -s --data '{"jsonrpc":"2.0", "method":"transaction_status_api.find_transaction", "params":{"transaction_id":"eba610257ad6c60d89f84ce54d3e10b52c18d4cc"}, "id":1}' https://api.steemit.com

Which returns:

{"jsonrpc":"2.0","result":{"status":"unknown"},"id":1}

We can provide the expiration:

curl -s --data '{"jsonrpc":"2.0", "method":"transaction_status_api.find_transaction", "params":{"transaction_id":"eba610257ad6c60d89f84ce54d3e10b52c18d4cc","expiration":"2018-10-15T19:52:09"}, "id":1}' https://api.steemit.com

Which returns:

{"jsonrpc":"2.0","result":{"status":"too_old"},"id":1}

Possible status results are:

StatusMeaning
unknownExpiration time in future, transaction not included in block or mempool
within_mempoolTransaction in mempool
within_reversible_blockTransaction has been included in block, block not irreversible (result will also contain block_num)
within_irreversible_blockTransaction has been included in block, block is irreversible (result will also contain block_num)
expired_reversibleTransaction has expired, transaction is not irreversible (transaction could be in a fork)
expired_irreversibleTransaction has expired, transaction is irreversible (transaction cannot be in a fork)
too_oldTransaction is too old, I don't know about it

Notes

Complete changes are detailed here:

https://github.com/steemit/devportal/pull/396/files

GitHub Account

https://github.com/inertia186

H2
H3
H4
Upload from PC
Video gallery
3 columns
2 columns
1 column
6 Comments