Skip to content

Contract ABI

evan saulpaugh edited this page Feb 27, 2025 · 35 revisions

Contract ABI Codec

Description

Canonicalizes and parses function signatures, encodes and decodes contract ABI calls. Offers detailed error messages for illegal signature syntax and non-matching arguments.

Supports Java types of Integer, int[], Long, long[], BigInteger, BigDecimal, Boolean, boolean[], String, byte[], a custom Address type, a custom Tuple type, and arrays of any of these. Arrays can have up to 255 dimensions (max allowed by the JVM) and tuples can be arbitrarily nested.

Usage

Function f = new Function("baz(uint32,bool)"); // canonicalizes and parses any signature automatically
Tuple args = Tuple.of(69L, true);

// Two equivalent styles:
ByteBuffer one = f.encodeCall(args);
ByteBuffer two = f.encodeCallWithArgs(69L, true);

System.out.println(Function.formatCall(one.array())); // a multi-line hex representation

Tuple decoded = f.decodeCall(two);

System.out.println(decoded.equals(args));
TupleType<Tuple> tupleType = TupleType.parse("(int8,bytes1,uint16,string)");

Tuple values = Tuple.of(-1, new byte[] { 0x42 }, 0x2424, "Hello, world!");

tupleType.validate(values);

byte[] packed = tupleType.encodePacked(values).array();

Tests

MonteCarloTest is basically a fuzzer that generates a random function signature, parses it, generates random matching arguments (no invalid data), encodes and decodes a function call, and tests for equality. Done N times successively. Randomness is derived from an initial seed, and is fully replayable. Customizable parameters for maximum tuple/array depth/length are used to constrain memory usage and running time.

Implementation Details

Since version 3.7.0, decoding does NOT operate in STRICT MODE. See https://github.com/ethereum/solidity/commit/3d1ca07e9b4b42355aa9be5db5c00048607986d1

To protect against denial of service, encodings specifying a dynamic array length of 221 or greater will not be decoded and instead an exception will be thrown.

Before encoding, the output length is calculated so that a buffer of the correct length can be allocated. Encoding is done strictly left-to-right (no backtracking to insert offsets).

A limited number of reflective calls are used to support the decoding of multidimensional arrays whose types are known only at runtime.

Build

Refer to https://github.com/esaulpaugh/headlong/wiki/Build

Miscellaneous

See Also

https://github.com/esaulpaugh/headlong-cli

https://github.com/esaulpaugh/headlong-android

Clone this wiki locally