Skip to content

ABI Type Parsing

← Back to ABI Encoding

This example demonstrates how to parse ABI type strings into type objects using ABIType.from_string(). It shows parsing of:

  • Primitive types: uint8, uint64, uint256, bool, byte, address, string
  • Array types: uint64[], byte[32], address[5]
  • Tuple types: (uint64,address), (bool,string,uint256) And demonstrates type properties and isinstance checks for type category detection.

No LocalNet required - pure ABI encoding/decoding

From the repository’s examples directory:

Terminal window
cd examples
uv run python abi/01_type_parsing.py

View source on GitHub

01_type_parsing.py
# ruff: noqa: N999, C901, PLR0912, PLR0915
"""
Example: ABI Type Parsing
This example demonstrates how to parse ABI type strings into type objects using ABIType.from_string().
It shows parsing of:
- Primitive types: uint8, uint64, uint256, bool, byte, address, string
- Array types: uint64[], byte[32], address[5]
- Tuple types: (uint64,address), (bool,string,uint256)
And demonstrates type properties and isinstance checks for type category detection.
No LocalNet required - pure ABI encoding/decoding
"""
from shared import print_header, print_info, print_step, print_success
from algokit_abi import abi
def main() -> None:
print_header("ABI Type Parsing Example")
# Step 1: Parse primitive unsigned integer types
print_step(1, "Parse Unsigned Integer Types")
uint8_type = abi.ABIType.from_string("uint8")
uint64_type = abi.ABIType.from_string("uint64")
uint256_type = abi.ABIType.from_string("uint256")
print_info(f"Parsed 'uint8': {uint8_type}")
print_info(f"Parsed 'uint64': {uint64_type}")
print_info(f"Parsed 'uint256': {uint256_type}")
# Show uint-specific properties
if isinstance(uint8_type, abi.UintType):
print_info(f" uint8 bit_size: {uint8_type.bit_size}")
print_info(f" uint8 byte_len: {uint8_type.byte_len()}")
print_info(f" uint8 is_dynamic: {uint8_type.is_dynamic()}")
if isinstance(uint64_type, abi.UintType):
print_info(f" uint64 bit_size: {uint64_type.bit_size}")
print_info(f" uint64 byte_len: {uint64_type.byte_len()}")
if isinstance(uint256_type, abi.UintType):
print_info(f" uint256 bit_size: {uint256_type.bit_size}")
print_info(f" uint256 byte_len: {uint256_type.byte_len()}")
# Step 2: Parse other primitive types
print_step(2, "Parse Other Primitive Types")
bool_type = abi.ABIType.from_string("bool")
byte_type = abi.ABIType.from_string("byte")
address_type = abi.ABIType.from_string("address")
string_type = abi.ABIType.from_string("string")
print_info(f"Parsed 'bool': {bool_type}")
print_info(f" bool byte_len: {bool_type.byte_len()}")
print_info(f" bool is_dynamic: {bool_type.is_dynamic()}")
print_info(f"Parsed 'byte': {byte_type}")
print_info(f" byte byte_len: {byte_type.byte_len()}")
print_info(f" byte is_dynamic: {byte_type.is_dynamic()}")
print_info(f"Parsed 'address': {address_type}")
print_info(f" address byte_len: {address_type.byte_len()}")
print_info(f" address is_dynamic: {address_type.is_dynamic()}")
print_info(f"Parsed 'string': {string_type}")
print_info(f" string is_dynamic: {string_type.is_dynamic()}")
# Step 3: Parse dynamic array types
print_step(3, "Parse Dynamic Array Types")
uint64_array_type = abi.ABIType.from_string("uint64[]")
address_array_type = abi.ABIType.from_string("address[]")
print_info(f"Parsed 'uint64[]': {uint64_array_type}")
if isinstance(uint64_array_type, abi.DynamicArrayType):
print_info(f" element: {uint64_array_type.element}")
print_info(f" is_dynamic: {uint64_array_type.is_dynamic()}")
print_info(f"Parsed 'address[]': {address_array_type}")
if isinstance(address_array_type, abi.DynamicArrayType):
print_info(f" element: {address_array_type.element}")
# Step 4: Parse static array types
print_step(4, "Parse Static Array Types")
byte32_type = abi.ABIType.from_string("byte[32]")
address5_type = abi.ABIType.from_string("address[5]")
print_info(f"Parsed 'byte[32]': {byte32_type}")
if isinstance(byte32_type, abi.StaticArrayType):
print_info(f" element: {byte32_type.element}")
print_info(f" size: {byte32_type.size}")
print_info(f" byte_len: {byte32_type.byte_len()}")
print_info(f" is_dynamic: {byte32_type.is_dynamic()}")
print_info(f"Parsed 'address[5]': {address5_type}")
if isinstance(address5_type, abi.StaticArrayType):
print_info(f" element: {address5_type.element}")
print_info(f" size: {address5_type.size}")
print_info(f" byte_len: {address5_type.byte_len()}")
# Step 5: Parse tuple types
print_step(5, "Parse Tuple Types")
simple_tuple_type = abi.ABIType.from_string("(uint64,address)")
complex_tuple_type = abi.ABIType.from_string("(bool,string,uint256)")
print_info(f"Parsed '(uint64,address)': {simple_tuple_type}")
if isinstance(simple_tuple_type, abi.TupleType):
print_info(f" elements count: {len(simple_tuple_type.elements)}")
for index, element in enumerate(simple_tuple_type.elements):
print_info(f" [{index}]: {element}")
print_info(f" is_dynamic: {simple_tuple_type.is_dynamic()}")
print_info(f" byte_len: {simple_tuple_type.byte_len()}")
print_info(f"Parsed '(bool,string,uint256)': {complex_tuple_type}")
if isinstance(complex_tuple_type, abi.TupleType):
print_info(f" elements count: {len(complex_tuple_type.elements)}")
for index, element in enumerate(complex_tuple_type.elements):
print_info(f" [{index}]: {element}")
print_info(f" is_dynamic: {complex_tuple_type.is_dynamic()} (contains 'string' which is dynamic)")
# Step 6: Parse nested tuple types
print_step(6, "Parse Nested Tuple Types")
nested_tuple_type = abi.ABIType.from_string("((uint64,bool),address[])")
print_info(f"Parsed '((uint64,bool),address[])': {nested_tuple_type}")
if isinstance(nested_tuple_type, abi.TupleType):
print_info(f" elements count: {len(nested_tuple_type.elements)}")
for index, element in enumerate(nested_tuple_type.elements):
print_info(f" [{index}]: {element}")
if isinstance(element, abi.TupleType):
for nested_index, nested_element in enumerate(element.elements):
print_info(f" [{nested_index}]: {nested_element}")
print_info(f" is_dynamic: {nested_tuple_type.is_dynamic()}")
# Step 7: Type category detection using isinstance
print_step(7, "Type Category Detection with isinstance")
test_types = ["uint64", "bool", "byte", "address", "string", "uint64[]", "byte[32]", "(uint64,address)"]
for type_str in test_types:
parsed_type = abi.ABIType.from_string(type_str)
category = "Unknown"
if isinstance(parsed_type, abi.UintType):
category = "UintType"
elif isinstance(parsed_type, abi.BoolType):
category = "BoolType"
elif isinstance(parsed_type, abi.ByteType):
category = "ByteType"
elif isinstance(parsed_type, abi.AddressType):
category = "AddressType"
elif isinstance(parsed_type, abi.StringType):
category = "StringType"
elif isinstance(parsed_type, abi.DynamicArrayType):
category = "DynamicArrayType"
elif isinstance(parsed_type, abi.StaticArrayType):
category = "StaticArrayType"
elif isinstance(parsed_type, abi.TupleType):
category = "TupleType"
print_info(f"'{type_str}' -> {category}")
# Step 8: Demonstrate type equality
print_step(8, "Type Equality Comparison")
type1 = abi.ABIType.from_string("uint64")
type2 = abi.ABIType.from_string("uint64")
type3 = abi.ABIType.from_string("uint32")
print_info(f"ABIType.from_string('uint64') == ABIType.from_string('uint64'): {type1 == type2}")
print_info(f"ABIType.from_string('uint64') == ABIType.from_string('uint32'): {type1 == type3}")
tuple1 = abi.ABIType.from_string("(uint64,address)")
tuple2 = abi.ABIType.from_string("(uint64,address)")
tuple3 = abi.ABIType.from_string("(uint64,bool)")
print_info(
f"ABIType.from_string('(uint64,address)') == ABIType.from_string('(uint64,address)'): {tuple1 == tuple2}"
)
print_info(f"ABIType.from_string('(uint64,address)') == ABIType.from_string('(uint64,bool)'): {tuple1 == tuple3}")
print_success("ABI Type Parsing example completed successfully!")
if __name__ == "__main__":
main()