EIP.tools

EIP.tools

⚠️ DraftStandards Track: ERC

ERC-8230: Self-Explanatory Smart Contract Instruction

An interface for self-explanatory smart contracts that expose operational instructions to AI agents.

Authors
Created2026-04-13
Discussion Linkhttps://ethereum-magicians.org/t/erc-8230-self-explanatory-smart-contract-instruction/28223

Markdown

https://raw.githubusercontent.com/wispig66/ERCs/re...

EIP-GPT summary

Contents
AbstractMotivation1. Self-Explanatory Contracts2. On-Chain Authority3. AI-Native FormatRelationship to Existing StandardsSpecificationInterfaceMutabilityContent Format: CommonMark SubsetRecommended Document StructureContent GuidelinesRationaleWhy One Function?Why Markdown?Why On-Chain, Not a URI?Backwards CompatibilityReference ImplementationProduction ReferenceSecurity ConsiderationsInstruction TrustworthinessMisleading InstructionsContent InjectionBytecode SizeCopyright

Abstract

This ERC defines a single function instruction() that allows a smart contract to describe — in its own bytecode — how it should be used. The returned content is a Markdown string intended for AI agents and automated systems to read, interpret, and act upon.

A contract that implements instruction() is self-explanatory: it carries its own operational documentation on-chain, with the same immutability and authority as the contract logic itself.

Motivation

AI agents are increasingly interacting with smart contracts on behalf of users. To do so effectively, an agent needs to understand not just what functions exist (the ABI), but how to use the contract to accomplish a goal — the roles, the workflow, the state machine, the edge cases.

Today this knowledge lives in off-chain docs, READMEs, and human-written guides. It is separated from the contract, can go stale, can be censored, and cannot be programmatically discovered. There is no standard way for a contract to say: "here is how you use me."

This ERC fills that gap with three design principles:

1. Self-Explanatory Contracts

A contract should be able to explain itself. Just as NatSpec lets a contract document its functions for developers, instruction() lets a contract document its complete workflow for agents. The contract becomes its own manual.

2. On-Chain Authority

The instruction is part of the contract's bytecode (when implemented as pure) or storage (when view). It is deployed, verified, and immutable alongside the contract logic. This gives the instruction the same authority as the contract itself — it cannot be altered, taken down, or fall out of sync independently. Off-chain documentation, no matter how well-maintained, can never make this guarantee.

3. AI-Native Format

The instruction is Markdown — the format that large language models understand most naturally. No schema negotiation, no deserialization step, no tooling required. An agent reads the string and knows what to do.

Relationship to Existing Standards

StandardWhat it providesAudience
ABI / NatSpecFunction-level signatures and developer docsDevelopers
ERC-7572 (contractURI())Contract identity (name, image)Frontends
ERC-7730Transaction display formatWallets / humans
This ERC (instruction())Complete operational workflowAI agents

Specification

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

Interface

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;

interface IInstruction {
    /// @notice Returns the operational instruction for this contract.
    /// @return A Markdown (CommonMark subset) string.
    function instruction() external view returns (string memory);
}

That is the entire interface. One function, one string.

The ERC-165 identifier for this interface is 0x5e486e0f (bytes4(keccak256("instruction()"))). Contracts that implement ERC-165 SHOULD return true for this identifier.

Mutability

  • Contracts with static instructions SHOULD declare instruction() as pure. This guarantees immutability at the language level and costs zero gas to read.
  • Contracts whose instructions depend on runtime state (e.g., dynamically computed parameters) MAY declare it as view.

Content Format: CommonMark Subset

The returned string MUST conform to the following subset of CommonMark:

Allowed elements:

ElementSyntaxPurpose
Headings#, ##, ###Document structure (max 3 levels)
Bold / Italic**bold**, *italic*Emphasis
Unordered lists- itemEnumerations
Ordered lists1. itemSequential steps
Inline code`code`Function names, parameters, values
Code blocks```Multi-line code, ABI fragments
Tables| col | col |Parameter tables, status code tables
Blockquotes> textCallouts, important notes
Links[text](url)References to external resources

Disallowed elements:

  • Raw HTML (<div>, <script>, etc.) — prevents injection
  • Images (![](...)) — not useful for agent consumption
  • Footnotes, task lists, and other extended syntax — keeps parsing simple

Implementations SHOULD organize the instruction with the following sections, including only those relevant to the contract:

  1. Title and overview (# heading + one paragraph) — what the contract does
  2. Roles — participant roles and responsibilities
  3. Workflow — step-by-step interaction flow from start to finish
  4. Functions — key function signatures with parameter tables
  5. Status Codes — state machine transitions and per-role actions (if applicable)
  6. Fees — fee structure and calculation
  7. Timeouts — duration and consequences per stage (if applicable)
  8. Notes — edge cases and additional guidance

Content Guidelines

  • The instruction SHOULD be self-contained. An agent MUST be able to operate the contract by reading only the instruction and the ABI.
  • Monetary amounts SHOULD specify unit, type, and encoding (e.g., "USDC raw uint96, decimals=6, 1500000 = 1.5 USDC").
  • The instruction SHOULD NOT exceed 32,768 characters.

Rationale

Why One Function?

Business contracts are wildly diverse — a token swap, an options contract, and a social media campaign have nothing in common structurally. Any attempt to decompose instructions into fixed typed fields (e.g., roles(), workflow(), fees()) would either be too rigid for most contracts or too loose to be useful. A single Markdown string lets each contract describe itself in whatever structure fits its domain, while the recommended sections provide enough convention for agents to navigate.

Why Markdown?

Three properties make Markdown the right choice:

  1. LLM-native — Large language models are trained on vast amounts of Markdown. They parse it, reason about it, and follow instructions written in it without any adapter layer.
  2. Human-auditable — A developer or auditor can read instruction() output directly. No decoder ring, no schema lookup.
  3. Forward-compatible — New conventions (sections, annotations) can emerge without changing the interface or the format. A JSON schema would require versioning; Markdown evolves by convention.

Why On-Chain, Not a URI?

The instruction could point to an off-chain resource (like contractURI() in ERC-7572). We chose to store the content directly because:

PropertyOn-chain instruction()Off-chain URI
AuthoritySame as contract bytecodeDepends on host
ImmutabilityGuaranteed (for pure)Not guaranteed
AvailabilitySame as the chainDepends on IPFS/server
Version syncAtomic with contract logicCan drift
DiscoverabilitySingle eth_callResolve URI + fetch

The instruction is not supplementary documentation — it is part of the contract's interface to the world. It should live where the contract lives.

Backwards Compatibility

This ERC introduces a new optional interface with no dependency on existing standards. It does not modify any existing behavior.

Contracts that already expose an instruction() function returning string memory are automatically compatible.

Reference Implementation

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.20;

/// @title InstructedVault — Minimal ERC-8230 reference implementation
contract InstructedVault {

    mapping(address => uint256) public balanceOf;

    function instruction() external pure returns (string memory) {
        return
            "# Simple Vault\n\n"
            "A basic ETH vault. Anyone can deposit; only depositors can withdraw their own balance.\n\n"
            "## Roles\n\n"
            "- **Depositor**: Any address that sends ETH.\n\n"
            "## Workflow\n\n"
            "1. Call `deposit()` with ETH value.\n"
            "2. Call `balanceOf(address)` to check balance.\n"
            "3. Call `withdraw(uint256)` to withdraw (amount in wei).\n\n"
            "## Functions\n\n"
            "| Function | Parameters | Description |\n"
            "|----------|------------|-------------|\n"
            "| deposit() | — | Deposit msg.value ETH |\n"
            "| withdraw(uint256) | amount in wei | Withdraw ETH |\n"
            "| balanceOf(address) | account | Query balance |\n\n"
            "## Notes\n\n"
            "- Minimum deposit: 0.01 ETH.\n"
            "- Withdrawals are immediate, no delay.\n";
    }

    function deposit() external payable {
        require(msg.value >= 0.01 ether, "min 0.01 ETH");
        balanceOf[msg.sender] += msg.value;
    }

    function withdraw(uint256 amount) external {
        require(balanceOf[msg.sender] >= amount, "insufficient");
        balanceOf[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }
}

Production Reference

The SyncTx project implements instruction() across four contract types in production:

  • XRepostDealContract: Sponsored repost campaigns (~4KB instruction, 14 status codes, dual-role workflow, verification and settlement)
  • XQuoteDealContract: Quote tweet campaigns with explicit content submission
  • XFollowCampaign: Follow-reward campaigns via factory/clone pattern
  • EuropeanOptionDealContract: Bilateral PUT/CALL options with collateral and dual-proposal settlement

Security Considerations

Instruction Trustworthiness

For pure implementations, the instruction is embedded in bytecode — it is as trustworthy and immutable as the contract logic. Auditors SHOULD review the instruction content alongside the code.

For view implementations, the instruction may depend on mutable state. Consumers SHOULD treat mutable instructions with the same caution as any admin-controlled parameter.

Misleading Instructions

A malicious contract can return instructions that misrepresent its behavior (e.g., "call approve with amount 1" while the contract actually drains the full balance). There is no on-chain mechanism to verify instruction accuracy.

Mitigations:

  • Agents SHOULD cross-reference instructions with verified source code and ABI.
  • Agents SHOULD enforce their own safety policies (e.g., approval limits) regardless of what the instruction says.
  • Source code verification (Etherscan/Sourcify) lets agents confirm that the instruction() output matches the audited code.

Content Injection

The Markdown subset defined in this ERC disallows raw HTML, eliminating the primary vector for XSS if instructions are rendered in a web context. Consumers that render instructions in HTML SHOULD additionally sanitize the output.

Bytecode Size

On-chain instructions increase deployment cost. A 4KB instruction adds roughly 80,000 gas to deployment. The 24KB bytecode limit (EIP-170) is sufficient for most instructions — our production contracts carry 2–5KB instructions comfortably. Contracts approaching the limit SHOULD keep instructions concise.

Copyright and related rights waived via CC0.

EIP.tools

EIP.tools

Search, read, and map Ethereum improvement proposals, ERCs, RIPs, and CAIPs from one focused interface.

Farcaster
by @apoorveth