Alert Source Discuss
⚠️ Draft Standards Track: ERC

ERC-8119: Parameterized Storage Keys

A format for parameterized string keys used in EVM key-value storage.

Authors Prem Makeig (@nxt3d)
Created 2025-01-06
Discussion Link https://ethereum-magicians.org/t/erc-8119-key-parameters-standard-format-for-parameterized-string-keys/27397

Abstract

This ERC defines standard formats for parameterized string keys used in EVM key-value storage. It supports two encodings: a slash/colon form for a single parameter (<key-label>/<key-parameter> or <key-label>:<key-parameter>) and a bracket form for one or more parameters (<key-label>[<key-parameter-1>][<key-parameter-2>]...).

Motivation

Many EVM-based smart contracts use key-value storage to store metadata where string keys may need to represent multiple instances or variations of the same metadata type. Without a standardized format for parameterized keys, different implementations use inconsistent formats, leading to interoperability issues and parsing difficulties.

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.

Key Format

String keys used in EVM key-value storage MAY include parameters to represent variations or instances of a metadata type. When keys include parameters, they MUST follow the format:

<key-label>/<key-parameter>   or   <key-label>:<key-parameter>

or:

<key-label>[<key-parameter-1>][<key-parameter-2>]...

Where:

  • <key-label>: MUST contain only printable ASCII characters except space, the forward slash character (/), the colon character (:), and the left bracket character ([). Concretely, allowed code points are 0x21-0x2E, 0x30-0x39, 0x3B-0x5A, and 0x5C-0x7E (letters, digits, and common punctuation), explicitly excluding control characters (0x00-0x1F), space (0x20), the slash character (0x2F), the colon character (0x3A), the left bracket (0x5B), and DEL (0x7F). The key-label identifies the type or category of metadata.
  • <key-parameter> in slash/colon form: MAY be any UTF-8 encoded string except one that begins with a space. The character immediately after / or : MUST NOT be space; parameters may contain spaces elsewhere (e.g., key/hello world). For parameter data that must start with a space, use a quoted encoding where the space is the first character inside the quote (e.g., quote/' space is the first character in the quote'). Parsing uses the first occurrence of / or : as the separator; all subsequent characters belong to the single parameter.
  • <key-parameter-n> in bracket form: each parameter MAY be any UTF-8 encoded string except ] (which is reserved as the closing delimiter).

Examples:

  • "registration/1" - ASCII key-label with numeric parameter
  • "registration:1" - Same as above, using colon separator
  • "user/alice" - ASCII key-label with ASCII parameter
  • "website/http://website.com" - Slash/colon form where parameter includes additional /
  • "name/María" - ASCII key-label with UTF-8 parameter (Spanish)
  • "description/说明" - ASCII key-label with UTF-8 parameter (Chinese)
  • "title/タイトル" - ASCII key-label with UTF-8 parameter (Japanese)
  • "label/Étiquette" - ASCII key-label with UTF-8 parameter (French with accent)
  • "user[alice]" - Bracket form with one parameter
  • "resource[chain][1][token][42]" - Bracket form with multiple parameters
  • "%gain/50" - Key-label with special character (percent)
  • "$price/100" - Key-label with special character (dollar sign)
  • "#tag/featured" - Key-label with special character (hash)
  • "quote/' space is the first character in the quote'" - Parameter data starting with space: use quotes; space is first character inside

Invalid formats:

  • "registration-1" (hyphen separator)
  • "registration1" (no separator)
  • "key/ value" (space immediately after separator)
  • "key label/value" (space in key-label)
  • "key[label" (missing closing bracket)
  • "key[]tail" (trailing text after bracket form parameter list)

These formats provide a clean, consistent way to represent parameterized keys while maintaining readability and compatibility with parsers.

Format Specification

For string keys used in EVM key-value storage (e.g., mapping(string => bytes) in Solidity, hash maps in Vyper, or equivalent structures in other EVM-compatible languages):

  1. The <key-label> MUST contain only printable ASCII characters (0x21-0x7E), excluding spaces, /, :, and [. This excludes control characters, space, /, :, [, and DEL.
  2. A key with parameters MUST use exactly one of the following encodings:
    • Slash/colon form: <key-label>/<key-parameter> or <key-label>:<key-parameter> (exactly one parameter)
    • Bracket form: <key-label>[<key-parameter-1>][<key-parameter-2>]... (one or more parameters)
  3. In slash/colon form, parsing uses the first occurrence of / or : as the separator; all remaining characters belong to the single parameter. The character immediately after the separator MUST NOT be space.
  4. In bracket form, the parser reads the label up to the first [, then reads one or more bracketed parameters in order. No trailing characters are allowed after the final ].

Rationale

The slash (/) and colon (:) separators were chosen for the single-parameter form because:

  • They provide clear, unambiguous separators that are easy to parse programmatically.
  • Using whichever comes first ensures one parse rule; both may appear in the parameter.
  • They are visually concise and user-friendly for casual or long text values, and avoid requiring a trailing ].
  • Excluding both from the label is not restrictive, since labels are intended to be ASCII/domain-friendly.
  • Disallowing a space immediately after the separator keeps parsing simple and avoids ambiguity; parameters with spaces elsewhere (e.g., key/hello world) remain valid.

The bracket form was added because:

  • It provides an explicit structure for one or more ordered parameters.
  • It allows applications to represent multi-parameter keys without custom encoding inside a single string.

Reserving /, :, and [ from <key-label> keeps both encodings unambiguous.

Backwards Compatibility

This ERC is fully backwards compatible. Existing implementations that do not use parameterized keys are unaffected. Implementations using non-standard parameter formats may continue to work but are encouraged to migrate to this standard format for better interoperability.

Test Cases

Valid Key Formats

  • "name" - Simple key without parameters
  • "registration/1" - Key with numeric parameter (slash)
  • "registration:1" - Key with numeric parameter (colon)
  • "registration/2" - Key with numeric parameter
  • "user/alice" - Key with ASCII string parameter (slash)
  • "user:alice" - Key with ASCII string parameter (colon)
  • "session/abc123" - Key with alphanumeric parameter
  • "website/http://website.com" - Slash/colon form parameter containing //
  • "name/María" - Key with UTF-8 parameter (Spanish)
  • "description/说明" - Key with UTF-8 parameter (Chinese)
  • "title/タイトル" - Key with UTF-8 parameter (Japanese)
  • "label/Étiquette" - Key with UTF-8 parameter (French with accent)
  • "key/value:with:colons" - Key with parameter containing colons
  • "key/one1 two2 three3" - Key whose single slash/colon-form parameter can be interpreted by an application as a list
  • "key/value/with/slashes" - Key with parameter containing additional / (parsed at first /)
  • "excerpt/Dan said \"hi: how are you?\"" - Key with quoted speech containing :
  • "quote/' space is the first character in the quote'" - Parameter starting with space: use quotes; space is first character inside
  • "user[alice]" - Bracket form with one parameter
  • "resource[chain][1][token][42]" - Bracket form with multiple parameters
  • "title[说明][日本語]" - Bracket form with UTF-8 parameters

Invalid Key Formats

  • "registration-1" - Uses hyphen instead of slash/colon
  • "registration1" - No separator
  • "key/ value" - Space immediately after separator (parameter must not start with space)
  • "key label/value" - Space in key-label (key-label must be ASCII with no spaces)
  • "key[label" - Unclosed bracket parameter
  • "key[]tail" - Trailing non-bracket content in bracket form
  • "key/param[extra]" - Mixed slash and bracket formats

Reference Implementation

The following is a Solidity reference implementation. This standard applies to all EVM-compatible languages (Solidity, Vyper, etc.) that support string-keyed storage.

pragma solidity ^0.8.25;
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

contract KeyParametersExample {
    mapping(string => bytes) private _metadata;

    constructor() {
        // Save three values
        setMetadata("registration/1", bytes("example1"));
        setMetadata("registration/2", bytes("example2"));
        setMetadata("registration/3", bytes("example3"));

        // Read them all back
        for (uint256 i = 1; i <= 3; i++) {
            string memory key = string(abi.encodePacked("registration/", Strings.toString(i)));
            bytes memory value = getMetadata(key);
            require(value.length != 0);
        }
    }

    function setMetadata(string memory key, bytes memory value) public {
        _metadata[key] = value;
    }

    function getMetadata(string memory key) public view returns (bytes memory) {
        return _metadata[key];
    }
}

Security Considerations

  • User-facing input: When keys are derived from user input, clients SHOULD validate <key-label> against the allowed ASCII range and reject labels containing spaces, /, :, or [ to avoid ambiguous or non-standard keys. For slash/colon form, clients SHOULD reject keys where the character immediately after the separator is space.
  • Bracket parsing: Clients that support bracket form SHOULD reject malformed inputs (for example unbalanced brackets, trailing characters after the final ], or mixed slash and bracket delimiters) to prevent parser divergence.

Copyright and related rights waived via CC0.

Citation

Please cite this document as:

Prem Makeig (@nxt3d), "ERC-8119: Parameterized Storage Keys [DRAFT]," Ethereum Improvement Proposals, no. 8119, January 2025. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-8119.