• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    Solidity
  • License
    MIT License
  • Created over 3 years ago
  • Updated 9 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

EIP-2535 Diamond reference implementation using Hardhat and Solidity 0.8.*

Diamond-1-Hardhat Implementation

This is a reference implementation for EIP-2535 Diamonds. To learn about other implementations go here: https://github.com/mudgen/diamond

Note: The loupe functions in DiamondLoupeFacet.sol MUST be added to a diamond and are required by the EIP-2535 Diamonds standard.

Note: In this implementation the loupe functions are NOT gas optimized. The facets, facetFunctionSelectors, facetAddresses loupe functions are not meant to be called on-chain and may use too much gas or run out of gas when called in on-chain transactions. In this implementation these functions should be called by off-chain software like websites and Javascript libraries etc., where gas costs do not matter.

Installation

  1. Clone this repo:
git clone [email protected]:mudgen/diamond-1-hardhat.git
  1. Install NPM packages:
cd diamond-1-hardhat
npm install

Deployment

npx hardhat run scripts/deploy.js

How the scripts/deploy.js script works

The scripts/deploy.js deployment script includes comments to explain how it works.

How a diamond is deployed is not part of the EIP-2535 Diamonds standard. This implementation shows an example.

Run tests:

npx hardhat test

Upgrade a diamond

Check the test/diamondTest.js file for examples of upgrades.

Note that upgrade functionality is optional. It is possible to deploy a diamond that can't be upgraded, which is a 'Single Cut Diamond'. It is also possible to deploy an upgradeable diamond and at a later date remove its diamondCut function so it can't be upgraded any more.

Note that any number of functions from any number of facets can be added/replaced/removed on a diamond in a single transaction. In addition an initialization function can be executed in the same transaction as an upgrade to initialize any state variables required for an upgrade. This 'everything done in a single transaction' capability ensures a diamond maintains a correct and consistent state during upgrades.

Facet Information

Note: In this implementation the loupe functions are NOT gas optimized. The facets, facetFunctionSelectors, facetAddresses loupe functions are not meant to be called on-chain and may use too much gas or run out of gas when called in on-chain transactions. In this implementation these functions should be called by off-chain software like websites and Javascript libraries etc., where gas costs do not matter as much.

However the facetAddress loupe function is gas efficient and can be called in on-chain transactions.

The contracts/Diamond.sol file shows an example of implementing a diamond.

The contracts/facets/DiamondCutFacet.sol file shows how to implement the diamondCut external function.

The contracts/facets/DiamondLoupeFacet.sol file shows how to implement the four standard loupe functions.

The contracts/libraries/LibDiamond.sol file shows how to implement Diamond Storage and a diamondCut internal function.

The scripts/deploy.js file shows how to deploy a diamond.

The test/diamondTest.js file gives tests for the diamondCut function and the Diamond Loupe functions.

How to Get Started Making Your Diamond

  1. Reading and understand EIP-2535 Diamonds. If something is unclear let me know!

  2. Use a diamond reference implementation. You are at the right place because this is the README for a diamond reference implementation.

This diamond implementation is boilerplate code that makes a diamond compliant with EIP-2535 Diamonds.

Specifically you can copy and use the DiamondCutFacet.sol and DiamondLoupeFacet.sol contracts. They implement the diamondCut function and the loupe functions.

The Diamond.sol contract could be used as is, or it could be used as a starting point and customized. This contract is the diamond. Its deployment creates a diamond. It's address is a stable diamond address that does not change.

The LibDiamond.sol library could be used as is. It shows how to implement Diamond Storage. This contract includes contract ownership which you might want to change if you want to implement DAO-based ownership or other form of contract ownership. Go for it. Diamonds can work with any kind of contract ownership strategy. This library contains an internal function version of diamondCut that can be used in the constructor of a diamond or other places.

Calling Diamond Functions

In order to call a function that exists in a diamond you need to use the ABI information of the facet that has the function.

Here is an example that uses web3.js:

const myUsefulFacet = new web3.eth.Contract(MyUsefulFacet.abi, diamondAddress);

In the code above we create a contract variable so we can call contract functions with it.

In this example we know we will use a diamond because we pass a diamond's address as the second argument. But we are using an ABI from the MyUsefulFacet facet so we can call functions that are defined in that facet. MyUsefulFacet's functions must have been added to the diamond (using diamondCut) in order for the diamond to use the function information provided by the ABI of course.

Here is another example that uses hardhat:

const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress)

Similarly you need to use the ABI of a facet in Solidity code in order to call functions from a diamond. Here's an example of Solidity code that calls a function from a diamond:

string result = MyUsefulFacet(address(diamondContract)).getResult()

Get Help and Join the Community

If you need help or would like to discuss diamonds then send me a message on twitter, or email me. Or join the EIP-2535 Diamonds Discord server.

Useful Links

  1. EIP-2535 Diamonds
  2. Introduction to the Diamond Standard, EIP-2535 Diamonds
  3. EIP2535 Diamonds Documentation
  4. Awesome Diamonds

Author

This example implementation was written by Nick Mudge.

Contact:

License

MIT license. See the license file. Anyone can use or modify this software for their purposes.

More Repositories

1

awesome-diamonds

A curated list of awesome EIP2535 Diamonds resources, libraries, tools, articles and more
341
star
2

diamond

Information about three diamond reference implementations.
257
star
3

diamond-3

EIP-2535 Diamonds reference implementation.
Solidity
254
star
4

diamond-3-hardhat

EIP-2535 Diamond reference implementation using Hardhat and Solidity 0.8.*
Solidity
234
star
5

runcss

A utility-first CSS runtime for rapid UI development.
TypeScript
108
star
6

diamond-2-hardhat

Gas-optimized EIP-2535 Diamond reference implementation using Hardhat and Solidity 0.8.*
Solidity
92
star
7

webscript

Webscript is a Javascript library for creating DOM elements. Use it to create web applications. It is like HTML but it is Javascript. It is designed to work with existing libraries.
JavaScript
86
star
8

diamond-1

EIP-2535 Diamonds reference implementation.
Solidity
30
star
9

diamond-2

Gas-optimized EIP-2535 Diamonds reference implementation.
Solidity
27
star
10

quickswap

Decentralized trading protocol on Matic Network.
Solidity
19
star
11

transparent-contracts-erc1538

Reference implementation of ERC1538
JavaScript
17
star
12

diamond-foundry

A reference implementation of EIP2535 Diamonds using Foundry
Solidity
12
star
13

emoji-token

💎 Token
Solidity
10
star
14

governance-token-diamond

An ERC20 governance token diamond that can be used to govern a project as well as itself.
Solidity
10
star
15

diamond-util

Javascript library for deploying and upgrading diamonds.
JavaScript
8
star
16

contracts-starter

Template for starting smart contract repos
JavaScript
8
star
17

diamond-docs

Documentation for EIP2535 Diamonds
Python
6
star
18

mokens-bug-bounty

Bug Bounty Program for Mokens Contract
6
star
19

ethers-ledger

TypeScript
5
star
20

jobboard

Clojure
5
star
21

erc998.org

Website for ERC998
HTML
4
star
22

personal-diamonds

Personal diamond
4
star
23

Telecommute-Job-Board

Free Job Board for telecommute technology jobs.
Ruby
3
star
24

ethereum-to-matic

Bridging ERC20 tokens from Ethereum to Matic Network
Solidity
3
star
25

quickswap-contracts

Solidity
3
star
26

deno-postcss

Port of postcss to deno.
JavaScript
2
star
27

SimpleCache

A Simple PHP Caching System
PHP
2
star
28

viv

Library for creating web applications in the browser.
JavaScript
2
star
29

denotailcss

Port of Tailwind CSS to deno.
JavaScript
1
star
30

hardhat-fork-test

Testing hardhat forks
JavaScript
1
star
31

matic-uniswap

Uniswap on Matic Network
1
star
32

quickswap-snapshot

Solidity
1
star
33

ideas

Some ideas
1
star
34

personal-diamonds-client

JavaScript
1
star