I don’t know if you might find it useful but, this is a Python snippet I used to write, try to retrieve and validate data as dictionaries using a 0 ALGO transaction note field.
Note: I didn’t checked if the copy&paste kept the correct indentation…
Example’s dependencies:
import time
import json
import base64
import msgpack
from schema import Schema, And, Optional
from datetime import datetime
from algosdk import mnemonic
from algosdk.error import *
from algosdk.future.transaction import PaymentTxn
Write data on-chain:
data_publisher_account = {
'pk': mnemonic.to_public_key(passphrase),
'sk': mnemonic.to_private_key(passphrase)
}
data = {
'counter': 4,
'answer': 42,
'coefficient': 0.1,
'timestamp': str(datetime.now())
}
bytes_note = msgpack.packb(data)
unsigned_txn = PaymentTxn(
sender=data_publisher_account['pk'],
sp=params,
receiver=data_publisher_account['pk'],
amt=0,
note=bytes_note
)
signed_txn = unsigned_txn.sign(data_publisher_account['sk'])
txid = algod_client.send_transaction(signed_txn)
Retrive transactions note form an address
, from start_block
up to end_block
:
def get_address_txns_note(
indexer_client,
address,
start_block=None,
end_block=None
):
nexttoken = ""
numtx = 1
address_txns = []
while numtx > 0:
result = indexer_client.search_transactions_by_address(
address=address,
limit=1000,
next_page=nexttoken,
min_round=start_block,
max_round=end_block
)
txns = result['transactions']
address_txns += txns
numtx = len(txns)
if numtx > 0:
# pointer to the next chunk of requests
nexttoken = result['next-token']
txns_note = [txn.get('note') for txn in address_txns]
return txns_note
CONNECTION_ATTEMPT_DELAY_SEC = 3
MAX_CONNECTION_ATTEMPTS = 10
attempts = 1
txns_note = None
while attempts <= MAX_CONNECTION_ATTEMPTS:
try:
txns_note = get_address_txns_note(
indexer_client, data_publisher_account['pk'], start_block, end_block
)
break
except IndexerHTTPError:
print(f'Indexer Client connection attempt {attempts}/{MAX_CONNECTION_ATTEMPTS}')
print('Trying to connect to Indexer Client again...')
time.sleep(CONNECTION_ATTEMPT_DELAY_SEC)
finally:
attempts += 1
if not txns_note:
quit("Unable to connect to Indexer Client.")
Validate data using schema
:
data_schema = Schema({
'counter': int,
'answer': And(int, lambda n: 0 <= n),
Optional('coefficient'): And(float, lambda n: 0 <= n <= 1),
'timestamp': str
})
data = []
for txn_note in txns_note:
try:
data = data_schema.validate(
msgpack.unpackb(base64.b64decode(txn_note))
)
if data['answer'] == 42:
data += [data]
except:
pass
if not data:
raise Exception(
f'Impossible to find valid data published by {data_publisher_account['pk']} '
f'starting from block {start_block}.'
)