Genesis Hash Error while using Testnet API

I’m getting a strange (to me) error regarding the genesis hash value when I try to use the Testnet API from the shell.

I am including the code and output, but sadly I am having to edit it because the system says I can’t post so many links (and urls are contained in the code).

I’m trying to do a send transaction. So, first I obtain the parameter data with this command:

curl -s [URI]://node.testnet.algoexplorerapi.io/v2/transactions/params

The output from the server is in the expected JSON format:

{“consensus-version”:"[URI]://github.com/algorandfoundation/specs/tree/d5ac876d7ede07367dbaa26e149aa42589aac1f7",“fee”:0,“genesis-hash”:“SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=”,“genesis-id”:“testnet-v1.0”,“last-round”:21678678,“min-fee”:1000}

My script parses this and gets the genesis hash and places it in my JSON transaction file:

{“txn”:{“amt”:3000000,“fee”:1000,“fv”:21678678,“gen”:“testnet-v1.0”,“gh”:“SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=”,“lv”:21679353,“note”:“Yipee!”,“rcv”:“NFNI7TEHPW22NDCAL2VRMM6XVUOPOTFDIPO6NPNDL5GFBTWR2VRRRF7QEY”,“snd”:“WJSSO4HPYJJR3XEMSA7FZHU7OVZQXO5RMV6OUH2GQIQEUIXQBHMRPIBPJ4”,“type”:“pay”}}

You can see that it is taking the exact base 64 hash value of the genesis hash and placing it into the transaction. The transaction is then converted to the msgpack format and signed with algokey, no problem there.

I then send the signed transaction in the format indicated by Algorand Explorer on its API page for testnet:

curl -X POST ‘https://node.testnet.algoexplorerapi.io/v2/transactions’ -H ‘accept: application/json’ -H ‘Content-Type: application/x-binary’ --data-binary ‘@/path/to/transaction.stxn’

Here’s the error message:

{“message”:“TransactionPool.Remember: tx.GenesisHash \u003cKNDU6MKHJNJXU6KFG5EUKUCJORKHQQ2CPF3TS6BYIZWW44SDIRSQ\u003e does not match expected \u003cJBR3KGFEWPEE5SAQ6IWU6EEBZMHXD4CZU6WCBXWGF57XBZIJHIRA\u003e”}

What is confusing about this in particular is that it seems that the base 64 hash is being converted to base 32 and then this prefix and suffix of \u003 is being added. In any case, the specs we are given on Algorand.org tell us to include the hash as it is published, in base 64, in our transaction file. It seems I am doing that correctly here.

Can a developer or someone else in the know tell me what’s happening here? Your help is much appreciated!

EDIT: I am wondering if something is wrong with the genesis-id value I’m getting back from the API. It says it is “testnet-v.10” but the API address has “v2” in it. Perhaps the API is sending back the wrong genesis-id value?

After more experimentation, including trying to submit the same signed transaction using Purestake and getting a different error, and also trying to use different messagepack conversion software, I’m convinced that the problem is that the messagepack conversions are not being accepted by the Algorand nodes. It appears that, sadly, there’s no way to do this using a shell script – at least no way to create the raw transaction. I’ll have to use one of the SDKs.

Using the SDK is highly recommended indeed.

That being said, I believe the issue may be that you are not encoding the addresses correctly. Addresses should be encoded as arrays of 32 bytes without checksum, while you seem to be using the “displayed” version of the address encoded in base32 with checksum.
See Overview - Algorand Developer Portal
The genesis hash needs to be a 32-byte array, and not a base64 string.
The note needs to be a byte array and not a string.

Also Algorand is not using pure msgpack but is using a canonical version of msgpack where zero fields are omitted and fields are sorted alphabetically by their key.
So you may not be able to use any msgpack tooling. Instead, you need to use msgpacktool.

See also Encoding and Decoding - Algorand Developer Portal

Thanks, Fabrice. It seems that the msgpack conversion software I was using wasn’t working for the reasons you mentioned. I don’t know about “msgpacktool” – is that part of goal? I looked in the Ubuntu 20.04 repo and didn’t find it.

In any case, I now have my script rewritten using the Python SDK and it works. I am able to generate a transaction, take it offline to sign, and send it (at least on testnet – I assume it will work on mainnet but I haven’t tested it yet).

However, I now have a bit of a problem with the Python SDK. I am able to do everything with Purestake but I would like to make my offline signing script available as GPL software on GitHub, and to do that it would be much better if I could use the Algoexplorer API because it doesn’t require registration or a token.

The problem is this: the Python SDK won’t let me use the Algoexplorer API because Algoexplorer doesn’t require a token, but the SDK class for making GET and POST requests requires you to enter a token. The class is “AlgodClient(algod_token, algod_address, headers=None)” and the “algod_token” is a required positional parameter – if omitted it gives an error. If you set the variable to “None” it gives you a type error:

TypeError: expected string or bytes-like object

If you try to just put some value into it like “A” to make it happy the server returns a 404 Forbidden errror.

So AlgodClient will let me use the API of Purestake because that requires a token, but it appears that it doesn’t allow you to use Algoexplorer API, which seems pretty odd.

Do I need to modify the class myself? I considered doing it but that doesn’t seem like a very reasonable solution and I am only a beginner with Python anyway.

Thanks very much for your help!

It’s installed with the Algorand software, which also installs goal.

See Examples for python in algov2 - #6 by fabrice
but please adapt to the new endpoints of algoexplorer, that is using https://node.algoexplorerapi.io or equivalent.
See AlgoExplorer API v2

Thanks very much Fabrice! I tried it and it worked fine once I got the right URL for the task.

For anyone else who might be reading this: I found that Algoexplorer now has two endpoints for API requests: for POST requests (and some GET requests for setting up transactions) it’s https://node.algoexplorerapi.io (mainnet). For almost all other GET requests you have to use the Algoindexer which is currently https://algoindexer.algoexplorerapi.io (mainnet). You can get the equivalent testnet and betanet endpoints on the algoexplorer site. On Purestake, it’s all one endpoint still.