Everything You Need to Know About Diamonds on Ethereum
Diamond Smart Contracts is the new term circling the crypto and decentralized space! A diamond refers to a smart contract system where functionality and storage are split up into separate contracts.
The Diamond Standard is a pattern for upgradeability that overcomes existing limitations around storage and contract size, as well as provides exceptional modularity. We believe that the Diamond Standard will become the de-facto approach to smart contract upgradeability, an area that has not seen extensive improvement in several years.
In this blog, we’re taking a look at what Diamonds are and how it overcomes the limitations of the current smart contract standards. Let’s get started!
What is the EIP 2535 Diamond?
The EIP-2535 Diamonds is a way to organize your Solidity code and contracts to give them the right amount of modularity and cohesion for your system. In addition, flexible upgrade capability is a vital part of it.
A diamond is a smart contract that uses the external functions of other contracts as its own. The contracts that a diamond uses for its external functions are called facets.
A diamond has a mapping inside it that associates functions to contracts (facets) that have those functions. When an external function is called on a diamond the diamond looks in the mapping to find the facet to retrieve the function from and execute. A diamond is implemented according to EIP-2535 Diamonds. That way tools can be used with them and it is easier to understand and work with people’s contracts because they follow the standard.
Let’s take a look at a diagram that shows a simple diamond:
The diagram above shows the DiamondStorage structs in the diamond. All contract storage data is indeed stored in the diamond, not in its facets. But the struct definitions exist in the facet source code. Or the struct definitions can exist in separate solidity files or Solidity libraries that are imported by facets, or the struct definitions can be in a contract that is inherited by multiple facets.
Why Diamonds?
If you plan to build a system that can grow or change over time then a diamond is a good choice because it enables a system to grow in a systematic, organized way. Here’s a list of issues that Diamond aims to address:
- The maximum size a smart contract can be on Ethereum is 24kb. However, sometimes larger smart contracts are needed or desired. Diamonds solve the problem of size limits in smart contracts.
- Provides a structure to systematically and logically organize and extend larger smart contract systems so they don’t turn into a spaghetti code mess.
- Provides fine-grained upgrades. Other upgrade approaches require replacing functionality in bulk. With a diamond, you can add, replace, or remove just the functionality that needs to be added, replaced, or removed without affecting or touching other smart contract functionality.
- Provides a single address for a lot of smart contract functionality. This makes integration with smart contracts and user interfaces and other software easier.
More on Diamond Storage
A key part of the Diamond Standard is how it helps you with contract storage. It introduces a new storage technique called Diamond Storage. It is a new technique because until recently it wasn’t possible to do.
- Create a contract. This is a Diamond Storage contract but let’s call it a “storage contract” because that is shorter.
- Create a struct in the storage contract that contains the state variables you care about.
- Choose a position in storage to read and write your struct.
- Write a function in the storage contract that creates a storage pointer for the struct and returns it.
- Any contract/proxy/facet that needs to read/write the state variables defined in the storage contract just needs to inherit the storage contract and call the function that returns the storage pointer.
Why is Diamond Storage Good?
Proxy contracts can’t use Solidity’s default storage layout. As a result, people have resorted to three different ways to handle storage layout, namely – Unstructured Storage, Inherited Storage, and Eternal Storage. Each of these ways has downsides. Diamond Storage is good because it doesn’t have the downsides of the other ways.
Diamond Storage has a nicer syntax for state variables. And using a local storage pointer makes it explicit that state variables are being read and written to. Diamond Storage works with structs that can contain multiple simple values, arrays, mappings, and other structs.
Proxy contracts, diamonds, and facets only need to inherit the Diamond Storage contracts that contain the state variables that they use. This is cleaner. Diamond Storage decouples facets and proxy contracts.
Diamond Storage only has one getter function that returns a storage pointer to a struct that can contain any number of values. The storage pointer is used directly to read and write values to storage. It works with structs that can contain multiple simple values, arrays, maps, and other structs.
The Downside
Amongst all the pros, there are also a few cons to the Diamond smart contracts which are listed below.
- More Complexity
- Harder to maintain
- Not many big real-life projects yet
- Not supported by tools like Etherscan
Conclusion
Sometimes immutability is good, and sometimes what you need is transparency. Transparency can ensure that only non-malicious and tested upgrades take place. The Diamond Standard is definitely an improvement over EIP-1538. It has the same idea: To map single functions for a delegatecall to addresses, instead of proxying a whole contract through.
The bottom line is diamonds are still bleeding edge and not a finalized or widely used standard. If you want to take advantage of the additional features of diamonds, this is a perfectly reasonable alternative now. Plus any custom functionality could be added with more facets! Diamonds might see more usage in the future once contract systems require more sophistication and tools are supporting them.
About ImmuneBytes
We at ImmuneBytes offer enterprises and startups comprehensive smart contract auditing solutions for their applications to have a secure commencement. Our journey begins with an aim to foster security in the upcoming blockchain world, improving the performance of large-scale systems.
ImmuneBytes administers stern smart contract audits, employing static and dynamic analysis and examining a contract’s code and gas optimization, leaving no escape route for bugs.