logo

Representable Contract State

an XML-based canonical view of EVM contract state


Concept

Abstract

This ERC introduces IXMLRepresentableState, a standard interface and XML binding schema that allows an EVM smart contract to define a static XML template with machine-readable bindings to its state and view functions. Off-chain renderers use this template to build a canonical XML document representing the contract's state at a specific block, without incurring any on-chain gas cost.

A contract that claims to implement IXMLRepresentableState MUST be XML-complete: every piece of mutable state that the author considers semantically relevant MUST be represented in the XML via bindings, so that the rendered XML is a complete representation of the contract at a given (chain-id, address, block-number).

Additionally, this ERC defines an optional interface IXMLRepresentableStatePart for contracts that expose one or more partial XML templates representing selected views of their state (for example, a settlement context), without changing the semantics of the canonical full representation.

Motivation

Smart contracts can efficiently orchestrate and process the life cycle of a financial (derivative) product to an extent that they effectively represent the financial product itself.

At the same time, many applications require a human-readable, machine-parseable representation of that product and its state: valuation oracles need inputs for settlements; smart bonds and other tokenized instruments need legal terms, term sheets, or regulatory reports; and on-chain registries, governance modules, or vaults benefit from a stable “document view” of their state.

In the traditional off-chain world, such needs are addressed by standards like FpML, the ISDA Common Domain Model, or the ICMA Bond Data Taxonomy. A common pattern is to treat an XML (or similar) document as the definitive source defining the financial product and then generate code to interact with the corresponding data. When a process modifies or updates properties of the product, developers must synchronize the smart contract’s internal state with the off-chain XML representation. Today, each project typically invents its own set of view functions and off-chain conventions, so clients need bespoke code to map contract state into XML, JSON, or PDF. This makes interoperability, independent auditing, and reuse of tooling harder.

This ERC inverts that pattern by putting the smart contract at the centre. A contract declares that it implements IXMLRepresentableState and defines an interface of representable state. Off-chain renderers can then derive a canonical XML document that reflects the semantically relevant state of the contract at a given (chain-id, address, block-number), using only eth_call and a standardized XML binding schema. Rendering happens entirely off-chain and does not change state, so there is no gas cost, yet the resulting XML remains cryptographically anchored to the chain.

Typical use cases include:

  • Smart derivative contracts that must present their current state to a valuation oracle or settlement engine.
  • Smart bonds and other tokenized financial instruments that must generate legal terms, term sheets, or regulatory and supervisory reports.
  • On-chain registries, governance modules, and vaults that want a reproducible, auditable document-style snapshot of their state.

By standardizing the Solidity interface and the XML attribute schema, this ERC allows generic tools to consume any compliant contract without project-specific adapters, and to plug directly into existing XML-based workflows in finance and beyond.

Specification

Terminology

  • XML template: A well-formed XML document, returned as a UTF-8 string by the contract, that contains placeholder bindings in the evmstate namespace.
  • Binding: An evmstate:* attribute on an XML element that instructs a renderer to fetch a value from the contract (or from chain context) and insert it into the document.
  • XML representation: The final XML document obtained by evaluating all bindings of the XML template against the contract at a specific (chain-id, address, block-number) and then removing all evmstate:* attributes.
  • XML-complete contract: A contract that implements IXMLRepresentableState and whose XML representation encodes all semantically relevant mutable state. Informally, if two contracts are bytecode-identical and their XML representations agree at some block, their externally observable behaviour MUST be the same from that block onward.
  • Partial XML template: A well-formed XML document returned by statePartXmlTemplate(partId) on a contract implementing IXMLRepresentableStatePart. It uses the same evmstate bindings as the full template but is intended to represent only a selected view or projection of the contract state.
  • Partial XML view: The XML document obtained by rendering a partial XML template against a contract at a specific (chain-id, address, block-number). Partial XML views are not required to be XML-complete and MAY omit state that is present in the full XML representation.

Interface

The base interface is:

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

/**
 * @title XML Representable State interface
 * @notice Contracts implementing this interface expose an XML template that can be rendered
 *         into a canonical XML representation of the contract state at a given block.
 * @dev The XML binding schema and version are defined inside the XML itself (e.g. via
 *      namespaces or attributes). Snapshot consistency is achieved off-chain by evaluating
 *      all view calls against a single fixed block.
 */
interface IXMLRepresentableState {
    /**
     * @notice Returns the XML template string, using a dedicated namespace for bindings.
     * @dev MUST return a well-formed XML 1.0 (or 1.1) document in UTF-8 encoding.
     *      Implementations SHOULD make this string independent of mutable contract state
     *      and environment variables, i.e., effectively constant.
     */
    function stateXmlTemplate() external view returns (string memory);
}

For contracts that want stronger off-chain tooling support (caching and integrity checks), optional extended interfaces are defined.

Versioned extension

/**
 * @title Representable State (versioned) interface
 * @notice Adds a monotonically increasing version of the representable state. This optional
 *         extension allows off-chain tools to cheaply detect whether the representation-relevant
 *         state has changed.
 */
interface IRepresentableStateVersioned {
    /**
     * @notice Monotonically increasing version of the representable state.
     * @dev Implementations SHOULD increment this whenever any mutable state that participates
     *      in the representation changes. It MAY start at 0.
     *
     *      Off-chain tools MAY use this to:
     *        - cache rendered XML and skip recomputation if the version is unchanged;
     *        - provide a simple ordering of state changes.
     */
    function stateVersion() external view returns (uint256);
}

Hashed extension

/**
 * @title Representable State (hashed) interface
 * @notice Exposes a hash of a canonical state tuple used for the representation.
 *         This optional extension allows off-chain tools to verify integrity of an
 *         externally provided representation against on-chain state.
 */
interface IRepresentableStateHashed {
    /**
     * @notice Hash of the canonical state tuple used for the representation.
     * @dev Implementations MAY choose their own canonical encoding of state (e.g.,
     *      abi.encode of a tuple of all fields that are represented).
     *
     *      This function is intended for off-chain integrity checks, for example:
     *        - parties can sign (chainId, contract, blockNumber, stateHash);
     *        - renderers can recompute the same hash from the values they used.
     *
     *      It is RECOMMENDED that stateHash() is implemented as a pure/view
     *      function that computes the hash on the fly, instead of storing it in
     *      contract storage and updating it on every change.
     */
    function stateHash() external view returns (bytes32);
}

Combined convenience extensions

/**
 * @title XML Representable State (versioned) interface
 * @notice Convenience interface combining XML template and versioned state.
 */
interface IXMLRepresentableStateVersioned is IXMLRepresentableState, IRepresentableStateVersioned {}

/**
 * @title XML Representable State (hashed) interface
 * @notice Convenience interface combining XML template and hashed state.
 */
interface IXMLRepresentableStateHashed is IXMLRepresentableState, IRepresentableStateHashed {}

/**
 * @title XML Representable State (versioned + hashed) convenience interface
 * @notice Convenience interface combining XML template and versioned/hashed state.
 */
interface IXMLRepresentableStateVersionedHashed is IXMLRepresentableState, IRepresentableStateVersioned, IRepresentableStateHashed {}

A contract that implements any of these extended interfaces is also considered an implementation of IXMLRepresentableState.

Partial XML state views (optional)

Some applications benefit from specialised views of the contract state (for example, a settlement context for a smart derivative contract) without needing to process the full XML representation.

To support such use cases, this ERC defines an optional interface that allows contracts to expose one or more partial XML templates keyed by an application-defined identifier:

/**
 * @title XML Representable State (partial) interface
 * @notice Optional extension exposing partial XML templates for selected views of the state.
 * @dev The meaning of partId is contract-specific or defined by higher-level standards
 *      (e.g. "settlement context" for an ERC-6123 implementation). Implementations of this
 *      interface alone are NOT required to be XML-complete.
 */
interface IXMLRepresentableStatePart {
    /**
     * @notice Returns the XML template string for a particular partial state view.
     * @param partId Contract-specific identifier of the partial view.
     * @dev MUST return a well-formed XML 1.0 (or 1.1) document in UTF-8 encoding and MUST
     *      follow the same binding rules as `stateXmlTemplate()`.
     */
    function statePartXmlTemplate(uint256 partId) external view returns (string memory);
}

Contracts that implement both IXMLRepresentableState and IXMLRepresentableStatePart may optionally declare a convenience interface:

/**
 * @title XML Representable State (full + parts) interface
 * @notice Convenience interface for contracts that provide a canonical full representation
 *         and one or more partial views.
 */
interface IXMLRepresentableStateWithParts is IXMLRepresentableState, IXMLRepresentableStatePart {}

Higher-level standards MAY reserve specific partId values for well-known views. Implementations that define their own partId mapping SHOULD document it in their contract documentation or off-chain specification.

XML Namespace and Bindings (overview)

This ERC defines the XML namespace URI

  • Namespace URI: urn:evm:state:1.0
  • Recommended prefix: evmstate

The XML template MUST declare this namespace, for example:

<Contract xmlns="urn:example:instrument"
          xmlns:evmstate="urn:evm:state:1.0">
    ...
</Contract>

Bindings are expressed as attributes in the evmstate namespace on XML elements. A binding element is any XML element that has one or more attributes in that namespace.

At a high level:

  • evmstate:call and evmstate:selector bind an element to a contract view function (signature form or raw selector).
  • evmstate:target (or the pluralised evmstate:targets in multi-binding mode) routes a value either into the element’s text content or into a named attribute.
  • evmstate:format / evmstate:scale (and their plural forms) control string formatting and decimal scaling.
  • The optional array binding profile uses
    • evmstate:item-element on an array container, and
    • evmstate:item-field on nodes inside the template row, to render arrays (and arrays of tuples) as repeated child elements.

The detailed rules for function binding, single vs. multi-binding mode, formatting, the array binding profile, and chain/contract identification are specified on the separate “XML Namespace and Bindings” page.

Chain and contract identification

The XML representation MUST identify the chain, contract, and block that it represents.

This ERC reserves the following attributes in the evmstate namespace on the root element:

  • evmstate:chain-id
  • evmstate:contract-address
  • evmstate:block-number

Example root element in the template:

<Contract xmlns="urn:example:instrument"
          xmlns:evmstate="urn:evm:state:1.0"
          evmstate:chain-id=""
          evmstate:contract-address=""
          evmstate:block-number="">
    ...
</Contract>

These attributes are context bindings:

  • The renderer MUST set evmstate:chain-id to the chain ID (e.g. [EIP-155] chain IDs), as a base-10 string.
  • The renderer MUST set evmstate:contract-address to the contract address, as a checksummed hex address.
  • The renderer MUST set evmstate:block-number to the block number at which the representation was evaluated, as a base-10 string.

These fields are filled based on the RPC context (chain id, contract address, and block tag) and do not correspond to actual contract calls.

XML representation and XML-complete contracts

For a given chain-id C, contract address A, and block-number B, and for a contract that implements IXMLRepresentableState, the XML representation at (C, A, B) is defined as follows:

  1. Choose a JSON-RPC provider for chain C.
  2. Call eth_getBlockByNumber (or equivalent) to obtain block B and its number, or use an externally provided B.
  3. Perform all eth_call invocations (for stateXmlTemplate() and for all bound functions) with blockTag = B.
  4. Start from the XML template returned by stateXmlTemplate().
  5. Resolve all bindings as specified (including the optional array profile, if supported by the renderer) and insert the resolved values.
  6. Fill evmstate:chain-id, evmstate:contract-address, and evmstate:block-number on the root element.
  7. Optionally remove all evmstate:* attributes from the document.

A contract is XML-complete if, for every block B at which its code matches this ERC’s interface, the following holds:

Given the XML representation at (C, A, B), one can reconstruct all semantically relevant mutable state that influences the contract’s future behaviour (up to isomorphism).

This is a semantic property that cannot be enforced by the EVM itself, but it can be audited and tested. Authors of contracts that claim to implement IXMLRepresentableState MUST ensure that:

  • Every mutable storage variable that influences behaviour is either:
    • directly bound via an evmstate:call / evmstate:selector, or
    • deterministically derivable from bound values via a public algorithm.
  • Adding new mutable state requires adding corresponding bindings to the template.

Contracts that implement IXMLRepresentableStatePart MAY define additional partial XML templates via statePartXmlTemplate(partId). Rendering of such partial templates follows the same binding rules and snapshot semantics as stateXmlTemplate(), but no XML-completeness claim is made for any individual partId. When a contract also implements IXMLRepresentableState and claims to be XML-complete, the XML representation defined above remains the canonical representation; partial views SHOULD be consistent with it and MUST NOT contradict the state that would be observed via the full representation.

Race conditions and consistent snapshots

If a renderer naively uses eth_call with blockTag = "latest" for each binding, state may change between calls when new blocks are mined. In that case, different bindings might see different blocks, and the resulting XML would not correspond to a single consistent contract state.

To avoid this race condition, renderers MUST:

  1. Determine a single block-number B at the start of rendering, e.g. by calling eth_getBlockByNumber("latest").
  2. Use blockTag = B for:
    • the call to stateXmlTemplate(), and
    • all subsequent function calls required by the bindings inside the template.

Under normal node behaviour, this guarantees that all view calls see the same state snapshot.

If the contract implements IRepresentableStateVersioned, the renderer MAY additionally use stateVersion() for caching or sanity checks, but the basic snapshot algorithm using a fixed blockTag is mandatory for all conforming renderers.

Representable Contract State referenced in Events

Emitting events is an on-chain operation that MUST be paid for by the transaction sender. If an event is intended to trigger external processing of a contract’s state, it is tempting to publish all required information as event arguments. However, logging large portions of static or slowly changing data can be expensive.

When a contract also exposes a representable contract state (e.g. via IXMLRepresentableState and/or IXMLRepresentableStatePart), it is natural to treat events primarily as triggers and to use them to carry compact references into that representable state instead of full by-value snapshots.

In other words, the event transports state by reference rather than by value: the event payload contains just enough information for an off-chain consumer to locate and render the relevant view of the contract state at the block in which the event was emitted.

Example: ERC-6123 Settlement Data by Reference

In ERC-6123, the settlement process is triggered by the SettlementRequested event:

event SettlementRequested(address initiator, string tradeData, string lastSettlementData);

A straightforward interpretation of this interface is that the full set of data required to perform a settlement is passed as part of the event parameters:

  • tradeData encodes the information required to value the underlying trade.
  • lastSettlementData encodes the information required to compute the valuation margin using the previous settlement as alignment point.

In many realistic deployments, large parts of tradeData and lastSettlementData are static or slowly changing. Logging such data in every settlement request can therefore lead to unnecessary gas consumption.

Contracts that implement both ERC-6123 and a representable contract state interface (for example, an XML-based representation exposed via read-only functions) SHOULD treat settlement events as compact references to the on-chain state rather than as self-contained data blobs. In particular:

  • Implementations MAY emit SettlementRequested with empty or minimal tradeData and lastSettlementData fields.
  • Off-chain oracles SHOULD obtain the full settlement context by reading the representable contract state (for example via an EvmXmlRenderer or a functionally equivalent renderer) instead of relying solely on the event payloads.
  • Implementations SHOULD document which fields in SettlementRequested are passed by value (containing all information needed locally) and which are passed by reference (containing only identifiers or indices into the representable contract state).

As an example, an implementation MAY define that in SettlementRequested the lastSettlementData parameter contains only an index or timestamp of the last settlement. This value then serves as a reference into the representable contract state from which the oracle derives the full settlement information needed to compute the margin. This pattern reduces event size and gas cost while preserving a deterministic, on-chain-defined view of the contract state used for settlement.

Reference URI Scheme

When events carry references into a representable contract state, those references SHOULD be expressed in a machine-readable URI format. This ERC does not mandate a single URI scheme, but defines a simple RECOMMENDED pattern that is sufficient for most use cases.

For events that refer to the same contract that emitted the event (the most common case), the chain, contract address, and block number are already known from the log context. A reference into the representable state only needs to identify:

  • which view is requested (for example, a particular partId for statePartXmlTemplate), and
  • optionally, which version or instance of that view (for example, an index into a list of settlements).

This ERC RECOMMENDS the following minimal scheme for references to partial XML views:

evmstate://self/part/<partId>[?key=<application-specific-key>]

where

  • self indicates that the reference points to the contract that emitted the event;
  • <partId> is the decimal or hexadecimal string representation of the uint256 partId argument that would be passed to statePartXmlTemplate(partId); and
  • key is an optional application-specific discriminator (e.g. a settlement index or timestamp).

For example, an ERC-6123 implementation that reserves partId = 1 for its “settlement context” view might emit a SettlementRequested event with

lastSettlementData = "evmstate://self/part/1?key=2026-01-02";

An off-chain oracle that consumes this event would then:

  1. Read the log (chain-id C, contract address A, block-number B).

  2. Parse lastSettlementData and extract partId = 1 and key = "2026-01-02".

  3. Call, at block B:

    statePartXmlTemplate(1)
    

    on contract A, and render the resulting partial XML template using the rules defined in this ERC.

  4. Apply any application-specific logic based on key (for example, selecting the settlement with date 2026-01-02 from within the rendered view).

Higher-level standards MAY define additional URI forms if they need to reference views on different contracts or chains (for example, evmstate://<chain-id>/<contract-address>/part/<partId>), but cross-contract references are intentionally out of scope for this ERC.

The partId used in the URI is always a uint256 and corresponds directly to the partId parameter of statePartXmlTemplate(uint256 partId). Standards that wish to define globally unique part identifiers MAY define their partId constants as uint256 values derived from a namespaced string, for example:

uint256 constant XML_PART_SETTLEMENT_CTX =
    uint256(keccak256("ERC-6123:XML:SETTLEMENT-CONTEXT:v1"));

In that case the URI would still carry the numeric identifier, e.g.

evmstate://self/part/8224939103947...

The on-chain type remains uint256 for simplicity and ABI compatibility. Tools are free to expose more human-friendly labels (such as "settlement-context") in their user interfaces, as long as those labels map unambiguously to the uint256 partId used on-chain.

Illustration: Contract event state by reference

The following sequence diagram illustrates the concept of fetching contract event state by reference.

Event Life Cycle - Fetching State by Reference

Rationale

  • Why XML, not JSON?
    XML remains widely used in financial and regulatory infrastructures, with mature schema tooling (XSD), XSLT, and document transformation pipelines. Many smart financial instruments and SDC-like products already use XML representations internally. This ERC does not preclude a future JSON analogue.

  • Why templates on-chain rather than hard-coded off-chain?
    Putting the template (and its bindings) on-chain makes it part of the contract’s immutable code and governance. Auditors and counterparties can verify that the representation is aligned with the contract logic, rather than trusting arbitrary off-chain conventions.

  • Why a separate namespace (evmstate)?
    Using a dedicated namespace keeps the templating mechanism explicit and avoids collisions with business XML schemas. It also aligns with existing XML templating patterns that use XML namespaces for processing instructions.

  • Why both call and selector forms?
    The signature form is human-readable and self-describing. The selector form accommodates low-level or obfuscated contracts and allows decoupling of the template from function names.

  • Why not enforce XML-completeness on-chain?
    The EVM cannot introspect storage layout or reason about “semantically relevant” variables in a general way. XML-completeness is therefore specified as a semantic, auditable property rather than a mechanically enforced one.

  • Why arrays as repeated child elements only?
    The array binding profile maps array-valued outputs to repeated child elements, a shape that is easy to validate with XSD and to transform with XSLT. Inline list or aggregated representations can be derived in a post-processing step without increasing the complexity of the on-chain binding schema.

  • Why partial XML state views?
    Many real-world use cases (such as settlement or margining for smart financial contracts) only require a specific projection of the state, not the entire representation. Partial XML templates allow contracts to expose such specialised views (for example, “settlement context” or “risk summary”) without duplicating or bloating the full XML template, and without weakening the semantics of the canonical XML-complete representation.

  • Why events by reference instead of by value?
    Referencing a representable contract state from events (for example, via a URI into a partial view) reduces gas cost while maintaining a deterministic, contract-defined source for all state that matters to off-chain processing.

Backwards Compatibility

This ERC is purely additive:

  • It introduces a new interface and does not change any existing standard.
  • Existing contracts remain unaffected.
  • Contracts can implement this interface alongside ERC-20, ERC-721, ERC-1155, or any other existing standard.

Contracts and renderers that do not implement the array binding profile remain fully compliant with the core profile of this ERC; they simply treat array-valued bindings and the corresponding attributes as errors.

Contracts and tools that do not support IXMLRepresentableStatePart remain fully compliant with this ERC; they simply ignore the optional partial state extension.

Reference Implementation

IRepresentableState.sol

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

/**
 * @title XML Representable State interface
 * @notice Contracts implementing this interface expose an XML template that can be rendered
 *         into a canonical XML representation of the contract state at a given block.
 * @dev The XML binding schema and version are defined inside the XML itself (e.g., via
 *      namespaces or attributes). Snapshot consistency is achieved off-chain by evaluating
 *      all view calls against a single fixed block.
 */
interface IXMLRepresentableState {
    function stateXmlTemplate() external view returns (string memory);
}

/**
 * @title Representable State (versioned) interface
 * @notice Adds a monotonically increasing version of the representable state.
 */
interface IRepresentableStateVersioned {
    function stateVersion() external view returns (uint256);
}

/**
 * @title Representable State (hashed) interface
 * @notice Exposes a hash of a canonical state tuple used for the representation.
 */
interface IRepresentableStateHashed {
    function stateHash() external view returns (bytes32);
}

/**
 * @title XML Representable State (versioned) interface
 * @notice Convenience interface combining XML template and versioned state.
 */
interface IXMLRepresentableStateVersioned is IXMLRepresentableState, IRepresentableStateVersioned {}

/**
 * @title XML Representable State (hashed) interface
 * @notice Convenience interface combining XML template and hashed state.
 */
interface IXMLRepresentableStateHashed is IXMLRepresentableState, IRepresentableStateHashed {}

/**
 * @title XML Representable State (versioned + hashed) convenience interface
 * @notice Convenience interface combining XML template and versioned/hashed state.
 */
interface IXMLRepresentableStateVersionedHashed is
    IXMLRepresentableState,
    IRepresentableStateVersioned,
    IRepresentableStateHashed
{}

Example contract

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

import "./IRepresentableState.sol";

/**
 * @title Example XML-representable contract
 * @notice Simple "instrument" with state fields owner, notional, currency, maturity, and active flag and
 *         an XML representation of its internal state using the generic IXMLRepresentableState
 *         schema.
 */
contract MinimalInstrument is IXMLRepresentableStateVersionedHashed {
    address public owner;

    uint256 public notional;
    string  public currency;
    uint256 public maturityDate;
    bool    public active;

    uint256 private _stateVersion;

    event Updated(address indexed updater, uint256 newNotional, uint256 newMaturity, bool newActive);

    constructor(address _owner, uint256 _notional, uint256 _maturityDate) {
        owner = _owner;
        notional = _notional;
        currency = "EUR";
        maturityDate = _maturityDate;
        active = true;
        _stateVersion = 1;
    }

    function update(uint256 _notional, uint256 _maturityDate, bool _active) external {
        require(msg.sender == owner, "not owner");
        notional = _notional;
        maturityDate = _maturityDate;
        active = _active;
        _stateVersion += 1;
        emit Updated(msg.sender, _notional, _maturityDate, _active);
    }

    /// @inheritdoc IXMLRepresentableState
    function stateXmlTemplate() external pure override returns (string memory) {
        // Notional as text, currency as attribute via multi-binding attributes.
        return
            "<Instrument xmlns='urn:example:instrument'"
                " xmlns:evmstate='urn:evm:state:1.0'"
                " evmstate:chain-id=''"
                " evmstate:contract-address=''"
                " evmstate:block-number=''>"
                    "<Owner evmstate:call='owner()(address)' evmstate:format='address'/>"
                    "<Notional"
                        " evmstate:calls='notional()(uint256);currency()(string)'"
                        " evmstate:formats='decimal;string'"
                        " evmstate:scales='2;'"       // 2 decimals for notional, no scaling for currency
                        " evmstate:targets=';currency'/>"
                    "<MaturityDate evmstate:call='maturityDate()(uint256)' evmstate:format='iso8601-date'/>"
                    "<Active evmstate:call='active()(bool)' evmstate:format='boolean'/>"
            "</Instrument>";
    }

    /// @inheritdoc IRepresentableStateVersioned
    function stateVersion() external view override returns (uint256) {
        return _stateVersion;
    }

    /// @inheritdoc IRepresentableStateHashed
    function stateHash() external view override returns (bytes32) {
        // Canonical encoding of the state relevant to the XML representation.
        return keccak256(abi.encode(owner, notional, currency, maturityDate, active));
    }
}

Security Considerations

  • Non-pure view functions: If a contract uses view functions that depend on non-deterministic environment variables (e.g., block.timestamp, block.number) or external calls, the XML representation at a given block may not be stable. Implementations SHOULD restrict bindings to pure or effectively pure getters.

  • Template size and complexity: Large XML templates or a very high number of bindings may result in expensive eth_call operations or timeouts, especially on public RPC endpoints. Implementations SHOULD keep templates reasonably small and avoid unnecessary bindings.

  • Misrepresentation: This ERC cannot prevent a malicious contract from claiming to be XML-complete while omitting relevant state from its XML representation. Users and auditors MUST not rely on the XML alone for safety and SHOULD review the contract code and, where necessary, the stateHash() encoding if provided.

  • Renderer correctness: The security and correctness of the final XML representation depend on the correctness of the off-chain renderer. Independent implementations and tests are recommended.

  • Event references: When events carry references into representable state, off-chain consumers MUST correctly map these references (for example, by resolving URIs and using the correct block tag). Misinterpretation of references can lead to incorrect downstream processing even if the underlying on-chain representation is sound.