# Introduction to the Diamond Standard, EIP-2535 Diamonds

**URL:** <https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505>\
**Category:** Guides and Tutorials\
**Tags:** proxies, design, upgrades\
**Created:** [July 15, 2021, 3:42am UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505 "2021-07-15T03:42:07Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [July 15, 2021, 3:42am UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/1 "2021-07-15T03:42:07Z")

</div>

> **[Introduction to the Diamond Standard, EIP-2535 Diamonds](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard)**
>
> Back in 2018 I was implementing an ERC721 token that could own/possess/control other ERC721 tokens and ERC20 tokens. To do this I was following ERC998 Composable Non-Fungible Token Standard, which is an extension of ERC721. I had to implement ERC721...

---

<div class="post-metadata">

**Author:** ![Steeve](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/steeve/32/3627_2.png) [@Steeve](https://forum.openzeppelin.com/u/Steeve)\
**Post date:** [July 21, 2021, 4:01pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/2 "2021-07-21T16:01:34Z")

</div>

Why are libraries not sufficient?

---

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [July 21, 2021, 4:56pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/3 "2021-07-21T16:56:49Z")

</div>

It depends on the circumstances. EIP-2535 Diamonds is used for multiple things: code organization, modularity, fine grained upgrades, reusable on-chain code, smart contract protocol extension, stable address without a limit of the number of external functions. It does not replace Solidity libraries.

---

<div class="post-metadata">

**Author:** ![Steeve](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/steeve/32/3627_2.png) [@Steeve](https://forum.openzeppelin.com/u/Steeve)\
**Post date:** [July 21, 2021, 5:16pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/4 "2021-07-21T17:16:36Z")

</div>

Correct me if I am wrong but I believe that libraries can do the following:

1. code organization, _yes libraries allow this_
2. modularity, _yes_
3. fine grained upgrades, _libraries and/ or contract can be upgraded with OZ but maybe not to the degree of Diamond_
4. reusable on-chain code, _the main reason libraries exist_

But not these:

1. smart contract protocol extension,
2. stable address without a limit of the number of external functions.

Edit: but I am looking for explaination that libraries can or cannot alleviate 24kb contract size limit. Please show me the where in docs this is shown

---

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [July 21, 2021, 6:44pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/5 "2021-07-21T18:44:45Z")

</div>

Yes, Solidity libraries can be used to help with these things.

EIP-2535 Diamonds is a general smart contract architecture for designing extensible smart contract systems. Solidity libraries are a programming language feature, not a contract architecture, though architectures could be designed that use them.

Solidity libraries are a tool for creating reusable deployed on-chain code. EIP-2535 Diamonds answers questions like this: How do I design an upgradeable smart contract system that can be easily extended in production without limit? It so happens that EIP-2535 Diamonds natively supports and solves some of the same problems that Solidity libraries do.

Solidity libraries work very nicely with diamonds, specifically using internal functions of Solidity libraries to share functions between facets. External functions from Solidity libraries can be used with diamonds too.

> Edit: but I am looking for explaination that libraries can or cannot alleviate 24kb contract size limit.

Solidity libraries can be used to alleviate the 24kb contract size limit but its ability to do so is limited. External functions defined in a contract generate bytecode. So if enough external functions are added to a contract then it will hit the 24kb contract size limit. A diamond can have practically an unlimited number of external functions. This enables deployed contract system to be extended without risk of hitting a technical limit in the future.

Using Solidity libraries to reduce bytecode size means reorganizing code to get around a technical limitation rather than reorganizing code to make it better or more organized. A developer may not want to organize her code based on a bytecode size limitation. On the other hand perhaps contract architectures can be designed that use Solidity libraries in a way that is nice and not likely to hit the bytecode size limit. EIP-2535 Diamonds is a solution like that: it uses delegatecall like Solidity libraries do.

---

<div class="post-metadata">

**Author:** ![DeepITM](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/deepitm/32/11484_2.png) [@DeepITM](https://forum.openzeppelin.com/u/DeepITM)\
**Post date:** [December 20, 2021, 3:26pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/6 "2021-12-20T15:26:02Z")

</div>

Hi!

I am looking into a smart contract structure that can be the foundation piece of a NFT based game, where one single NFT will have various attributes(character level, data, history etc.) and functions (level up, adjusting attributes, etc.). Is the EIP-2535 Diamond standard a good foundation piece for such usage?

LH

---

<div class="post-metadata">

**Author:** ![zomglings](https://avatars.discourse-cdn.com/v4/letter/z/73ab20/32.png) [@zomglings](https://forum.openzeppelin.com/u/zomglings)\
**Post date:** [December 21, 2021, 2:56pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/7 "2021-12-21T14:56:48Z")

</div>

My team worked on the smart contracts and on-chain operations for Crypto Unicorns ([https://cryptounicorns.fun](https://cryptounicorns.fun)), which uses EIP2535 proxies extensively. @Nick_Mudge works on the smart contracts for Aavegotchi, I believe. They also use the diamond standard extensively.

Diamond proxies are a great choice for games, especially, because game mechanics change over time and the diamond standard supports data/rules initialization and migrations directly in the standard.

The most important thing if you go with EIP2535 is to build good tooling around attaching/detaching facets to your core diamond contract, and introspecting on which contracts are serving which functionality.

---

<div class="post-metadata">

**Author:** ![zomglings](https://avatars.discourse-cdn.com/v4/letter/z/73ab20/32.png) [@zomglings](https://forum.openzeppelin.com/u/zomglings)\
**Post date:** [December 21, 2021, 3:00pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/8 "2021-12-21T15:00:09Z")

</div>

I think you could make a lot of this work with libraries, but the diamond standard comes with a lot of batteries included. Specifically, some diamond features I have used heavily in production:

1. Convenient initialization and migration of data in storage
2. The ability to attach and detach individual facet methods without having to implement and manage a separate method-level lock mechanism.

---

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [January 13, 2022, 11:45pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/9 "2022-01-13T23:45:30Z")

</div>

Yes. For example Aavegotchi has done this.

---

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [October 20, 2022, 2:12pm UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/10 "2022-10-20T14:12:10Z")

</div>

EIP-2535 Diamonds recently became a "Final" Ethereum smart contract standard.

---

<div class="post-metadata">

**Author:** ![Cainuriel](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/cainuriel/32/5410_2.png) [@Cainuriel](https://forum.openzeppelin.com/u/Cainuriel)\
**Post date:** [January 6, 2024, 12:57am UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/11 "2024-01-06T00:57:55Z")

</div>

What are functions between Facets called? If I want to use the owner function of `OwnershipFacet ` to limit access to a function.

I have been testing but it does not work. It returns me an empty address.  
I share code from my last test:

```auto
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./OwnershipFacet.sol";
library LibA {

struct DiamondStorage {
    address owner;
    bytes32 dataA;
    string testSring;
}

function diamondStorage() internal pure returns(DiamondStorage storage ds) {
    bytes32 storagePosition = keccak256("diamond.storage.LibA");
    assembly {
    ds.slot := storagePosition
    }
}
}

contract FacetA {

    function setDataA(bytes32 _dataA) external {
        LibA.DiamondStorage storage ds = LibA.diamondStorage();
        ds.dataA = _dataA;
    }

    function getDataA() external view returns (bytes32) {
        return LibA.diamondStorage().dataA;
    }

      function setStringData(string memory _string) external {
        LibA.DiamondStorage storage ds = LibA.diamondStorage();
        ds.testSring = _string;
    }

    function getStringData() external view returns (string memory) {
        if(msg. sender != getOwner()) revert("You are not the Owner");
        return LibA.diamondStorage().testSring;
    }

    // testing using a function from other Facet
    function getOwner() public view returns (address) {
        return OwnershipFacet(0x7D005138A26110bAd9075807Bb16B5527951074e).owner();
    }
}

```

The function is public to check what value it returns when it is deployed

---

<div class="post-metadata">

**Author:** ![Sufiyan](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/sufiyan/32/21656_2.png) [@Sufiyan](https://forum.openzeppelin.com/u/Sufiyan)\
**Post date:** [October 22, 2024, 11:13am UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/12 "2024-10-22T11:13:23Z")

</div>

The current approach of using function selectors alone (i.e., the first 4 bytes of the function's signature) limits the flexibility of the Diamond standard, as it treats functions with the same name but different parameters as identical. If the Diamond pattern were extended to include both the function selectors and their parameter types, it would allow for greater versatility by enabling the same function name to be used with different parameter sets, thus supporting function overloading directly within the proxy setup.

---

<div class="post-metadata">

**Author:** ![Nick\_Mudge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/nick_mudge/32/1636_2.png) [@Nick\_Mudge](https://forum.openzeppelin.com/u/Nick_Mudge)\
**Post date:** [October 11, 2025, 11:40am UTC](https://forum.openzeppelin.com/t/introduction-to-the-diamond-standard-eip-2535-diamonds/12505/13 "2025-10-11T11:40:06Z")

</div>

No, the function selectors that the Diamond Standard uses also includes the parameter types that are used by the function.
