Create Publication

We are looking for publications that demonstrate building dApps or smart contracts!
See the full list of Gitcoin bounties that are eligible for rewards.

Tutorial Thumbnail
Beginner · 15 minutes or less

Locating a Transaction using the Archiver/Indexer with Python

This tutorial walks through using the archival and indexer modes to locate older transactions with Python. With many blockchains finding older transactions can be a painful experience. Algorand provides several modes and APIs that can ease this process and improve searching performance. This tutorial covers four different search techniques.

Requirements

Background

By default, Algorand installed nodes only store the last 1000 blocks. This means using the APIs to locate a transaction committed over 1k blocks ago will fail. If an application will need historical data older than this, the node the API is connecting to can be configured to store all blocks in the ledger. This can be configured by setting the Archival property to true in the node configuration. The node configuration details are described in Node Configuration Settings. The Archival node configuration is described in Algorand Node Types.

The node can also be configured to implement a local indexer, which speeds up block searches and offers two additional API calls. The indexer can be turned on by setting the IsIndexerActive property to true. The node configuration details are described in Node Configuration Settings. The isIndexerActive node configuration is described in Algorand Node Types.

Enabling the archival mode will require the node to re-sync the entire ledger.

Steps

1. Create an Account and Add Funds

$goal account new -d <your-data-directory> -w <your-wallet>

Save this address for later usage in the tutorial.

Use the dispenser to add funds to the account. As part of doing this operation, a transaction id will be produced on the dispenser page which will be displayed to the right of Status: Code 200 success:. Copy this transaction id for later usage in this tutorial


Learn More
- Add Funds using Dispenser

2. Recover Recent Transaction Without Achiever/Indexer

Without the achiever or indexer turned on you have a limited search range (1k blocks). You can locate the transaction using the following code. Notice we are setting the address and txid variable to the values obtained in step 1.

from algosdk import algod
import json
import datetime

try:
    my_address = "FCG5AE4EK7UDBKONUZGQRYNC2HWRASPID3T73HBHJKVM2J72I35XUU62MA"
    txid = "EGYVHWXPUZQEOR66FVWLUBUKHF4NLCGMBBS76VCCPLIJRKLFW3OA"

    # create an algod client
    algod_token = <algod-token>
    algod_address = <algod-address>
    acl = algod.AlgodClient(algod_token, algod_address)

    # Read the transction
    try:
        txn1 = acl.transaction_info(my_address, txid)
    except Exception as err:
        print(err)
    print("Transaction information tx1: {}".format(json.dumps(txn1, indent=4)))

except Exception as e:
    print(e)

This operation will only search up to the last 1000 blocks. If the transaction is older than this, the call will return an error.

3. Recover Older Transaction With Achiever

With the archiver enabled you can specify 1k round ranges to search. This can be done using code similar to the following.

from algosdk import algod
import json
import datetime

try:
    my_address = "FCG5AE4EK7UDBKONUZGQRYNC2HWRASPID3T73HBHJKVM2J72I35XUU62MA"
    txid = "EGYVHWXPUZQEOR66FVWLUBUKHF4NLCGMBBS76VCCPLIJRKLFW3OA"

    # create an algod client
    algod_token = <algod-token>
    algod_address = <algod-address>
    acl = algod.AlgodClient(algod_token, algod_address)

    # get last round
    status = acl.status()
    last_round = status.get("lastRound") 
    print(datetime.datetime.now())

    try:
        txn2 = acl.transactions_by_address(my_address, last_round - 1000, last_round)
    except Exception as err:
        print(err)
    print("Transaction List tx2: {}".format(json.dumps(txn2, indent=4))) 

except Exception as e:
    print(e)

This will return the transaction if the transaction is in the 1k block range specified as parameters.

4. Recover Older Transaction With Indexer

With the indexer turned on, two additional calls are made available to search the entire chain without having to specify a round range. Note that turning on the indexer also requires that the archiver also be turned on. The code below finds the transaction using two different methods. One method uses just the transaction id and the other uses the account and a date range.

from algosdk import algod
import json
import datetime

try:
    my_address = "FCG5AE4EK7UDBKONUZGQRYNC2HWRASPID3T73HBHJKVM2J72I35XUU62MA"
    txid = "EGYVHWXPUZQEOR66FVWLUBUKHF4NLCGMBBS76VCCPLIJRKLFW3OA"

    # create an algod client
    algod_token = <algod-token>
    algod_address = <algod-address>
    acl = algod.AlgodClient(algod_token, algod_address)

    # find transaction in date range
    try:
        txn3 = acl.transactions_by_address(my_address, None, None, None, "2020-03-08T15:00:00Z", "2020-03-09T17:00:00Z")
    except Exception as err:
        print(err)
    print("Transaction Lists tx3: {}".format(json.dumps(txn3, indent=4)))  

    # find transaction with just txid
    try:
        txn4 = acl.transaction_by_id(txid)
    except Exception as err:
        print(err)
    print("Transaction information tx4: {}".format(json.dumps(txn4, indent=4)))
except Exception as e:
    print(e)