Application Binary Interface (ABI) | Algorand Developer Portal

Application Binary Interface (ABI)

Abstract

This document introduces conventions for encoding method calls, including argument and return value encoding, in Algorand Application call transactions. The goal is to allow clients, such as wallets and dapp frontends, to properly encode call transactions based on a description of the interface. Further, explorers will be able to show details of these method invocations.

Definitions

Specification

The key words “ MUST”, “ MUST NOT”, “ REQUIRED”, “ SHALL”, “ SHALL NOT”, “ SHOULD”, “ SHOULD NOT”, “ RECOMMENDED”, “ MAY”, and “ OPTIONAL” in this document are to be interpreted as described in RFC-2119.

Interfaces are defined in TypeScript. All the objects that are defined are valid JSON objects, and all JSON string types are UTF-8 encoded.

Overview

This document makes recommendations for encoding method invocations as Application call transactions, and for describing methods for access by higher-level entities. Encoding recommendations are intended to be minimal, intended only to allow interoperability among Applications. Higher level recommendations are intended to enhance user-facing interfaces, such as high-level languages, dapps, and wallets. Applications that follow the recommendations described here are called ARC-4 Applications.

Methods

A method is a section of code intended to be invoked externally with an Application call transaction. A method must have a name, it may take a list of arguments as input when it is invoked, and it may return a single value (which may be a tuple) when it finishes running. The possible types for arguments and return values are described later in the Encoding section.

Invoking a method involves creating an Application call transaction to specifically call that method. Methods are different from internal subroutines that may exist in a contract, but are not externally callable. Methods may be invoked by a top-level Application call transaction from an off-chain caller, or by an Application call inner transaction created by another Application.

Method Signature

A method signature is a unique identifier for a method. The signature is a string that consists of the method’s name, an open parenthesis, a comma-separated list of the types of its arguments, a closing parenthesis, and the method’s return type, or void if it does not return a value. The names of the arguments MUST NOT be included in a method’s signature, and MUST NOT contain any whitespace.

For example, add(uint64,uint64)uint128 is the method signature for a method named add which takes two uint64 parameters and returns a uint128. Signatures are encoded in ASCII.

For the benefit of universal interoperability (especially in HLLs), names MUST satisfy the regular expression [_A-Za-z][A-Za-z0-9_]*. Names starting with an underscore are reserved and MUST only be used as specified in this ARC or future ABI-related ARC.

Method Selector

Method signatures contain all the information needed to identify a method, however the length of a signature is unbounded. Rather than consume program space with such strings, a method selector is used to identify methods in calls. A method selector is the first four bytes of the SHA-512/256 hash of the method signature.

For example, the method selector for a method named add which takes two uint64 parameters and returns a uint128 can be computed as follows:

Method signature: add(uint64,uint64)uint128

SHA-512/256 hash (in hex): 8aa3b61f0f1965c3a1cbfa91d46b24e54c67270184ff89dc114e877b1753254a

Method selector (in hex): 8aa3b61f

Method Description

A method description provides further information about a method beyond its signature. This description is encoded in JSON and consists of a method’s name, description (optional), arguments (their types, and optional names and descriptions), and return type and optional description for the return type. From this structure, the method’s signature and selector can be calculated. The Algorand SDKs provide convenience functions to calculate signatures and selectors from such JSON files.

These details will enable high-level languages and dapps/wallets to properly encode arguments, call methods, and decode return values. This description can populate UIs in dapps, wallets, and explorers with description of parameters, as well as populate information about methods in IDEs for HLLs.

The JSON structure for such an object is:

interface Method {

/** The name of the method */

name: string;

/** Optional, user-friendly description for the method */

desc?: string;

/** The arguments of the method, in order */

args: Array<{

/** The type of the argument */

type: string;

/** Optional, user-friendly name for the argument */

name?: string;

/** Optional, user-friendly description for the argument */

desc?: string;

}>;

/** Information about the method's return value */

returns: {

/** The type of the return value, or "void" to indicate no return value. */

type: string;

/** Optional, user-friendly description for the return value */

desc?: string;

};

}

For example:

{

"name": "add",

"desc": "Calculate the sum of two 64-bit integers",

"args": [

{ "type": "uint64", "name": "a", "desc": "The first term to add" },

{ "type": "uint64", "name": "b", "desc": "The second term to add" }

],

"returns": { "type": "uint128", "desc": "The sum of a and b" }

}

Interfaces

An Interface is a logically grouped set of methods. All method selectors in an Interface MUST be unique. Method names MAY not be unique, as long as the corresponding method selectors are different. Method names in Interfaces MUST NOT begin with an underscore.

An Algorand Application implements an Interface if it supports all of the methods from that Interface. An Application MAY implement zero, one, or multiple Interfaces.

Interface designers SHOULD try to prevent collisions of method selectors between Interfaces that are likely to be implemented together by the same Application.

Interface Description

An Interface description is a JSON object containing the JSON descriptions for each of the methods in the Interface.

The JSON structure for such an object is:

interface Interface {

/** A user-friendly name for the interface */

name: string;

/** Optional, user-friendly description for the interface */

desc?: string;

/** All of the methods that the interface contains */

methods: Method[];

}

Interface names MUST satisfy the regular expression [_A-Za-z][A-Za-z0-9_]*. Interface names starting with ARC are reserved to interfaces defined in ARC. Interfaces defined in ARC-XXXX (where XXXX is a 0-padded number) SHOULD start with ARC_XXXX.

For example:

{

"name": "Calculator",

"desc": "Interface for a basic calculator supporting additions and multiplications",

"methods": [

{

"name": "add",

"desc": "Calculate the sum of two 64-bit integers",

"args": [

{ "type": "uint64", "name": "a", "desc": "The first term to add" },

{ "type": "uint64", "name": "b", "desc": "The second term to add" }

],

"returns": { "type": "uint128", "desc": "The sum of a and b" }

},

{

"name": "multiply",

"desc": "Calculate the product of two 64-bit integers",

"args": [

{ "type": "uint64", "name": "a", "desc": "The first factor to multiply" },

{ "type": "uint64", "name": "b", "desc": "The second factor to multiply" }

],

"returns": { "type": "uint128", "desc": "The product of a and b" }

}

]

}

Contracts

A Contract is a declaration of what an Application implements. It includes the complete list of the methods implemented by the related Application. It is similar to an Interface, but it may include further details about the concrete implementation, as well as implementation-specific methods that do not belong to any Interface. All methods in a Contract MUST be unique; specifically, each method MUST have a unique method selector.

Method names in Contracts MAY begin with underscore, but these names are reserved for use by this ARC and future extensions of this ARC.

OnCompletion Actions and Creation

In addition to the set of methods from the Contract’s definition, a Contract MAY allow Application calls with zero arguments, also known as bare Application calls. Since method invocations with zero arguments still encode the method selector as the first Application call argument, bare Application calls are always distinguishable from method invocations.

The primary purpose of bare Application calls is to allow the execution of an OnCompletion (apan) action which requires no inputs and has no return value. A Contract MAY allow this for all of the OnCompletion actions listed below, for only a subset of them, or for none at all. Great care should be taken when allowing these operations.

Allowed OnCompletion actions:

Note that OnCompletion action 3, ClearState, is NOT allowed to be invoked as a bare Application call.

If a Contract elects to allow bare Application calls for some OnCompletion actions, then that Contract SHOULD also allow any of its methods to be called with those OnCompletion actions, as long as this would not cause undesirable or nonsensical behavior.

If a Contract requires an OnCompletion action to take inputs or to return a value, then the RECOMMENDED behavior of the Contract is to not allow bare Application calls for that OnCompletion action. Rather, the Contract should have one or more methods that are meant to be called with the appropriate OnCompletion action set in order to process that action.

A Contract MUST NOT allow any of its methods to be called with the ClearState OnCompletion action.

If an Application is called with greater than zero Application call arguments (i.e. NOT a bare Application call) and the OnCompletion action is NOT ClearState, the Application MUST always treat the first argument as a method selector and invoke the specified method. This behavior MUST be followed for all OnCompletion actions, except for ClearState. This applies to Application creation transactions as well, where the supplied Application ID is 0.

Method Invocation

In order for a caller to invoke a method, the caller and the method implementation (callee) must agree on how information will be passed to and from the method. This ABI defines a standard for where this information should be stored and for its format.

This standard does not apply to Application calls with the ClearState OnCompletion action, since it is unsafe for ClearState programs to rely on user input.

Standard Format

The method selector must be the first Application call argument (index 0), accessible as txna ApplicationArgs 0 from TEAL (except for bare Application calls, which use zero application call arguments).

If a method has 15 or fewer arguments, each argument MUST be placed in order in the following Application call argument slots (indexes 1 through 15). The arguments MUST be encoded as defined in the Encoding section.

Otherwise, if a method has 16 or more arguments, the first 14 MUST be placed in order in the following Application call argument slots (indexes 1 through 14), and the remaining arguments MUST be encoded as a tuple in the final Application call argument slot (index 15). The arguments must be encoded as defined in the Encoding section.

Implementing a Method

An ARC-4 Application implementing a method must follow specific steps regarding bare Application calls, examining method selectors, executing method actions, extracting arguments, and encoding return values, as described in the main document.

Calling a Method from Off-Chain

To invoke an ARC-4 Application, an off-chain system, such as a dapp or wallet, would create an Application call transaction as specified in the main document, including the method selector as the first Application call argument, encode arguments, and submit the transaction.

Encoding

This section describes how ABI types can be represented as byte strings, focusing on non-sequential reads and relocatable encoding. Types such as uint<N>, address, string, and tuples are defined with specific encoding rules.

Rationale

Security Considerations

None.

Copyright

Copyright and related rights waived via CCO.