Generalized Contract-Linked Services
Welcome to ERC-7656, a finalized Ethereum standard that defines a factory capable of deploying generic services linked to specific contracts, such as ERC-4337 accounts or ERC-721 tokens (NFTs). These linked services extend the functionalities of the target contract, operating under the ownership of the contract's or NFT's owner without requiring modifications to the original contract's code.
Building upon the foundation laid by ERC-6551, ERC-7656 introduces a more flexible and generalized approach that enables extending existing contracts with new capabilities while maintaining backward compatibility with deployed instances.
ERC-6551 set the stage by enabling NFTs to have associated smart contract accounts, effectively giving NFTs their own wallets. This breakthrough allowed for more dynamic interactions and functionalities. However, existing projects like token-bound accounts have two key limitations:
ERC-7656 proposes a more versatile factory specification that enables the deployment of proxies pointing to any contract that enhances the associated contract's capabilities, whether it's an NFT or an account contract.
ERC-7656 reimagines the way contracts interact with services by removing unnecessary restrictions and embracing flexibility. Here's how:
mode parameter enables different linkage types (with or without token IDs) while ensuring consistent deterministic addressing.mode parameter while ensuring consistent deterministic addressing.The Ethereum ecosystem has witnessed a rapid increase in the number of ERC standards, each aiming to introduce new functionalities or address specific use cases. While innovation is essential, it's important to distinguish between two different approaches. For clarity, we'll use NFTs as our primary example throughout this section, but these principles apply equally to ERC-4337 accounts, and any other contract type where ERC-7656 is applicable.
ownerOf(), transferFrom(), or approve() need different signatures or behaviors.By using ERC-7656 services for functional extensions, developers can:
Conclusion:
ERC-7656 doesn't discourage ERC creation—it encourages thoughtful decision-making about when to extend functionality versus when to modify core behavior. Use ERC-7656 services for functional extensions that don't require core contract behavior changes (whether for NFTs, ERC-4337 accounts, ERC-1155 tokens, or any other contract type), and create new ERCs only when fundamental modifications to contract standards are necessary. This approach maintains the integrity of existing standards while enabling unlimited innovation through linked services across all contract types.
The following summarizes the core technical specification of ERC-7656. The complete specification is available in the official EIP.
Any ERC-7656 factory MUST implement the IERC7656Factory interface. The interface ID is 0x9e23230a.
interface IERC7656Factory {
event Created(
address contractAddress,
address indexed implementation,
bytes32 salt,
uint256 chainId,
bytes12 mode,
address indexed linkedContract,
uint256 indexed linkedId
);
error CreationFailed();
function create(
address implementation,
bytes32 salt,
uint256 chainId,
bytes12 mode,
address linkedContract,
uint256 linkedId
) external returns (address);
function compute(
address implementation,
bytes32 salt,
uint256 chainId,
bytes12 mode,
address linkedContract,
uint256 linkedId
) external view returns (address service);
}
create deploys a new linked service (an ERC-1167 minimal proxy) and returns its address. It MUST revert with CreationFailed if deployment fails. compute returns the deterministic address of the service without deploying it, so addresses can be computed off-chain or before deployment.
The mode parameter selects how the linked contract is interpreted. ERC-7656 defines two standard modes:
bytes12 constant NO_LINKED_ID = 0x000000000000000000000001; bytes12 constant LINKED_ID = 0x000000000000000000000000;
linkedId parameter is still present for interface consistency but SHOULD be zero unless used for service-specific data.
The 12-byte mode allows future extensions (e.g. other linkage patterns) without changing the interface.
Each linked service MUST be deployed as an ERC-1167 minimal proxy with immutable data appended to the bytecode. The structure is:
ERC-1167 Header (10 bytes) implementation (address) (20 bytes) ERC-1167 Footer (15 bytes) salt (bytes32) (32 bytes) chainId (uint256) (32 bytes) mode (bytes12) (12 bytes) linkedContract (address) (20 bytes) linkedId (uint256) (32 bytes) Total: 183 bytes
Linked services SHOULD implement IERC7656Service so that the link data can be read by integrators and other contracts. The interface ID is 0x7e110a1d.
interface IERC7656Service {
function linkedData() external view
returns (uint256 chainId, bytes12 mode, address linkedContract, uint256 linkedId);
}
linkedData() returns the four immutable values appended to the proxy bytecode at deployment: chainId, mode, linkedContract, and linkedId. Implementations typically read these by using extcodecopy to read the last 96 bytes (0x60) of the contract's bytecode and decoding them. This allows the service to know which contract and (for NFTs) which token ID it is linked to, and on which chain it was deployed.
When implementing a linked service, developers SHOULD consider the following patterns (see the EIP for full details):
LINKED_ID, the ownerOf(tokenId) on the linked contract).mode to handle NFT-linked (LINKED_ID) vs account-linked (NO_LINKED_ID) cases correctly (e.g. resolving "owner" from the NFT vs from the account contract).block.chainid matches the stored chainId to avoid cross-chain replay or misuse.ERC-7656 has an official reference implementation available on GitHub:
The following bytecode has been deployed:
0x608060405234801561001057600080fd5b5061030b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806301ffc9a7146100465780632ae81fb11461006e578063b4cb3cbb14610099575b600080fd5b61005961005436600461021a565b6100ac565b60405190151581526020015b60405180910390f35b61008161007c366004610267565b6100e3565b6040516001600160a01b039091168152602001610065565b6100816100a7366004610267565b610152565b60006001600160e01b03198216634f11918560e11b14806100dd57506001600160e01b031982166301ffc9a760e01b145b92915050565b600060406024608c376e5af43d82803e903d91602b57fd5bf3606c5286605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495282841760cc528160ec5260ff60005360b76055206035523060601b6001528560155260556000208060601b60601c60005260206000f35b600060406024608c376e5af43d82803e903d91602b57fd5bf3606c5286605d52733d60ad80600a3d3981f3363d3d373d3d3d363d7360495282841760cc528160ec5260ff60005360b76055206035523060601b600152856015526055600020803b61020a578660b760556000f5806101d25763d786d3936000526004601cfd5b80606c52508460cc528284897f5d6f1b27222bf34d576ad575c1c8749e981db502da9cd2e96e6e5258938099056080606ca46020606cf35b8060601b60601c60005260206000f35b60006020828403121561022c57600080fd5b81356001600160e01b03198116811461024457600080fd5b9392505050565b80356001600160a01b038116811461026257600080fd5b919050565b60008060008060008060c0878903121561028057600080fd5b6102898761024b565b9550602087013594506040870135935060608701356001600160a01b0319811681146102b457600080fd5b92506102c26080880161024b565b915060a08701359050929550929550929556fea2646970667358221220a95345c2c3cc528a43338da1b7fd0be8b9ba8af6c1e486ed761e02824da252ce64736f6c63430008160033
Contract deployed to
0x76565d90eeB1ce12D05d55D142510dBA634a128F
Using the following salt:
0x7656000000000000000000000000000000000000000000000000000000001688
The deployment has been made on the following networks. More will come soon.
Notice that you can use it for your convenience, or deploy your own version where you prefer.
You can install ERC-7656 as a dependency via npm:
npm install erc7656 @openzeppelin/contracts
Look at the examples in the examples folder for inspiration.
The story of ERC-7656 begins with ERC-6551. When we first read about ERC-6551, we were working on the Cruna Protocol (later suspended) and we were immediately struck by its innovative approach to extending NFT functionality. We suggested to the ERC-6551 team that they could extend the ERC6551Registry to be more generic, allowing it to create any type of service linked to NFTs, not just token-bound accounts. This would enable seamless extension of NFT functionalities beyond just account capabilities.
The team's response was thoughtful and understandable: they were focused on keeping ERC-6551 as simple as possible, and a more generic version of the registry might create confusion for implementers and users of token-bound accounts. Their priority was to establish a solid foundation for token-bound accounts specifically.
At some point, Jayden Windle (@jaydenwindle) suggested that we create a new proposal. With his blessing and encouragement, we decided to pursue this idea as ERC-7656.
As we developed the proposal, we realized that with a small modification, it could be used to link generic services not only to contracts with IDs (like NFTs) but to a much broader set of contracts, including ERC-4337 smart accounts. This expanded the scope significantly and made ERC-7656 a truly universal solution for contract extension.
In drafting the ERC, we maintained all references to ERC-6551 until we had to move to Last Call. At that point, the EIP reviewers informed us that we could not move an ERC to Last Call (the step before finalization) while referencing another ERC that was not yet final. This required us to remove the direct references and use more generic references to token-bound accounts instead.
We want to be clear: we do not claim to have created ERC-7656 from scratch. ERC-7656 builds directly upon the groundbreaking work of ERC-6551. Here, we would like to explicitly thank all the contributors to ERC-6551:
We would like to give special recognition to Jayden Windle and vectorized, who worked on the ERC-6551 reference implementation. Their code served as the foundation that we modified to create the ERC7656Factory reference implementation.
ERC-7656 stands on the shoulders of ERC-6551, and we are grateful to the entire ERC-6551 community for their pioneering work that made this proposal possible.
ERC-7656 is a finalized standard—a unified approach to extending any contract type with new capabilities. By supporting both NFTs and smart accounts, ERC-7656 creates a standardized way to enhance existing contracts without modification. We invite developers to collaborate, share ideas, and contribute to the evolution of contract extension technology.
Whether you're working with NFTs, ERC-4337 accounts, or other contract types, your insights and contributions are invaluable. Join the discussion, contribute to the codebase, or start building with ERC-7656 today.
Join the Discussion Read the Proposal