I wanna push data (string type) to store in Global State of Smart Contract.
This my TEAL code:
#pragma version 2
byte "myKey"
txna ApplicationArgs 0
app_global_put
int 1
return
“appArgs” is required Uint8Array so I convert my string data and then create the transaction.
let appArgs = [];
appArgs[0] = stringToUint8Array('This is my data');
let txn = algosdk.makeApplicationCreateTxn(recoveredAccount.addr, suggestedParams, 0,
approvalProgByteArray, clearProgByteArray, localInts, localBytes,
globalInts, globalBytes, appArgs);
I used this function to read Global State data
async function readGlobalState(client, account, index){
let accountInfoResponse = await client.accountInformation(account.addr).do();
for (let i = 0; i < accountInfoResponse['created-apps'].length; i++) {
if (accountInfoResponse['created-apps'][i].id == index) {
console.log("Application's global state:");
for (let n = 0; n < accountInfoResponse['created-apps'][i]['params']['global-state'].length; n++) {
console.log(accountInfoResponse['created-apps'][i]['params']['global-state'][n]);
}
}
}
}
I got the result and I tried to convert it to human-readable but I can’t.
The problem is that ‘AAAAAAANCgo=’ doesn’t correspont to the base64 of ‘This is my data’.
The base64 form of ‘This is my data’ is ‘77+5VGhpcyBpcyBteSBkYXRh’
In Python I manage to decode the key field but not the bytes field (I get UnicodeDecodeError) :
dict_state["key"] = base64.b64decode(dict_state["key"]).decode()
dict_state["value"]["bytes"] = base64.b64decode(dict_state["value"]["bytes"]).decode() # NOT WORKING
The value is : "bytes": "E9IakdtRwMU+/ZtaF5LP97oQKUkOlxWC5NEkDlyuV3Q="
And the error is :
UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xd2 in position 1: invalid continuation byte
The bytes corresponding to the base64 representation E9IakdtRwMU+/ZtaF5LP97oQKUkOlxWC5NEkDlyuV3Q= does not represent a valid UTF-8 string.
Not all byte arrays are valid strings.
This smart contract key/value does not store actual strings but instead store some raw data that needs to be displayed differently to be human readable.
In your specific case, the base64 representation corresponds to a 32-byte array. So it’s very likely it’s an Algorand address (but there is no way to be sure without checking the smart contract). To display it in a human-readable way:
$ python3 -c "import base64, sys, algosdk; [print(algosdk.encoding.encode_address(base64.b64decode(line.strip()))) for line in sys.stdin if line.strip()]" <<< E9IakdtRwMU+/ZtaF5LP97oQKUkOlxWC5NEkDlyuV3Q=
CPJBVEO3KHAMKPX5TNNBPEWP665BAKKJB2LRLAXE2ESA4XFOK52CIGZDYA
Note that some smart contracts do not even use valid strings as keys.
Thanks Fabrice it works !
Indeed I did not precise it but it is an address.
I have a function to make keys and values human readable and I will need to add a specific case for addresses.
Hi everybody! got a question for @fabrice : There’s a way to do the same as you suggested in Java? i can’t find an encoder method in the Java sdk to convert the bytes value (which actually is an Algorand address in human readable format) into the readable 58 chars String. Thanks a lot!