Encoding and Decoding
Consistent data representation is crucial when interacting with Algorand smart contracts. This section explains the fundamental concepts of encoding and decoding information so that on-chain logic and off-chain applications remain compatible. By following these guidelines, developers can ensure reliable data handling and a seamless flow of information throughout the development lifecycle.
Encoding Types
Section titled “Encoding Types”The encoding most often returned when querying the state of the chain is JSON.
It is easy to visually inspect but may be relatively slow to parse.
All byte arrays are base 64 encoded strings
MessagePack
Section titled “MessagePack”The encoding used when transmitting transactions to a node is MessagePack.
To inspect a given msgpack file contents a convenience commandline tool is provided:
msgpacktool -d < file.msgpBase64
Section titled “Base64”The encoding for byte arrays is Base64.
This is to make it safe for the byte array to be transmitted as part of a json object.
Base32
Section titled “Base32”The encoding used for Addresses and Transaction Ids is Base32.
Individual Field Encodings
Section titled “Individual Field Encodings”Address
Section titled “Address”In Algorand a public key is a 32 byte array.
The Accounts or Addresses are typically shown as a 58 character long string corresponding to a base32 encoding of the byte array of the public key + a checksum.
Given an address 4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4, encoding to and from the public key format can be done as follows:
address = "4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4"pk = encoding.decode_address(address)addr = encoding.encode_address(pk)
assert addr == addressconst address = '4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4';const addr = algosdk.Address.fromString(address);console.log(address, addr);address := "4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4"pk, _ := types.DecodeAddress(address)addr := pk.String()String addrAsStr = "4H5UNRBJ2Q6JENAXQ6HNTGKLKINP4J4VTQBEPK5F3I6RDICMZBPGNH6KD4";// Instantiate a new Address object with stringAddress addr = new Address(addrAsStr);// Or with the bytesAddress addrAgain = new Address(addr.getBytes());assert addrAgain.equals(addr);Byte arrays
Section titled “Byte arrays”When transmitting an array of bytes over the network, byte arrays are base64 encoded. The SDK will handle encoding from a byte array to base64 but may not decode some fields and you’ll have to handle it yourself. For example compiled program results or the keys and values in a state delta in an application call will be returned as base64 encoded strings.
Example:
Given a base64 encoded byte array SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0 it may be decoded as follows:
encoded_str = "SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0"decoded_str = base64.b64decode(encoded_str).decode("utf-8")print(decoded_str)const b64Encoded = 'SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0';const b64Decoded = algosdk.base64ToBytes(b64Encoded);console.log(b64Encoded, b64Decoded);encoded := "SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0"decoded, _ := base64.StdEncoding.DecodeString(encoded)reencoded := base64.StdEncoding.EncodeToString(decoded)String encodedStr = "SGksIEknbSBkZWNvZGVkIGZyb20gYmFzZTY0";byte[] decodedBytes = Encoder.decodeFromBase64(encodedStr);String reEncodedStr = Encoder.encodeToBase64(decodedBytes);assert encodedStr.equals(reEncodedStr);Integers
Section titled “Integers”Integers in algorand are almost always uint64, sometimes it’s required to encode them as bytes. For example when passing them as application arguments in an ApplicationCallTransaction. When encoding an integer to pass as an application argument, the integer should be encoded as the big endian 8 byte representation of the integer value.
Example:
Given an integer 1337, you may encode it as:
val = 1337encoded_uint = val.to_bytes(8, "big")decoded_uint = int.from_bytes(encoded_uint, byteorder="big")assert decoded_uint == valconst int = 1337;const encoded = algosdk.encodeUint64(int);const safeDecoded = algosdk.decodeUint64(encoded, 'safe');const mixedDecoded = algosdk.decodeUint64(encoded, 'bigint');console.log(int, encoded, safeDecoded, mixedDecoded);val := 1337encodedInt := make([]byte, 8)binary.BigEndian.PutUint64(encodedInt, uint64(val))
decodedInt := binary.BigEndian.Uint64(encodedInt)// decodedInt == valBigInteger val = BigInteger.valueOf(1337);byte[] encodedVal = Encoder.encodeUint64(val);BigInteger decodedVal = Encoder.decodeUint64(encodedVal);assert val.equals(decodedVal);Working with Encoded Structures
Section titled “Working with Encoded Structures”transactions
Section titled “transactions”Sometimes an application needs to transmit a transaction or transaction group between the front end and back end. This can be done by msgpack encoding the transaction object on one side and msgpack decoding it on the other side. Often the msgpack’d bytes will be base64 encoded so that they can be safely transmitted in some json payload so we use that encoding here.
Essentially the encoding is:
tx_byte_str = base64encode(msgpack_encode(tx_obj))
and decoding is:
tx_obj = msgpack_decode(base64decode(tx_byte_str))
Example:
Create a payment transaction from one account to another using suggested parameters and amount 10000, we write the msgpack encoded bytes