New v2 Block Query does not have transactionHash

Hello ,

I have recently upgraded my node to leatest version which responds only to V2 query.

When i try to query a block using - v2/blocks/27966704 it provides all the transactions but i am not able to get the transactionhash in the result .

sample data

“txns”: [
{
“hgi”: true,
“sig”: “fMcS/GmOPHXAKYMUUxOxL1sMVLdKv9W9h4KmMRLd8vUFt7cbWqx2rMCjrJcPR1PLzOSI9UvBN6z0MREEFjeTAw==”,
“txn”: {
“arcv”: “HX2NYIIWEYBTSKE2EMAKIRZAQPRRL2JJOLPBCX33V2TYWGIBR626JHM6RA”,
“fee”: 1000,
“fv”: 27966701,
“lv”: 27966901,
“note”: “eyJhcHBsaWNhdGlvbklEIjoiMSIsImFwcGxpY2F0aW9uTmFtZSI6IjdPM0lWQVhYWDY0NVpES0JPSklSWFc3VUxXNEI3N0tLNEI1S0dWUklJWVIzQ1RLMlU1S1JMTFhXRlEiLCJkZXZpY2VOYW1lIjoiNEQiLCJkZXZFVUkiOiI3MGIzZDUxNzAwOWVlOGQ3IiwicnhJbmZvIjpbeyJnYXRld2F5SUQiOiI2MGM1YThmZmZlNzYxMmJkIiwidXBsaW5rSUQiOiIwYTBjNTE2MC1iY2ZkLTRmNzMtYjExNy1lOTk1NzI4NjE2NGUiLCJuYW1lIjoiT3BlbklvVF9Tb3JhX0FyZHVpbm8iLCJyc3NpIjotNzYsImxvUmFTTlIiOjcuNSwibG9jYXRpb24iOnsibGF0aXR1ZGUiOjQwLjc4NDc2LCJsb25naXR1ZGUiOjE0LjM3NjMyLCJhbHRpdHVkZSI6MTA5fX1dLCJ0eEluZm8iOnsiZnJlcXVlbmN5Ijo4Njc1MDAwMDAsImRyIjo1fSwiYWRyIjp0cnVlLCJmQ250IjoyMDI5LCJmUG9ydCI6MSwiZGF0YSI6IkFnRlZCUk1BMkJzRHRTQT0iLCJvYmplY3QiOnsiaGV4IjoiMDIwMTU1MDUxMzAwRDgxQjAzQjUyMCIsIm1lYXMiOnsiY28yIjo5NDksInJoIjoyNywidGVtcCI6MjEuNn0sIm9wY29kZSI6NSwicG9ydCI6MSwic3RvcCI6WyIyIl0sInZlcnNpb24iOjIsInZvbHRhZ2UiOjMuNDF9fQ==”,
“snd”: “7O3IVAXXX645ZDKBOJIRXW7ULW4B77KK4B5KGVRIIYR3CTK2U5KRLLXWFQ”,
“type”: “axfer”,
“xaid”: 338444324
}
},

Can any one help here

Hey @debasish,

The TXID can be calculated from the contents of the transaction and isn’t returned with the data, however using the SDKs you can calculate what the TXID is. Which language are you using?

For example in Python you can use get_txid() on a Transaction object.
It may also be required that you add the genesis ID and Hash of the network to the transaction data, but I can’t recall exactly where that’s required. Maybe in the GOSDK only.

Hope that helps?

1 Like

It’s not obvious (at all). You also have to copy in the genesis id and hash from the network you’re connected to.

Eg getting a block using the go-sdk and calculating transaction ids:

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/algorand/go-algorand-sdk/v2/client/v2/algod"
    "github.com/algorand/go-algorand-sdk/v2/crypto"
    "github.com/algorand/go-algorand-sdk/v2/types"
)

func main() {
    client, _ := algod.MakeClient("https://mainnet-api.algonode.cloud", "")
    ctx := context.Background()

    params, _ := client.SuggestedParams().Do(ctx)
    block, err := client.Block(27460672).Do(ctx)
    if err != nil {
        log.Fatalln(err)
    }
    for _, txn := range block.Payset {
        if txn.Txn.Type != types.PaymentTx {
            continue
        }
        fmt.Printf("Amount:%.6f\n", txn.Txn.Amount.ToAlgos())
        fmt.Printf("Sender:%s\n", txn.Txn.Sender.String())
        fmt.Printf("Receiver:%s\n", txn.Txn.Receiver.String())
        txn.Txn.GenesisID = params.GenesisID
        copy(txn.Txn.GenesisHash[:], params.GenesisHash[:])
        fmt.Printf("TxId:%s\n", crypto.GetTxID(txn.Txn))
        fmt.Println("---")
    }
}

Thanks for the code @PatrickB .
Actually, it’s even more subtle, you should copy the GenesisID only if the corresponding boolean in the transaction (hgi in JSON) is set to true.
In practice, almost all transactions set it to true.

Yeah, this is kind of ridiculous. All of the SDKs should provide a simple method to recreate a transaction id for a block retrieved from a node and it shouldn’t require such intimate knowledge to get it. The Transaction class itself could just provide a method to recreate it.

1 Like

I agree… To calculate tx id from the algod it is quite complicated… it should be one method in sdk something like vote-coin-indexer/computeTransactionId.ts at master · scholtz/vote-coin-indexer · GitHub

Hello All,

I am using c# , is it a doable thing using this language. Also how do i get the genesis Id.

Kind of little confused why this the transatiohash was removed.

@FrankS might be able to help with C#

Thanks for the tag @funk !

@debasish The .NET SDK does have a TxID() property for every transaction. Including those in the block.

Are you using the right SDK?

By the way, let me know if you want a Block function to update txns with their missing genesis id and hash . I could add it as a trivial helper.

@FrankS Thanks for chiming in. So what i need is i have an archival Algorand node running with latest version which supports v2 apis . I am using the v2 apis using c# to query the block and get the transactions . But with v2 i see transactionId missing . So as per the above suggestions its is like we need to calculate the same .

So if there is any .Net sdk to do the same that would be really helpful , can you please guide on the .net algo sdk if this is achieveable.

Hi @debasish . Yes @funk already linked you the latest NET SDK above. It is available as a NuGet called Algorand2

Feel free to ask me questions in the Discord channel for Algorand developers. I don’t check here very much.

The main thing is that every transaction does have a TxID() property, but for those returned in a block the genesis fields [may] be missing. Because the TxID() property is a computed field, the transactions returned as elements of a block will compute a different TxID property. So you could simply do a foreach on the Block’s SignedTransaction property and update the txns according to the guidance specified above in this thread.

I ran into this issue myself at some point and found a TODO to remind a future me to add a helper function for this :slight_smile:

Also, I am not sure what your use case is, but if you are running a full archival node purely for monitoring transactions, Algorand has a new feature out called Conduit, which offers a new type of light ‘follower’ node purely for that purpose.

@PatrickB The go code works absolutely fine . but when i point this to my node it throws error “exit with status code 1”. only line i changed in the entire process is

client, _ := algod.MakeClient(“http://:/v2”, “”)

I pointed to the node and passed the api key , do i need to do something different to point to my node.

@FrankS i also tried the .net solution but its failing with error 404, for address and token i filled the right values by removing place holders

using Algorand;
using Algorand.Algod;
using Algorand.Algod.Model;

namespace sdk_examples
{
class BasicExample
{
public static async Task Main(string args)
{
string ALGOD_API_ADDR = “”;
string ALGOD_API_TOKEN = “”;

        var httpClient = HttpClientConfigurator.ConfigureHttpClient(ALGOD_API_ADDR, ALGOD_API_TOKEN);
        DefaultApi algodApiInstance = new DefaultApi(httpClient);
        try
        {
            var supply = await algodApiInstance.GetSupplyAsync();
            Console.WriteLine("Total Algorand Supply: " + supply.TotalMoney);
            Console.WriteLine("Online Algorand Supply: " + supply.OnlineMoney);

        }
        catch (Exception e)
        {
            Console.WriteLine("Exception when calling algod#getSupply:" + e.Message);
        }
    }
}

}

Well, that doesn’t really give me enough info to work out what you might be experiencing.

A 404 is simply that your endpoint cannot be found. Try to put a trailing slash on the URL and see if it helps you. Beyond that, either
a) your sandbox is not running
b) the endpoint is behind a firewall
c) the endpoint is mistyped.

If you join the Algorand Discord server I can help you in the NET SDK channel. Post more complete code there.