Application Binary Interface#

The GenVM Application Binary Interface defines how contracts expose their functionality to external callers and how different contracts interact with each other. The ABI provides a standardized way to encode method calls, handle parameters, and manage contract schemas while supporting both deterministic and non-deterministic operations.

The public ABI includes the stable values listed in Constants. Values listed in Constants bound what a run may do, but they are not part of that surface: a contract cannot read them, and nothing in the ABI is required to keep them stable

Method Calling Convention#

Method calls use Calldata Encoding format with following convention:

# deployment
{
  "args": Array | absent,
  "kwargs": Map | absent,
}

# not deployment
{
  "": String | absent
  "args": Array | absent,
  "kwargs": Map | absent,
}

The method name is carried under the empty key "". Because calldata maps are encoded with sorted keys, the empty key always sorts first.

This shape is enforced by GenVM before any runner is loaded, so a malformed call fails identically in every runner language. The payload must decode as Calldata Encoding and yield a Map whose every key is one of "", "args" or "kwargs", with "" a String, "args" an Array and "kwargs" a Map. On a deployment the "" key must be absent.

The key set is closed: unknown keys are rejected rather than ignored, so two byte-different payloads can never describe the same call. The extension point of the convention is the value of "" (see Special Methods), not the key set. Element types inside args/kwargs are matched against the method signature by the runner, not here.

Violations are reported as malformed_entry; where that surfaces depends on the entry point, see Entry Payload Validation and CallContract Message.

Call Key#

Every emitted message (see EmitInternalMessage Message) carries a call_key: a 256-bit unsigned integer that identifies which method the message targets. It serves the same role as a function selector in EVM, but is derived differently and is not truncated.

The call_key is computed by GenVM from the method name (the empty-key "" field) of the Method Calling Convention calldata as follows:

  • A deployment message uses the reserved value 0 (DEPLOY).

  • A non-deployment message with no method name uses the reserved value 0 (UNNAMED).

  • For a method name shorter than 32 bytes (UTF-8), the call_key is the name bytes placed at the most significant end of a 32-byte big-endian buffer, zero-padded on the right. This keeps short names directly human-readable from their key.

  • For a method name of 32 bytes or longer, the call_key is keccak256(name) with the least significant bit of the last octet forced to 1. The forced bit guarantees this branch can never collide with the zero-padded short-name encoding above (whose low bytes are always zero once the name fits) nor with the reserved 0 value.

The resulting value is interpreted as a big-endian U256.

Special Methods#

All special methods start with a # character. Currently there are:

  • get_schema may expose contract schema, that provides definition of existing methods.

    This method must Return a string containing a JSON object, that follows a schema.

  • errored_message called when execution of an emitted message, that had a value, was not successful