--- eip: 7970 title: Stateless Encrypted Communication description: A log-based protocol for encrypted communication between two addresses on EVM chains. author: Scott Ewing (@sewing848) discussions-to: https://ethereum-magicians.org/t/erc-stateless-encrypted-communication-standard/24554 status: Draft type: Standards Track category: ERC created: 2025-06-10 requires: 165 --- ## Abstract This ERC defines a minimal, non-financial, gas-efficient communication protocol. It enables encrypted peer-to-peer communication through a single emitted event. The protocol maintains no on-chain state and avoids economic constructs. It assumes that encrypted communication is established off-chain. All message semantics are interpreted and enforced off-chain by client applications. ## Motivation Rather than defining a full messaging protocol, this ERC defines a minimal interface for sending encrypted messages on-chain. It does not prescribe how messages are encrypted, how keys are managed, or how sessions are handled. Those choices are left entirely to client applications. Existing systems often rely on contract state, token-based interactions, or application-specific logic. This proposal avoids those assumptions and instead defines a simple event-based mechanism that can be used by a wide range of messaging designs. This ERC defines a basic interface that: - Supports encrypted communication between two addresses. - Emits a single event for all messages. - Leaves message interpretation to off-chain clients. Applications can build more complex behavior—such as key exchange, session management, or spam control—on top of this interface without requiring changes to the contract. ### Related EIPs [ERC-3722: Poster](./eip-3722.md) enables on-chain message publication but focuses on plaintext broadcast rather than encrypted peer-to-peer communication. [ERC-7627: Secure Messaging Protocol](./eip-7627.md) defines a messaging interface that includes on-chain key management and session structure. By contrast, this proposal does not standardize protocol behavior and instead provides a minimal transport layer for encrypted messages. ## 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. ### Contract Interface Implementations of this protocol MUST define an event named `MessageSent` that is emitted when `sendMessage()` is called. The `MessageSent` event MUST contain `address indexed from`, `address indexed to`, `uint256 indexed messageType`, and `bytes data` in that order. Implementations MUST define a public function named `name()` that returns a human-readable identifier for the contract. To promote compatibility and discoverability, the contract interface shown below is RECOMMENDED: ```solidity interface IERC7970 is IERC165 { function name() external view returns (string memory); function sendMessage(address to, uint256 messageType, bytes calldata data) external; event MessageSent(address indexed from, address indexed to, uint256 indexed messageType, bytes data); } ``` - `from`: the sender of the message - `to`: the intended recipient - `messageType`: a message classifier - `data`: the message data (not interpreted on-chain) It is RECOMMENDED to include [ERC-165](./eip-165.md) support for interface detection. ```solidity function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC7970).interfaceId || super.supportsInterface(interfaceId); } ``` ### Message Type Semantics The `messageType` field is included as an indexed classifier to support efficient filtering of `MessageSent` events using standard RPC methods such as `eth_getLogs` and `eth_subscribe`. This allows clients to distinguish between categories of messages without inspecting the `data` field, while preserving the minimal design of this ERC. The meaning of `messageType` values is defined by each application. ## Rationale This ERC is designed to support messaging applications that can run entirely on user devices and public blockchains, without relying on application-specific servers or cloud storage. To achieve that goal, the on-chain component must remain minimal. The contract only emits events and stores no state. All key exchange, encryption, session handling, and message interpretation are performed off-chain by client applications. The `messageType` field provides a simple way for clients to filter and route messages using standard RPC methods. The contract does not interpret or enforce message structure. Applications are free to define their own protocols within the `data` field while sharing a common on-chain transport. Adding features on-chain, such as key registries, session tracking, or message validation, would increase gas costs and reduce flexibility. These concerns can be handled off-chain. This design also reduces the need for ongoing infrastructure and maintenance. Applications built on this standard do not require dedicated servers or backend services to operate. As a result, they can be simpler to deploy, easier to maintain, and more accessible to independent developers. The primary benefit of this approach is not improved privacy, but greater resistance to censorship. Messages can be sent across any EVM-compatible chain using a wide range of nodes. Applications may also use multiple chains or split messages into parts. This makes it harder to block communication than systems that depend on centralized servers or cloud providers. ## Backwards Compatibility This ERC introduces a new interface and does not modify or conflict with existing standards. ## Reference Implementation ```solidity // SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.30; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; /// @dev This interface MAY be used with ERC-165 for discoverability. /// @dev Supporting ERC-165 is RECOMMENDED but NOT REQUIRED. interface IERC7970 is IERC165 { /// @notice A short name to identify the contract implementation /// @return The name of the contract function name() external view returns (string memory); /// @notice Sends a message from the caller to the specified address /// @param to The address to receive the message /// @param messageType The type of message function sendMessage(address to, uint256 messageType, bytes calldata data) external; /// @notice Emitted when a message is sent /// @param from The address from which message was sent /// @param to The address to which the message was sent /// @param messageType The message type event MessageSent(address indexed from, address indexed to, uint256 indexed messageType, bytes data); } /// @title Stateless Encrypted Communication Standard /// @notice A log-based protocol for encrypted communication between two addresses on EVM chains. /// @dev This contract does not store any state and emits all communication as logs. /// @dev All semantics are interpreted off-chain. contract ReferenceContract is IERC7970, ERC165 { /// @notice The name of the implementation string private constant NAME = "ReferenceContract"; /// @notice A short name to identify the contract implementation /// @return The name of the contract function name() external pure returns (string memory) { return NAME; } /// @notice Send a message of the given type to the specified recipient /// @param to The recipient address /// @param messageType The classifier of the message /// @param data The encrypted or structured payload function sendMessage(address to, uint256 messageType, bytes calldata data) external { emit MessageSent(msg.sender, to, messageType, data); } /// @notice Indicates support for the IERC7970 interface via ERC-165 /// @param interfaceId The interface identifier, as specified in ERC-165 /// @return true if the contract implements the specified interface function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC7970).interfaceId || super.supportsInterface(interfaceId); } } ``` ## Security Considerations This protocol defines a minimal on-chain transport. All encryption, key exchange, and identity management are handled off-chain by client applications. All messages are public and permanent once published on-chain. Anyone can view event logs, including sender and recipient addresses, message size, timing, and frequency. Message contents may be encrypted, but this metadata is always visible. This design provides strong censorship resistance. There is no central server to block, modify, or delete messages. However, it does not protect against metadata analysis, spam, or misuse. Applications must handle their own security. This includes encryption, key management, authentication, and message validation. Poor implementation at the application layer can compromise confidentiality or integrity. This approach is not suitable for all use cases. Systems that require strong metadata privacy, content deletion, or centralized control may be better served by other designs. ## Copyright Copyright and related rights waived via [CC0](../LICENSE).