<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nick Mudge</title>
    <description>The latest articles on DEV Community by Nick Mudge (@mudgen).</description>
    <link>https://dev.to/mudgen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F360860%2Fa7c95bf9-ceb9-4f6f-ba08-d1cd3db83623.jpg</url>
      <title>DEV Community: Nick Mudge</title>
      <link>https://dev.to/mudgen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mudgen"/>
    <language>en</language>
    <item>
      <title>Understanding EIP-2535 Diamonds: The Future of Smart Contract Design</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Wed, 22 May 2024 17:42:32 +0000</pubDate>
      <link>https://dev.to/mudgen/understanding-eip-2535-diamonds-the-future-of-smart-contract-design-doh</link>
      <guid>https://dev.to/mudgen/understanding-eip-2535-diamonds-the-future-of-smart-contract-design-doh</guid>
      <description>&lt;p&gt;In the ever-evolving world of blockchain technology, Ethereum Improvement Proposals (EIPs) play a crucial role in advancing the capabilities and functionalities of the Ethereum network. One such significant proposal is EIP-2535 Diamonds. This proposal introduces a standard for organizing and managing complex smart contracts, offering unprecedented flexibility and scalability. In this blog post, we'll explore what EIP-2535 Diamonds are, their benefits, and how you can use them in your smart contract development.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is EIP-2535?
&lt;/h3&gt;

&lt;p&gt;EIP-2535, proposed by Nick Mudge in 2020, introduces the concept of "Diamonds," a modular and scalable architecture for smart contracts on the Ethereum blockchain. Unlike traditional smart contracts, which can become cumbersome and difficult to manage as they grow in complexity, Diamonds allow developers to break down their contracts into smaller, more manageable pieces called "facets."&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Components of EIP-2535
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Diamond Contract&lt;/strong&gt;: This is the core contract that acts as a hub, managing the various facets. It delegates function calls to the appropriate facet based on the function signature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Facets&lt;/strong&gt;: These are modular contracts that contain specific functionalities. A single Diamond can have multiple facets, each responsible for different parts of the overall logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Selectors&lt;/strong&gt;: Function selectors are used to route calls to the correct facet. The Diamond contract maintains a lookup table of function selectors to the corresponding facet addresses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Loupe Functions&lt;/strong&gt;: These are introspection functions that allow developers to query the Diamond for information about its facets and the functions they provide.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Benefits of EIP-2535
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modularity&lt;/strong&gt;: By breaking down a smart contract into smaller facets, developers can manage and update specific parts of the contract without affecting the entire system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: Diamonds enable the development of large and complex systems that can grow organically. New functionalities can be added by deploying new facets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Upgradeability&lt;/strong&gt;: Individual facets can be upgraded independently, allowing for flexible and seamless updates without redeploying the entire contract.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced Gas Costs&lt;/strong&gt;: Since only the facets that are updated need to be redeployed, the overall gas costs for contract upgrades can be significantly lower.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Organization&lt;/strong&gt;: By organizing code into facets, developers can keep their codebase clean and easier to navigate, enhancing maintainability.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Use EIP-2535 Diamonds
&lt;/h3&gt;

&lt;p&gt;Using EIP-2535 Diamonds involves several steps, from setting up your development environment to deploying and interacting with your Diamond contract. Here's a step-by-step guide:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Setting Up Your Environment
&lt;/h4&gt;

&lt;p&gt;First, ensure you have a development environment set up with tools like Hardhat or Truffle, and a coding editor like VSCode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; hardhat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Create Your Diamond Contract
&lt;/h4&gt;

&lt;p&gt;Create the Diamond contract that will act as the central hub. This contract includes the logic to delegate function calls to the appropriate facets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Diamond.sol
pragma solidity ^0.8.0;

import "./IDiamondCut.sol";

contract Diamond {
    // Diamond storage
    struct Facet {
        address facetAddress;
        bytes4[] selectors;
    }

    mapping(bytes4 =&amp;gt; address) public selectorToFacet;

    constructor(IDiamondCut.FacetCut[] memory _diamondCut) {
        // Implement diamond cut
    }

    fallback() external payable {
        address facet = selectorToFacet[msg.sig];
        require(facet != address(0), "Function does not exist");
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 {revert(0, returndatasize())}
            default {return(0, returndatasize())}
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Define Your Facets
&lt;/h4&gt;

&lt;p&gt;Create facet contracts that contain specific functionality. For example, you might have one facet for token management and another for governance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// TokenFacet.sol
pragma solidity ^0.8.0;

contract TokenFacet {
    mapping(address =&amp;gt; uint256) balances;

    function transfer(address to, uint256 amount) external {
        require(balances[msg.sender] &amp;gt;= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        balances[to] += amount;
    }

    function balanceOf(address account) external view returns (uint256) {
        return balances[account];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Deploy Your Diamond and Facets
&lt;/h4&gt;

&lt;p&gt;Deploy your Diamond contract and then the facet contracts. After deploying, you need to link the facets to the Diamond using the Diamond Cut mechanism.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Diamond&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Diamond&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diamond&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Diamond&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;diamond&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Diamond deployed to:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;diamond&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TokenFacet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TokenFacet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TokenFacet deployed to:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Add facets to the Diamond&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;diamond&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;diamondCut&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;facetAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Add&lt;/span&gt;
            &lt;span class="na"&gt;functionSelectors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;getSelectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;constants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AddressZero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Interact with Your Diamond
&lt;/h4&gt;

&lt;p&gt;Once deployed, you can interact with your Diamond contract. Calls to the Diamond will be routed to the appropriate facet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diamond&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Diamond&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;diamondAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContractAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TokenFacet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;diamondAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receiverAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;tokenFacet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;receiverAddress&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Balance:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A fully working and complete implementation of EIP-2535 Diamonds is here: &lt;a href="https://github.com/mudgen/diamond-1-hardhat"&gt;https://github.com/mudgen/diamond-1-hardhat&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To date more than 100 projects have used EIP-2535 Diamonds. A list is available here: &lt;a href="https://github.com/mudgen/awesome-diamonds?tab=readme-ov-file#projects-using-diamonds"&gt;https://github.com/mudgen/awesome-diamonds?tab=readme-ov-file#projects-using-diamonds&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;EIP-2535 Diamonds provide a powerful framework for building modular, scalable, and upgradeable smart contracts on Ethereum. By breaking down contracts into facets, developers can manage complex systems more effectively, reduce gas costs, and ensure seamless upgrades. Whether you are building decentralized finance (DeFi) applications, gaming platforms, or any other type of dApp, Diamonds offer a robust solution to the challenges of smart contract development. Start exploring EIP-2535 Diamonds today and take your blockchain projects to the next level!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to solve OpenSea's "We couldn’t find this contract." error for ERC721 Validation</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Tue, 01 Mar 2022 16:22:15 +0000</pubDate>
      <link>https://dev.to/mudgen/how-to-solve-openseas-we-couldnt-find-this-contract-during-erc721-validation-4lp2</link>
      <guid>https://dev.to/mudgen/how-to-solve-openseas-we-couldnt-find-this-contract-during-erc721-validation-4lp2</guid>
      <description>&lt;p&gt;You may have a perfectly valid ERC721 contract yet OpenSea gives you an error when you try to add your ERC721 contract to OpenSea.&lt;/p&gt;

&lt;p&gt;This is the URL for adding an ERC721 collection to OpenSea's testnet which uses Rinkeby: &lt;a href="https://testnets.opensea.io/get-listed/step-two"&gt;https://testnets.opensea.io/get-listed/step-two&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the error you can get:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We couldn't find this contract. Please ensure that this is a valid ERC721 or ERC1155 contract deployed on Rinkeby and that you have already minted items on the contract.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may get this error even if your contract is compliant with the ERC721 standard. A team from the &lt;a href="https://www.opinyour.com/"&gt;Opinyour project&lt;/a&gt; and myself  &lt;a href="https://dev.to/mudgen/how-to-debug-code-2850"&gt;debugged&lt;/a&gt; OpenSea's ERC721 validation and discovered what we think is the problem and a solution that works.&lt;/p&gt;

&lt;h2&gt;
  
  
  How OpenSea ERC721 Validation Works
&lt;/h2&gt;

&lt;p&gt;From behavior of OpenSea's ERC721 validation we discovered how OpenSea validates contracts as ERC721 or not. This investigation and discovery occurred on the Rinkeby network. Based on observed behavior this is how OpenSea ERC721 validation works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;OpenSea automatically monitors all new contracts that are deployed. The moment OpenSea detects a new contract has been deployed it calls &lt;code&gt;contract.supportsInterface(type(IERC721).interfaceId)&lt;/code&gt; on that contract. If the function call returns true then OpenSea adds it to its list or database of potential ERC721 contracts. If the function call returns false then OpenSea will not detect it as an ERC721 contract and any attempts at validation fails.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenSea checks during deployment and after deployment (for any contract that passes step 1 above) if any ERC721 Transfer events have been emitted from a contract. If not then any validation fails.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a contract passes step 1 and 2 then it will pass ERC721 validation on OpenSea's &lt;a href="https://testnets.opensea.io/get-listed/step-two"&gt;validation webpage&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When OpenSea ERC721 Validation Fails
&lt;/h2&gt;

&lt;p&gt;For a lot of contracts OpenSea's current ERC721 validation strategy works. But there are two cases that I know where OpenSea will fail to validate smart contracts that comply fully with the ERC721 standard. Here are the two cases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If OpenSea's infrastructure that processes newly deployed contracts on a blockchain stops working or develops a backlog then newly deployed ERC721 contracts will fail validation until OpenSea's monitoring infrastructure is working again or until the backlog of unprocessed contracts is handled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A proxy contract that is upgraded after deployment to support ERC721 can fail validation. The reason is because OpenSea validates contracts when they are deployed, but such contracts don't implement ERC721 until after they are deployed. See solutions to this below.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is an example of a scenario where ERC721 validation fails and how to get it working:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We deploy an &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP2535 diamond&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Right after deployment we upgrade the diamond to fully implement the ERC721 standard.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note: Introduction article to EIP2535 Diamonds here: &lt;a href="https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard"&gt;https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As mentioned before such a diamond contract can fail OpenSea ERC721 validation if OpenSea validates the diamond before the upgrade transaction adds the ERC721 functions. Also understand that it is possible for ERC721 validation to pass in this case if OpenSea has a blacklog of contracts to process and by the time it processes our diamond the upgrade transaction has been added to the blockchain.&lt;/p&gt;

&lt;p&gt;The very specific solution to this is to add the &lt;code&gt;supportsInterface(bytes4 _interfaceId)&lt;/code&gt; function to the diamond when it is deployed. This is easily done by adding the function to the diamond in the constructor function of the diamond. It could also be added directly to the diamond as an &lt;a href="https://eips.ethereum.org/EIPS/eip-2535#terms"&gt;immutable function&lt;/a&gt;. Also be sure that the function returns &lt;code&gt;true&lt;/code&gt; for the &lt;code&gt;type(IERC721).interfaceId&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;Here is a link to code that shows an example of adding the &lt;code&gt;supportsInterface&lt;/code&gt; function to a diamond in its constructor function: &lt;a href="https://gist.github.com/mudgen/fe2ee945446e64c56c9c11c1796c1f3b"&gt;https://gist.github.com/mudgen/fe2ee945446e64c56c9c11c1796c1f3b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because we now understand why validation fails and generally how to fix it (add supportsInterface function during deployment), there are a number of different ways to implement a solution. &lt;/p&gt;

&lt;p&gt;One solution is to add all the ERC721 functions to the diamond during deployment. It is possible to add the ERC721 functions to the diamond in the diamond's proxy constructor function.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Solidity: AppStorage for distinguishing state variables and preventing name clashes</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Thu, 13 Jan 2022 21:47:51 +0000</pubDate>
      <link>https://dev.to/mudgen/solidity-appstorage-for-distinguishing-state-variables-and-preventing-name-clashes-3lh</link>
      <guid>https://dev.to/mudgen/solidity-appstorage-for-distinguishing-state-variables-and-preventing-name-clashes-3lh</guid>
      <description>&lt;p&gt;Solidity state variables, immutable variables, constants, local variables and function names can look the same and it is possible to have name clashes, where for example a local variable or function name is named the same thing as a state variable, which can reduce code clarity and cause frustration.&lt;/p&gt;

&lt;p&gt;AppStorage is a variable naming technique which makes state variables clear in your code and prevents name clashes with other kinds of variables and function names.&lt;/p&gt;

&lt;p&gt;This is how it is done: Define a struct in a file and name the struct AppStorage. Define all the state variables in your application within the AppStorage struct.&lt;/p&gt;

&lt;p&gt;Then in your smart contracts import the AppStorage struct. Then define this state variable: &lt;code&gt;AppStorage internal s;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's it. Now you can access all your state variables by prepending an "s." to them.&lt;/p&gt;

&lt;p&gt;Here is a simple example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define AppStorage that contains all your state variables:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AppStorage.sol
&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;secondVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;firstVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;lastVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Import it and use it in contracts:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"./AppStorage.sol"&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;Staking&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;myFacetFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstVar&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secondVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>How Diamond Upgrades Work</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Fri, 14 May 2021 04:20:19 +0000</pubDate>
      <link>https://dev.to/mudgen/how-diamond-upgrades-work-417j</link>
      <guid>https://dev.to/mudgen/how-diamond-upgrades-work-417j</guid>
      <description>&lt;p&gt;To understand diamond upgrades, let's first understand how function calls work in contracts created by Solidity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Function Calls Work
&lt;/h2&gt;

&lt;p&gt;In order for a transaction to execute a function on a smart contract there needs to be a way for a transaction to specify to the contract what function to execute. This is done by a transaction supplying a four-byte value that identifies for a contract what function to execute.&lt;/p&gt;

&lt;p&gt;The four-byte value is called a function selector. It consists of the first four bytes of a hash of a string of a function signature.&lt;/p&gt;

&lt;p&gt;A function signature is a string that consists of a function name and the types of its arguments. Let's look at an example. Here's a function signature: &lt;code&gt;"transfer(address,uint256)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here we get the first four bytes of a hash of that function signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bytes functionSelector = bytes4(keccak256("transfer(address,uint256)"));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function selector is&lt;code&gt;0xa9059cbb&lt;/code&gt;. So if the first four bytes of transaction data is that value and the transaction is sent to a contract, then it tells that contract to execute the &lt;code&gt;"transfer(address,uint256)"&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Diamond Upgrades Work
&lt;/h2&gt;

&lt;p&gt;Diamonds store function selectors and contract addresses of contracts that have the functions that the function selectors identify. The contracts that diamonds use are called facets.&lt;/p&gt;

&lt;p&gt;A diamond has a mapping that maps function selectors to facet addresses.&lt;/p&gt;

&lt;p&gt;Adding functions to a diamond means adding function selectors to a diamond and adding the facet addresses of the facets that have the functions that the function selectors identify. &lt;/p&gt;

&lt;p&gt;Replacing functions means associating existing function selectors in a diamond with different facet addresses.&lt;/p&gt;

&lt;p&gt;Removing functions means removing function selectors and their facet addresses from the diamond.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;diamondCut&lt;/code&gt; function is used to upgrade diamonds. It has a &lt;code&gt;_diamondCut&lt;/code&gt; argument that consists of an array of function selectors and facet addresses and an action which specifies whether to add, replace or remove them. Here's an example of a value for the &lt;code&gt;_diamondCut&lt;/code&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    facetAddress: '0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82',
    action: 0,
    functionSelectors: [
      '0x4cd5d1f7',
      '0x24a6665e',
      '0x4113e5ca',
      '0x49aa1f27',
      '0x24d86f00',
      '0x2e0bcb43',
      '0xbec10cde',
      '0xa3ea00f1'
    ]
  },
  {
    facetAddress: '0x549549085493058324890438543949485a499A1b',                  
    action: 1,
    functionSelectors: [
      '0x45943954',
      '0xa4349495',
      '0x9684834e'
    ]
  }  
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above the action value of 0 means adding new functions.  The action value of 1 means replacing the functions by replacing the facet address for them.&lt;/p&gt;

&lt;p&gt;In Javascript scripts the FacetCutAction object can used to more explicitly show the action. Here is its definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const FacetCutAction = { Add: 0, Replace: 1, Remove: 2 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example of a Javascript script that creates the &lt;code&gt;_diamondCut&lt;/code&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const FacetCutAction = { Add: 0, Replace: 1, Remove: 2 }

  const newFuncs = [
    getSelector('function setSleeves(tuple(uint256 sleeveId, uint256 wearableId)[] calldata _sleeves) external'),
    getSelector('function updateSvg(string calldata _svg, tuple(bytes32 svgType, uint256[] ids, uint256[] sizes)[] calldata _typesAndIdsAndSizes) external')
  ]
  const existingFuncs = getSelectors(facet).filter(selector =&amp;gt; !newFuncs.includes(selector))

  const _diamondCut = [
    {
      facetAddress: facet.address,
      action: FacetCutAction.Add,
      functionSelectors: newFuncs
    },
    {
      facetAddress: facet.address,
      action: FacetCutAction.Replace,
      functionSelectors: existingFuncs
    }
  ]
  console.log(_diamondCut)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://github.com/aavegotchi/aavegotchi-contracts/tree/master/scripts/upgrades"&gt;AavegotchiDiamond has many upgrade scripts&lt;/a&gt;. Check them out for more code examples.&lt;/p&gt;

&lt;p&gt;You may want to initialize state after an upgrade. That is what the second and third arguments of the &lt;code&gt;diamondCut&lt;/code&gt; function are for. The &lt;code&gt;_init&lt;/code&gt; argument holds the contract address of a function to call to initialize the state of the diamond. The &lt;code&gt;_calldata&lt;/code&gt; argument holds a function call to send to the contract at &lt;code&gt;_init&lt;/code&gt;. The function call is executed with delegatecall so that the diamond's state is affected and can be initialized.&lt;/p&gt;

&lt;p&gt;Executing an initialization function by using the &lt;code&gt;_init&lt;/code&gt; and &lt;code&gt;_calldata&lt;/code&gt; arguments when making an upgrade means that the upgrade and state initialization are done in the same transaction. This is good because it prevents the diamond from getting into a bad or inconsistent state, which could possibly happen if an upgrade and state initialization are done in separate transactions.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Debug Code &amp; Debugging Techniques</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Sun, 02 May 2021 00:26:26 +0000</pubDate>
      <link>https://dev.to/mudgen/how-to-debug-code-2850</link>
      <guid>https://dev.to/mudgen/how-to-debug-code-2850</guid>
      <description>&lt;p&gt;You might not know that you can solve most of your software or coding problems yourself and it is important that you do so rather than seek help directly from others. So the first thing to become more aware of is that it is possible to solve your own coding problems, and for many coding problems you can solve them easily and quickly. You just need to know how and practice and get better at debugging. It can actually be fun and rewarding.&lt;/p&gt;

&lt;p&gt;It is important to know how to debug code. It is a skill that can be developed and improved. The more you debug code the better you get at it.  It is like a muscle, the more you flex it and use it the better and stronger and faster you get at it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is being good at debugging important?
&lt;/h3&gt;

&lt;p&gt;The old fish story is applicable here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your code doesn't work you could ask a senior developer about it. So the senior developer uses his time to look at, understand and debug your code for you. He finds the problem and gives you the solution. You learn from it. That's good. But a bit later your code stops working and so you ask the senior developer about it and the senior developer looks at it, understands and debugs your code and you learn from it. And the cycle repeats. You do learn this way but it is not a good way to learn. You are reliant on others when you get stuck. You are stuck and stopped and have to wait until someone else can help you. You can't do anything new without someone else to help you. You are using up the valuable time of a senior developer. You might be a developer that was hired to solve problems, not find or create problems for others to solve.  It doesn't have to be this way. If you are good at debugging then you can solve your own problems and be self-reliant. You will save tons of time and you won't be stopped when you start working on new things or using new technologies. The good thing is that debugging is a skill that you can learn and get better at.&lt;/p&gt;

&lt;p&gt;You might have excuses for not solving problems or successfully debugging things, or maybe others have given you excuses. You will have to give up excuses. Notice you have excuses, if you have them, and let them go. The more you work on your debugging skills and work on debugging things yourself, the better you will get at debugging and solving things.&lt;/p&gt;

&lt;p&gt;The benefit of being good at debugging goes beyond getting code to work. Debugging makes you more familiar with your code, other people's code, documentation and tools. Debugging increases your general knowledge and competency and confidence. All these things make you a better developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you actually debug?
&lt;/h3&gt;

&lt;p&gt;The primary, fundamental thing about code that is not running as expected is that it means you don't know something.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Debugging means finding out what you don't know so you can know it and get your code working right.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another way to say this is this: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Debugging is increasing your understanding with what you are working with so you make it work right.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Some people make random changes to code in hopes that it works now. That is not debugging. That's a waste of time. That indicates that a person doesn't understand the code in the first place, which is terrible. Nobody should be dealing with code they don't understand. The first step is to understand what you are dealing with. Anything that is done that helps you to understand more is valuable. Experimenting or changing code to see different outputs or results that helps you understand something better is valuable. Always aim for increasing your understanding. When you understand then you can solve with certainty.&lt;/p&gt;

&lt;p&gt;I'm going to separate debugging into two separate areas:  Lacking Knowledge and Oversight. &lt;/p&gt;

&lt;h3&gt;
  
  
  Lacking Knowledge
&lt;/h3&gt;

&lt;p&gt;Lacking knowledge means that your code isn't working because you lack knowledge about the tools you are using. There could be code in your script you don't understand, a smart contract you are interacting with that you don't understand or you don't understand something about the execution environment (Hardhat or nodejs) or a library you are using, or configuration or other software running with your script, such as Hardhat Network. Or maybe you don't understand the error message you are getting.&lt;/p&gt;

&lt;p&gt;The thing to do is increase your understanding of the code and tools you are using so you can use them correctly.&lt;/p&gt;

&lt;p&gt;Any tradesman, musician, mechanic, technical person is expected to know his/her tools. A programmer is no different. Take some time everyday, if you can, to learn more about your programming language, libraries, smart contract standards, smart contracts, programming editor/IDE and other tools. Read documentation and buy and read books about your tools. Watch videos if you like to learn that way.&lt;/p&gt;

&lt;p&gt;If your code throws an error then look at every part of the error and if there is an error message then ask yourself if you understand it or not. If you don't understand the error message then your next step is to find out what the error message means.&lt;/p&gt;

&lt;p&gt;If you understand what the error message means but still don't understand why it is being thrown then look through your code and see if there is any code you don't understand or might not understand. You should understand all the code in your scripts and if you don't you should take action to understand it.&lt;/p&gt;

&lt;p&gt;The best and easiest and most accurate way to learn about functions and features about your programming language and libraries and tools is to read the documentation about them. &lt;/p&gt;

&lt;p&gt;Documentation is your best friend. For something you don't understand read the documentation about it. Here are the documentation sources for the tools and software we use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Javascript: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;nodejs: &lt;a href="https://nodejs.org/en/docs/"&gt;https://nodejs.org/en/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hardhat: &lt;a href="https://hardhat.org/getting-started/"&gt;https://hardhat.org/getting-started/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ethersjs: &lt;a href="https://docs.ethers.io/v5/"&gt;https://docs.ethers.io/v5/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Solidity: &lt;a href="https://docs.soliditylang.org/en/v0.8.4/"&gt;https://docs.soliditylang.org/en/v0.8.4/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Polygon: &lt;a href="https://docs.matic.network/docs/develop/getting-started"&gt;https://docs.matic.network/docs/develop/getting-started&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Aavegotchi: &lt;a href="https://wiki.aavegotchi.com/"&gt;https://wiki.aavegotchi.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AavegotchiDiamond: &lt;a href="https://docs.aavegotchi.com/"&gt;https://docs.aavegotchi.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice that Stack Overflow and other forum software is not on this list. Usually the documentation from a project is better, more accurate, than other sources so first seek the documentation of a project.&lt;/p&gt;

&lt;p&gt;But sometimes what you need to understand or learn is not in the documentation of a project. That's when to use google or other search software and Stack Overflow and forums to find data that you need.&lt;/p&gt;

&lt;p&gt;Sometimes the documentation or information you need isn't found searching it on Google or on forums etc. So search the Github issues for the project. It is also possible to look at the source code of the project to understand or get the data you need. &lt;/p&gt;

&lt;p&gt;If you still can't find the data you need then there are a number of things you can do. You can create a github issue for the project.  You can find the discord server for the project and ask your questions there. &lt;/p&gt;

&lt;p&gt;If you still can't find the data you need then you can ask a senior developer. Don't say your code doesn't work and give little data. Ask for data that you need to solve and debug your own code.  If you ask for data that is already in the documentation then a senor developer is going to wonder why you are asking him/her about something that is already answered in the documentation. So if you can't find answers in the documentation then it is good to say so. You could say something like this:  "I could not find in the documentation [the question],  do you know where documentation is for this?"  If there isn't documentation for your question then it signals to the senior developer that he/she or someone should write documentation for that thing, which is useful.&lt;/p&gt;

&lt;p&gt;Going to a senior developer for things that are already answered in the documentation for a tool is wasting the senior developers time and is wasting the time and effort of the person who wrote the documentation to answer or solve your problems. In addition getting things hand fed from a senior developer doesn't strengthen your debugging muscle and makes you dependent on others. It might save time but it doesn't make you as good as you could be.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oversight
&lt;/h3&gt;

&lt;p&gt;Sometimes code doesn't work not so much because we don't understand tools but because of some little mistake in code that we missed. Syntax errors and logic errors are examples of this.  Sometimes these mistakes are very easy and fast to find and fix and sometimes they take longer to find and fix. The various debugging techniques can be used to find the source of code not working so it can be fixed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Debugging Techniques
&lt;/h1&gt;

&lt;p&gt;All debugging techniques should help you discover the cause for software not working correctly. It is not enough to just get software to run correctly. You need to understand why it wasn't working correctly.  You need to know the cause, source of it working incorrectly. Only then can you be sure that you really fix the problem so it doesn't happen again.&lt;/p&gt;

&lt;p&gt;Many debugging techniques help you find where in code a problem is. Once you know where in code a problem is you can focus your attention there to really understand the code there and find the source of a problem.&lt;/p&gt;

&lt;p&gt;There are many debugging techniques. These are some of them.  Please contact me about adding more if you have some good techniques.&lt;/p&gt;

&lt;h3&gt;
  
  
  Look at the Error Message
&lt;/h3&gt;

&lt;p&gt;If you get an error then look at the error message.  Often somewhere in the stack trace there is an error message that states what the error is. Use that. Also the error may say or indicate where in the code the error is.  Looking at and using error messages is one of the most common and first approaches for debugging something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Program a Little at a Time
&lt;/h3&gt;

&lt;p&gt;When working with unfamiliar code or tools it is important to program a little at a time. Write a small amount of code. It could be a few lines of code. Then run the code. Use some print or console.log() statements to the show the results of your code execution to prove to yourself that your code does what you expect. If  your code works then write a little more code and print out the results. If your code stops working correctly then you know where the problem is -- in the little amount of code you just wrote. Focus your attention on and increase your understand of that little bit of code you just wrote to find the source of the problem. &lt;/p&gt;

&lt;p&gt;If you are handed code or script you are unfamiliar with and it doesn't work and you don't know why then you can use the "program a little at a time" technique to debug it. Create a brand new, blank script to start from.  Copy a little amount of code from the start of the script you are debugging. Add some print/console.log statements and run the code. If it works then copy a little more code into your new script and run it. Keep doing this, little by little, until something breaks and then increasing your understanding of what breaks and fix it and continue programming little by little. &lt;br&gt;
Also, make sure you understand any code you copy into your script. Perhaps the biggest sin in programming is writing or copying code you don't understand. Don't do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Follow the Logic
&lt;/h3&gt;

&lt;p&gt;Sometimes code does not execute correctly because there is a logic error, meaning the code does something other than you think or expect. The way to solve this is to read the code of the script line by line starting at the beginning. Understand what each line does and see how each line logically follows the next line. This is executing a program in your mind.&lt;br&gt;
Sometimes running the program in your mind as you read it is enough to notice that the code does something that does not make sense. Sometimes it is not enough because you don't understand the code well enough to do that. When it isn't enough to execute it in your mind then you can add print or console.log statements to the code to show the output and progress of the script.  Check that the output corresponds to what you expect it to be. Prove to yourself that you understand what each line of code is doing by getting the expected output of print or console.log statements in your code. &lt;/p&gt;

&lt;p&gt;Your script may call code or functions from another script or from a library or a third-party smart contract. Sometimes it is necessary when following the logic to jump to the source code of another script or library or smart contract to follow the logic there. This is necessary because the bug may be in the script or library that you are using or you need to follow the logic there so you understand what the script or library or smart contract is doing and how it affects the code you are writing.&lt;/p&gt;

&lt;p&gt;Follow the logic can be used in combination with other debugging techniques like program a little at a time or divide or conquer.&lt;/p&gt;

&lt;p&gt;A debugger can be used to follow the logic.&lt;/p&gt;

&lt;p&gt;When things don't work follow the logic. The better you can follow the logic the more capable you are at finding out what is wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Divide and Conquer
&lt;/h3&gt;

&lt;p&gt;Sometimes you can have a bug or problem in your code but you don't know where it is. This can be solved by the divide and conquer approach. This approach is used to find where in code a problem is.&lt;/p&gt;

&lt;p&gt;Comment out the last half of the script or code.  Or add a statement in the middle of the code that kills the process. If the first half of the code runs correctly then you know that the bug/problem lies in the second half of the code. So if the first half of the code runs correctly then find the middle of the second half of the code and comment out the code from the middle to the end. Run the code. If the code runs correctly then you know the problem is in the commented out code. Or if running the code now shows up the bug then you know the section where the bug is and can further divide and conquer to further pin point it.&lt;/p&gt;

&lt;p&gt;If the bug or problem shows up when running the first half of a script or code then you know the bug is in the first half of the code. Now you need to use the same approach on the first half of the code. Find the middle of the first half of the code and comment out from the middle to the end. See if the code works. If it does work then you know that the bug or issue is in the section that you just commented out and can further divide and conquer. If the code doesn't work then you know the problem or bug is in the first half of the code you just ran and you can further divide and conquer.&lt;/p&gt;

&lt;p&gt;Once you have pin pointed much more closely where in the code the bug or problem is you can focus your attention there to find the bug or problem. You can write console.log statements to look at output to better understand what is happening.  Look and increase your understanding of the section of the code where the bug is to find it and fix it.&lt;/p&gt;

&lt;p&gt;There are other ways to debug by dividing and conquering. When you want to find out where a bug is look for ways to remove or divide code and run isolated code to see if the bug shows up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compare Code that Doesn't Work to Code That Works
&lt;/h3&gt;

&lt;p&gt;If you have code that doesn't work but you don't know why and you have read the documentation about the code involved but it still doesn't work then one approach is to find code that does the same or similar thing that does work. Compare your code to code that works to find out what you are doing different.&lt;/p&gt;

&lt;p&gt;There are many scripts and smart contracts in our repos that can be looked at.  Google can be searched to find code that does something.&lt;/p&gt;

&lt;h3&gt;
  
  
  Change of Behavior
&lt;/h3&gt;

&lt;p&gt;Sometimes code can be debugged by making changes to code and running it and observing changes or differences in results. This method of debugging gives you information about what the code is doing. It can give you clues to what is happening and the source of the problem. Remember that debugging is about increasing your understanding of the code and software so you can determine the cause of a problem.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>debugging</category>
      <category>programming</category>
    </item>
    <item>
      <title>Ethereum Diamonds Solve These Problems</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Sat, 01 May 2021 22:38:43 +0000</pubDate>
      <link>https://dev.to/mudgen/ethereum-diamonds-solve-these-problems-3fmp</link>
      <guid>https://dev.to/mudgen/ethereum-diamonds-solve-these-problems-3fmp</guid>
      <description>&lt;p&gt;Diamonds solve these problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The maximum size a smart contract can be on Ethereum is 24kb.  But sometimes larger smart contracts are needed or desired. Diamonds solve that problem.&lt;/li&gt;
&lt;li&gt;Provides a structure to systematically and logically organize and extend larger smart contract systems so they don't turn into a spaghetti code mess.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Provides a single address for a lot of smart contract functionality. This makes integration with smart contracts and user interfaces and other software easier.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The standard for diamonds is here: &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;https://eips.ethereum.org/EIPS/eip-2535&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resources: &lt;a href="https://eips.ethereum.org/EIPS/eip-2535#learning--references"&gt;https://eips.ethereum.org/EIPS/eip-2535#learning--references&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>smartcontracts</category>
    </item>
    <item>
      <title>How to Share Functions Between Facets of a Diamond</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Wed, 31 Mar 2021 06:06:01 +0000</pubDate>
      <link>https://dev.to/mudgen/how-to-share-functions-between-facets-of-a-diamond-1njb</link>
      <guid>https://dev.to/mudgen/how-to-share-functions-between-facets-of-a-diamond-1njb</guid>
      <description>&lt;p&gt;There are a number of ways to share or reuse functions between facets of an Ethereum diamond. &lt;strong&gt;The best way I have found is to write internal functions in Solidity libraries and call those functions in facets.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is a common misunderstanding to think that all Solidity libraries are deployed. Only Solidity libraries with external functions must be deployed. Solidity libraries with only internal functions are not deployed -- they are added to the bytecode of contracts/facets that use them.&lt;/p&gt;

&lt;p&gt;Also, only the bytecode from the internal functions that are actually used from a Solidity library are added to the bytecode of a facet. So it is possible to have large Solidity libraries that are utilized across facets without adding too much to the bytecode of facets that use them.&lt;/p&gt;

&lt;p&gt;It is possible to use &lt;a href="https://dev.to/mudgen/how-diamond-storage-works-90e"&gt;diamond storage&lt;/a&gt; and/or &lt;a href="https://dev.to/mudgen/appstorage-pattern-for-state-variables-in-solidity-3lki"&gt;AppStorage&lt;/a&gt; in Solidity libraries which makes libraries even more useful and powerful. &lt;/p&gt;

&lt;p&gt;Checkout &lt;a href="https://github.com/aavegotchi/aavegotchi-contracts/tree/master/contracts/Aavegotchi/libraries"&gt;Aavegotchi's libraries&lt;/a&gt; which are used across facets.&lt;/p&gt;

&lt;p&gt;In addition to using internal functions in Solidity libraries &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535 Diamonds&lt;/a&gt; describes a number of other ways functions can be shared or reused between facets:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write internal functions in Solidity libraries and call those functions in facets. These functions can access diamond storage or AppStorage directly.&lt;/li&gt;
&lt;li&gt;Copy internal function code in one facet to the other facet.&lt;/li&gt;
&lt;li&gt;Put common internal functions in a contract that is inherited by multiple facets.&lt;/li&gt;
&lt;li&gt;A type safe way to call an external function defined in another facet is to do this: &lt;code&gt;MyOtherFacet(address(this)).myFunction(arg1, arg2)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A more gas-efficient way to call an external function defined in another facet is to use delegatecall. Here is an example of doing that:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="n"&gt;DiamondStorage&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;diamondStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;bytes4&lt;/span&gt; &lt;span class="n"&gt;functionSelector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;bytes4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myFunction(uint256)"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// get facet address of function
&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="n"&gt;facet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectorToFacet&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;functionSelector&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="k"&gt;memory&lt;/span&gt; &lt;span class="n"&gt;myFunctionCall&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encodeWithSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;functionSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;facet&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;delegatecall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myFunctionCall&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"myFunction failed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instead of calling an external function defined in another facet you can instead create an internal function version of the external function. Add the internal version of the function to the facet that needs to use it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>diamonds</category>
      <category>ethereum</category>
      <category>smartcontracts</category>
    </item>
    <item>
      <title>AppStorage Pattern for State Variables in Solidity</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Tue, 02 Feb 2021 05:34:00 +0000</pubDate>
      <link>https://dev.to/mudgen/appstorage-pattern-for-state-variables-in-solidity-3lki</link>
      <guid>https://dev.to/mudgen/appstorage-pattern-for-state-variables-in-solidity-3lki</guid>
      <description>&lt;p&gt;I have written about the &lt;a href="https://dev.to/mudgen/how-diamond-storage-works-90e"&gt;diamond storage pattern&lt;/a&gt; for organizing contract state variables in proxy contracts and diamonds. &lt;/p&gt;

&lt;p&gt;As a quick refresher, a state variable or storage layout organizational pattern is needed when writing proxy contracts or diamonds in Solidity because Solidity's builtin storage layout system doesn't work for them. &lt;/p&gt;

&lt;p&gt;Diamond storage is particularly good for isolating or compartmenting state variables to specific facets or functionality. This is great for creating modular facets that can be understood as their own units and be added to diamonds.  A diamond with a lot of functionality is well organized and understandable if each of its facets can be understood in isolation.  Diamond storage helps make that possible.&lt;/p&gt;

&lt;p&gt;However, I have found that when building applications with diamonds I often want to share state variables specific to my application with facets that are specific to my application. It gets tedious to call a &lt;code&gt;diamondStorage()&lt;/code&gt; function in every function that I want to access state variables.&lt;/p&gt;

&lt;p&gt;I have successfully utilized a new pattern in contracts called &lt;code&gt;AppStorage&lt;/code&gt;.  It is a nicer and more convenient way to access application specific state variables that are shared among facets.&lt;/p&gt;

&lt;p&gt;The pattern works in the following way:&lt;/p&gt;

&lt;p&gt;1) Define a struct called AppStorage that contains all the state variables specific to your application and that you plan to share with different facets. Store AppStorage in a file. Any of your facets can now import this file to access the state variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="c1"&gt;// AppStorage.sol
&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;secondVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;firstVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;uint256&lt;/span&gt; &lt;span class="n"&gt;lastVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) In a facet that imports the AppStorage struct declare an AppStorage state variable called &lt;code&gt;s&lt;/code&gt;.  This should be the only state variable declared in the facet. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"./AppStorage.sol"&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;StakingFacet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now in your facet you can access all the state variables in AppStorage by prepending state variables with &lt;code&gt;s.&lt;/code&gt;. Here's a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"./AppStorage.sol"&lt;/span&gt;

&lt;span class="k"&gt;contract&lt;/span&gt; &lt;span class="n"&gt;StakingFacet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;myFacetFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;external&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firstVar&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secondVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very nice convention because it makes state variables concise, easy to access, and it distinguishes state variables from local variables and prevents name clashes/shadowing with local variables and function names. It helps identify and make explicit state variables in a convenient and concise way.  It is also a little more gas efficient than diamond storage access.&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;AppStorage s&lt;/code&gt; is the first and only state variable declared  in facets its position in contract storage is &lt;code&gt;0&lt;/code&gt;. This fact can be used to access AppStorage in Solidity libraries using diamond storage access. Here's an example of that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;
&lt;span class="k"&gt;library&lt;/span&gt; &lt;span class="n"&gt;MyLib&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;appStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
    &lt;span class="k"&gt;internal&lt;/span&gt; 
    &lt;span class="k"&gt;pure&lt;/span&gt; 
    &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;    
    &lt;span class="k"&gt;assembly&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;someFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AppStorage&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;appStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;stuff&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;AppStorage s&lt;/code&gt; can be declared as the one and only state variable in facets or it can be declared in a contract that facets inherit.&lt;/p&gt;

&lt;p&gt;AppStorage won't work if state variables are declared outside of AppStorage and outside of Diamond Storage. It is a common error for a facet to inherit a contract that declares state variables outside AppStorage and Diamond Storage. This causes a misalignment of state variables.&lt;/p&gt;

&lt;p&gt;One downside is that state variables can't be declared public in structs so getter functions can't automatically be created this way. But I think it is better anyway to make your own getter functions for state variables because its more explicit.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/aavegotchi/ghst-staking"&gt;GHSTStakingDiamond&lt;/a&gt; is a good example of a diamond that uses the AppStorage pattern.&lt;/p&gt;

&lt;p&gt;For a large, in production, successful example of using the AppStorage pattern, checkout the Aavegotchi diamond. The &lt;code&gt;AppStorage&lt;/code&gt; struct is defined in this file: &lt;a href="https://github.com/aavegotchi/aavegotchi-contracts/blob/master/contracts/Aavegotchi/libraries/LibAppStorage.sol"&gt;LibAppStorage&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Notice that the &lt;code&gt;AppStorage&lt;/code&gt; struct utilizes other structs in arrays and mappings. &lt;/p&gt;

</description>
      <category>solidity</category>
      <category>smartcontracts</category>
      <category>blockchain</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Addressing Josselin Feist's Concern's of EIP-2535 Diamonds</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Sun, 01 Nov 2020 02:14:00 +0000</pubDate>
      <link>https://dev.to/mudgen/addressing-josselin-feist-s-concern-s-of-eip-2535-diamond-standard-me8</link>
      <guid>https://dev.to/mudgen/addressing-josselin-feist-s-concern-s-of-eip-2535-diamond-standard-me8</guid>
      <description>&lt;p&gt;Josselin Feist, from Trail of Bits, &lt;a href="https://blog.trailofbits.com/2020/10/30/good-idea-bad-design-how-the-diamond-standard-falls-short/"&gt;wrote an article with a number of concerns&lt;/a&gt; about &lt;a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2535.md"&gt;EIP-2535 Diamonds&lt;/a&gt; and an implementation of it. I'll address concerns he brought up and correct some things along the way.&lt;/p&gt;

&lt;p&gt;One thing to mention is that EIP-2535 Diamond and its implementations and tools and information is a community effort. There is a growing group of people making the standard and its growing ecosystem what it is.&lt;/p&gt;

&lt;p&gt;I invite Trail of Bits and other people to help fill in the gaps of information, tests, procedures, ideas and tools to help make diamonds and upgrades better and easier to use for everyone. &lt;/p&gt;

&lt;p&gt;The Diamond Discord is here: &lt;a href="https://discord.gg/kQewPw2"&gt;https://discord.gg/kQewPw2&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  EIP-2535 Diamonds Is Not Just For Upgrades
&lt;/h3&gt;

&lt;p&gt;Josselin's article describes EIP-2535 Diamonds as an "upgradeable standard" only. This is a fundamental misunderstanding of the standard. EIP-2535 Diamonds is more than just a standard for upgrading smart contracts. In addition “upgradeability” is an optional feature of the standard.&lt;/p&gt;

&lt;p&gt;EIP2535 Diamonds is a general purpose smart contract framework for building multi-contract systems. Diamonds can be upgradeable or not. Diamonds provide a way to have smart contract functionality that exceeds the 24kb smart contract size limit at a single Ethereum address. It provides a standard way to organize the source code of a large smart contract system. It provides a mechanism for on-chain code reuse and modularity. It provides mechanisms for transparency and tooling.&lt;/p&gt;

&lt;p&gt;Yes, it also enables upgrades (if desired), in such a way that a project can be deployed and then be extended as needed in a systematic and organized way, without limit. And diamonds provide fine-grained upgrades so code that doesn't need to be changed doesn't have to be redeployed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Josselin's Article Is Biased Against EIP2535 Diamonds With False Data
&lt;/h3&gt;

&lt;p&gt;Josselin's article is not an objective, honest review of EIP2535 Diamonds. It contains outdated code and false data. His article brings up security concerns that are addressed and handled by the standard and related diamond documentation.&lt;/p&gt;

&lt;p&gt;A prominent and obvious technical advantage of EIP2535 Diamonds is that it provides a way for a smart contract to exceed the 24kb smart contract size limit. Josselin's article fails to mention that and other benefits of the standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Upgrades
&lt;/h2&gt;

&lt;p&gt;Josselin says an upgradability standard should have the following things:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A clear, simple implementation.&lt;/strong&gt; Standards should be easy to read to simplify integration with third-party applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Understood, this has been done with the &lt;a href="https://github.com/mudgen/diamond-1-hardhat"&gt;diamond-1-hardhat&lt;/a&gt; implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A thorough checklist of upgrade procedures.&lt;/strong&gt; Upgrading is a risky process that must be thoroughly explained.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A list of things to watch out for and rules to follow to ensure safe upgrades has been written and exists here: &lt;a href="https://eip2535diamonds.substack.com/p/diamond-upgrades"&gt;https://eip2535diamonds.substack.com/p/diamond-upgrades&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;On-chain mitigations against the most common upgradeability mistakes, including function shadowing and collisions.&lt;/strong&gt; Several mistakes, though easy to detect, can lead to severe issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The diamond reference implementations contain no function shadowing and provides a solution for handling that. The standard prevents function selector clashes. Diamond storage helps prevent contract storage corruption or collisions. Additional tools and ways to do this are welcome. There is also information about upgradeable contracts and their pitfalls that can be found online.&lt;/p&gt;

&lt;p&gt;I have written many articles (and there are others online) about how to correctly and safely write smart contracts and diamonds. These can be found here: &lt;a href="https://eip2535diamonds.substack.com/"&gt;https://eip2535diamonds.substack.com/&lt;/a&gt; and here: &lt;a href="https://dev.to/mudgen"&gt;https://dev.to/mudgen&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A list of associated risks.&lt;/strong&gt; Upgradeability is difficult; it can conceal security considerations or imply that risks are trivial. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A list of things to watch out for and rules to follow to ensure safe upgrades has been written and exists here: &lt;a href="https://eip2535diamonds.substack.com/p/diamond-upgrades"&gt;https://eip2535diamonds.substack.com/p/diamond-upgrades&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Also this blog post about Pros and Cons of diamonds is recommended reading: &lt;a href="https://eip2535diamonds.substack.com/p/answering-some-diamond-questions"&gt;https://eip2535diamonds.substack.com/p/answering-some-diamond-questions&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tests integrated with the most common testing platforms.&lt;/strong&gt; The tests should highlight how to deploy the system, how to upgrade a new implementation, and how an upgrade can fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The diamond reference implementations have a suite of tests to test them. The reference diamond implementations and other implementations show ways to deploy and upgrade diamonds. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/wighawag/hardhat-deploy#builtin-in-support-for-diamonds-eip2535"&gt;hardhat-deploy&lt;/a&gt; provides builtin support for deploying and upgrading diamonds and includes documentation about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contract Standardization
&lt;/h2&gt;

&lt;p&gt;One of the main purposes of a contract standard is to provide standard interfaces with implementation details so that implementations can be made that interoperate with other contracts and tools and software. &lt;/p&gt;

&lt;p&gt;EIP-2535 Diamonds does this by providing a standard function &lt;code&gt;diamondCut&lt;/code&gt; for upgrades, a standard event &lt;code&gt;DiamondCut&lt;/code&gt; for recording what functions are added/replaced/removed and 4 standard functions that are used to show what functions a diamond has.&lt;/p&gt;

&lt;p&gt;The standard provides information about how to implement these functions and other useful information. All of this is useful and being used in development and production successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diamond Implementation
&lt;/h2&gt;

&lt;p&gt;Josselin shows part of an implementation of the &lt;code&gt;diamondCut&lt;/code&gt; function that is used for upgrades. In several places he mentions that gas-optimizations make the code more complicated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Additionally, much of the code complexity is due to optimization in locations that don’t need it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The gas-optimizations that were made in that implementation save gas and it is really up to the people building an application whether or not the gas optimizations are needed or wanted or not.&lt;/p&gt;

&lt;p&gt;People who aren't interested in gas-optimizations can use the much simpler &lt;a href="https://github.com/mudgen/diamond-1-hardhat"&gt;diamond-1-hardhat&lt;/a&gt; implementation.&lt;/p&gt;

&lt;p&gt;Josselin's article is badly out of date. The code shown for the upgrade function was removed and replaced by simplified code &lt;em&gt;7 weeks before the date Josselin's article was published&lt;/em&gt;. The code he shows does not exist in any of the current diamond reference implementations. I have asked Josselin to update his article with code from a current implementation, but he has not done that.&lt;/p&gt;

&lt;p&gt;Josselin was hired from Trail of Bits back in 2020 to help us find bugs and improve our code. And he did and we fixed and improved things. Then he published an article featuring our old, unfixed code to represent EIP-2535 Diamonds. To be accurate he should provide information and code for current implementations.&lt;/p&gt;

&lt;p&gt;Also note that the EIP-2535 Diamond is a smart contract standard. It is not an implementation. There can be good or bad implementations of it. Josselin's article conflates an outdated implementation with the standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diamond Terminology
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Diamond&lt;/strong&gt; A contract that gets its external functions from other contracts called facets. A diamond has a fallback function that delegates function calls to facets. A diamond implements the &lt;a href="https://eips.ethereum.org/EIPS/eip-2535#specification"&gt;Specification section&lt;/a&gt; of EIP-2535 Diamonds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facet&lt;/strong&gt; A contract that supplies external functions to a diamond. In the diamond industry a facet is a side of a diamond.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loupe&lt;/strong&gt; Four standard functions that show what functions and facets a diamond has. In the diamond industry a loupe is a magnifying glass that is used to look at diamonds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upgradeable Diamond&lt;/strong&gt; A diamond that has the &lt;code&gt;diamondCut&lt;/code&gt; external function so functions can be added/replaced/removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finished Diamond&lt;/strong&gt; A diamond that was an upgradeable diamond but then its &lt;code&gt;diamondCut&lt;/code&gt; function was removed so functions can no longer be add/replaced/removed. It can't be upgraded anymore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single Cut Diamond&lt;/strong&gt; A diamond that adds all of its functions and facets in its constructor function, and does not add the &lt;code&gt;diamondCut&lt;/code&gt; or other upgrade function. A single cut diamond is fully formed upon deployment, is immutable and can't be upgraded. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Josselin says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;EIP 2535 introduces “diamond terminology,” wherein the word “diamond” means a proxy contract, “facet” means an implementation, and so on. It’s unclear why this terminology was introduced.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me clear this up.&lt;/p&gt;

&lt;p&gt;Originally EIP-2535 Diamonds was called the &lt;a href="https://eips.ethereum.org/EIPS/eip-1538"&gt;Transparent Contract Standard&lt;/a&gt;, but that name clashed with something from OpenZeppelin and they asked me to change the name.&lt;/p&gt;

&lt;p&gt;When making transparent contracts it was noticed that each of its facets/implementations could handle a different aspect or set of functionality and it was useful to organize code this way. It was like each facet/implementation was a different side or facet of a transparent contract.&lt;/p&gt;

&lt;p&gt;Physical diamonds have facets that share a common center. EIP-2535 diamonds have facets that share the same contract storage space and a common Ethereum address.&lt;/p&gt;

&lt;p&gt;The terminology helps conceptualize how diamonds work and how to build applications with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Loupe Functions
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://dev.to/mudgen/why-loupe-functions-for-diamonds-1kc3"&gt;loupe functions&lt;/a&gt; are four standard functions defined by EIP-2535 Diamonds that return what functions a diamond has and the facet addresses they come from. &lt;/p&gt;

&lt;p&gt;The verified source code of a diamond does not show what functions it has or where it gets them. And a diamond's ABI doesn't include what functions it has. To help get this information the DiamondCut event or the loupe functions are used.&lt;/p&gt;

&lt;p&gt;The loupe functions are being used successfully by the application &lt;a href="https://louper.dev/"&gt;https://louper.dev/&lt;/a&gt; to display and make diamonds transparent. It is like etherscan but for diamonds.&lt;/p&gt;

&lt;p&gt;One of the loupe functions is &lt;code&gt;facetFunctionSelectors&lt;/code&gt;. Josselin says this about it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;facetFunctionSelectors&lt;/code&gt; returns all the function selectors of an implementation. This information will only be useful for off-chain components, which can already extract the information from the contract’s events. There’s no need for such a feature on-chain&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An important reason the loupe functions (including &lt;code&gt;facetFunctionSelectors&lt;/code&gt;) exist is because functions on smart contracts are more reliable than events. These functions make diamonds robust. This ensures their transparency and interoperability with software.&lt;/p&gt;

&lt;p&gt;Some event systems fail, some are inconsistent and fragile. Events work better on some blockchains than others. For example on Polygon where block times are fast querying events on nodes will fail if trying to query too far back in time. Basing a system on an unreliable event system makes a system also unreliable or harder to deal with  or program to make reliable. This is why diamonds use on-chain loupe functions for transparency. It is robust. &lt;/p&gt;

&lt;p&gt;Currently the loupe functions are being used in unit tests to test diamonds. They are being used in code that deploys and upgrades diamonds. They are used by &lt;a href="https://github.com/wighawag/hardhat-deploy#builtin-in-support-for-diamonds-eip2535"&gt;hardhat-deploy&lt;/a&gt; to deploy and upgrade diamonds.&lt;/p&gt;

&lt;p&gt;It is true that &lt;code&gt;DiamondCut&lt;/code&gt; events can be queried and processed to get the same data that the loupe functions return. This means there are two ways to get data about diamonds. Both ways can get data about diamonds and either way can be used.&lt;/p&gt;

&lt;p&gt;So why have two ways? Because in some cases it will be easier and better to use function calls, and in other cases it will be easier and better to use events.&lt;/p&gt;

&lt;p&gt;For example a blockchain explorer website may want to use events to show facet and function information about diamonds because it is already using event tooling and infrastructure to capture and process events for contracts. &lt;/p&gt;

&lt;p&gt;An upgrade script may want to check that functions don't already exist in a diamond before trying to add them. Using the &lt;code&gt;facets&lt;/code&gt; loupe function for this is simple and easy and reliable.&lt;/p&gt;

&lt;p&gt;A simple static website can show information about any diamond by calling the loupe functions and then using the returned data to query services like Etherscan to get and show verified source code, ABI information and other information. This could be done with events, but it would be easier, simpler and probably run faster if done with loupe functions.&lt;/p&gt;

&lt;p&gt;Having loupe functions and events give people and software choice to use what is best for their use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is also a question about reliability.&lt;/strong&gt; Querying and processing events is not as reliable, available and performant as contract function calls. Likewise, a connection to an Ethereum node may not always be available in every system but there may be a connection to an events database that can be used to retrieve diamond information. Having both events and loupe functions makes diamonds &lt;strong&gt;robust&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The loupe functions add some complexity to diamonds. Generally it is a good idea to push complexity out of contracts into off-chain software. But every case is different and requires evaluation. In the case of diamonds there is another principle which is optimize for simplicity for common use cases. A diamond is implemented and deployed once but will be queried many times and may be used by or integrated with a lot of software. The loupe functions are a simple, reliable and direct way to query diamonds and integrate with software. The loupe functions are read-only, tested and security audited. The loupe functions can simply be added and used in every diamond without touching application specific smart contract code.&lt;/p&gt;

&lt;p&gt;In addition the loupe functions can be deployed once and be reused on-chain by many diamonds.&lt;/p&gt;

&lt;p&gt;Someone suggested the idea of making the loupe functions optional in the standard. The problem with that is it would break interoperability. Some diamonds would work with some software and not with other software.&lt;/p&gt;

&lt;p&gt;I wrote another article about loupe functions that provides more information: &lt;a href="https://dev.to/mudgen/why-loupe-functions-for-diamonds-1kc3"&gt;Diamonds Loupe Functions&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Addressing False Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Many Interfaces
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;While the proposal only needs a lookup table, from the function signature to the implementation’s address, the EIP defines many interfaces that require storage of additional data:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This statement is a lie. It is easily verifiably false. You can easily fact check it yourself. &lt;/p&gt;

&lt;p&gt;Josselin says the EIP "&lt;em&gt;defines many interfaces that require storage of additional data&lt;/em&gt;". If you look at &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535&lt;/a&gt; you will see that the EIP &lt;strong&gt;only defines two interfaces&lt;/strong&gt; in the entire standard. So unless you think "many" means two the statement is false. But still, only one of the interfaces requires storing additional data besides a lookup table. One definitely does not mean "many".&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://eips.ethereum.org/EIPS/eip-2535#diamond-loupe"&gt;IDiamondLoupe&lt;/a&gt; interface requires storing function selectors in an array and their positions in the array. That is all the additional data that needs to be stored.&lt;/p&gt;

&lt;p&gt;Why does Josselin lie about this?  If it is just a mistake then why doesn't he fix it?&lt;/p&gt;

&lt;p&gt;In general I suggest that you verify the technical details for yourself with regards to Josselin's article. The diamond reference implementations can be found from here: &lt;a href="https://github.com/mudgen/diamond"&gt;https://github.com/mudgen/diamond&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Safe Struct Storage Pointers with Diamond Storage
&lt;/h3&gt;

&lt;p&gt;EIP-2535 Diamonds shows and encourages a contract storage technique called Diamond Storage.&lt;/p&gt;

&lt;p&gt;Diamond Storage enables different facets to share or use their own contract storage space within a diamond and access it with a namespace. The namespace is a unique, human-readable and meaningful string that represents the area of data. For example &lt;code&gt;"com.mywebsite.myproject.mytoken"&lt;/code&gt;. The string is hashed and used as a pointer to a struct in contract storage. More information about this and examples are in this article: &lt;a href="https://dev.to/mudgen/how-diamond-storage-works-90e"&gt;How Diamond Storage Works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There is no risk of accidentally or maliciously colliding diamond storage with other contract storage because of using hashes of unique and meaningful strings for struct storage pointers. &lt;/p&gt;

&lt;p&gt;OpenZeppelin &lt;a href="https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/issues/158#issuecomment-1101565291"&gt;plans to use Diamond Storage&lt;/a&gt; in their next version of upgradeable contracts.&lt;/p&gt;

&lt;p&gt;Josselin's article shows an example of colliding contract storage data. However his storage pointer is not a hash of a unique and meaningful string. His storage pointer is not even a hash of a string but is a hash of a &lt;a href="https://solidity.readthedocs.io/en/v0.7.4/types.html#hexadecimal-literals"&gt;hex literal&lt;/a&gt; of a specific but random looking value. It is easy to see that it is not a namespace to an area of contract storage.&lt;/p&gt;

&lt;p&gt;Malicious storage pointers are obvious and easy to spot. Here is a comparison:&lt;/p&gt;

&lt;p&gt;Namespace to an area of contract storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;storagePosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myproject.mytoken"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Malicious pointer that collides with existing contract storage data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;storagePosition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s"&gt;hex"78c8663007d5434a0acd246a3c741b54aecf2fefff4284f2d3604b72f26"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Someone adding code to their contract or diamond with a malicious pointer means that the person is adding code that they didn't look at or understand. If that is the case then any kind of malicious code could be added.&lt;/p&gt;




&lt;h3&gt;
  
  
  Diamond Storage Not Required
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The EIP proposes that every implementation have an associated structure to hold the implementation variables, and a pointer to an arbitrary storage location where the structure will be stored. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;EIP-2535 Diamonds does show, explain and encourage using diamond storage. But it does not require it.&lt;/p&gt;

&lt;p&gt;Diamonds and facets are free to use or mix any contract storage strategy such as inherited storage etc. &lt;/p&gt;

&lt;p&gt;To comply with the standard and be a diamond an implementation must implement the &lt;a href="https://eips.ethereum.org/EIPS/eip-2535#specification"&gt;Specification section&lt;/a&gt; of the standard, which does not mandate any contract storage strategy or mechanism.&lt;/p&gt;




&lt;h3&gt;
  
  
  Function Shadowing
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Upgradeable contracts often have functions in the proxy that shadow the functions that should be delegated. Calls to these functions will never be delegated, as they will be executed in the proxy. Additionally, the associated code will not be upgradeable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;None of the diamond reference implementations have any functions shadowing any other functions. Function shadowing is not possible in diamonds that follow the standard.&lt;/p&gt;

&lt;p&gt;It is possible to have external functions directly in a diamond in a safe way. They are called immutable functions in EIP-2535 Diamonds. They are functions that can't be replaced or removed. The diamond loupe functions provide information about them and they are emitted in the &lt;code&gt;DiamondCut&lt;/code&gt; event. In the reference implementations calling &lt;code&gt;diamondCut&lt;/code&gt; to replace or remove immutable functions will revert. See the standard for more info.&lt;/p&gt;




&lt;h3&gt;
  
  
  Contract Existence Check
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Another common mistake is the absence of an existence check for the contract’s code. If the proxy delegates to an incorrect address, or implementation that has been destructed, the call to the implementation will return success even though no code was executed (see the Solidity documentation). As a result, the caller will not notice the issue, and such behavior is likely to break third-party contract integration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Note: Josselin's article shows a fallback function without the contract code check he talks about.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The fallback function in the diamond reference implementations do not check for contract code. It does not do this because of the gas cost and because the &lt;code&gt;diamondCut&lt;/code&gt; function prevents any functions from being added from facets that do not have code.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://eip2535diamonds.substack.com/p/diamond-upgrades"&gt;rule which is documented&lt;/a&gt; is don't write &lt;code&gt;selfdestruct&lt;/code&gt; in facet source code and don't use facets with &lt;code&gt;selfdestruct&lt;/code&gt; in them unless it specifically makes sense for some use case. It is unnecessary and useless (and costs gas) to check for contract existence on contracts that can never be deleted.&lt;/p&gt;

&lt;p&gt;OpenZeppelin's &lt;a href="https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Proxy.sol#L15"&gt;proxy contracts&lt;/a&gt; also do not perform the check in the fallback function. Like the diamond reference implementations they prevent implementation contracts from being added that don't have code.&lt;/p&gt;

&lt;p&gt;EIP-2535 Diamonds does not prevent people from adding this check in the diamond fallback function so it can be added by people who want it. Contract existence check in the diamond fallback function is not part of the EIP2535 Diamonds standard so it is up to the implementer to implement it or not.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>smartcontracts</category>
      <category>standards</category>
    </item>
    <item>
      <title>Diamond Loupe Functions</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Thu, 08 Oct 2020 20:34:36 +0000</pubDate>
      <link>https://dev.to/mudgen/why-loupe-functions-for-diamonds-1kc3</link>
      <guid>https://dev.to/mudgen/why-loupe-functions-for-diamonds-1kc3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A loupe is a magnifying glass that is used to look at diamonds.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535 Diamond Standard&lt;/a&gt; a loupe is four standard read-only functions that tell you what functions and facets are provided by a diamond.&lt;/p&gt;

&lt;p&gt;A facet is a smart contract that supplies diamonds with external functions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you look at the source code of a diamond it will show a fallback function. It doesn't show what external functions it has. To get that information you need to call one or more of the four standard, read-only loupe functions. &lt;/p&gt;

&lt;p&gt;Here are the four standard read-only loupe functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;facetAddresses()&lt;/code&gt; Returns all the facet addresses used by a diamond.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetAddress(bytes4 _functionSelector)&lt;/code&gt; Returns the facet address that implements a functions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetFunctionSelectors(address _facet)&lt;/code&gt; Returns all the functions used by a diamond that come from a particular facet.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facets()&lt;/code&gt; Returns an array consisting of all the facet addresses and functions used by a diamond.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The loupe functions can be used for many useful things including:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the facet addresses to query services like Etherscan to retrieve and show all the source code used by a diamond.&lt;/li&gt;
&lt;li&gt;Retrieve ABI info for a diamond.&lt;/li&gt;
&lt;li&gt;Tools and programming libraries use them to deploy diamonds.&lt;/li&gt;
&lt;li&gt;Tools and programming libraries use them to upgrade diamonds.&lt;/li&gt;
&lt;li&gt;User interfaces use them to show information about diamonds.&lt;/li&gt;
&lt;li&gt;User interfaces use them to enable users to show and call functions on diamonds.&lt;/li&gt;
&lt;li&gt;Tests use them to verify that correct functions and facets are being used correctly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The loupe functions make diamonds transparent. This is important for understanding, showing and using exactly the functionality provided by diamonds. &lt;/p&gt;

&lt;p&gt;They are important for security to verify that diamonds are used correctly and not mistakenly or maliciously.&lt;/p&gt;

&lt;p&gt;They are important for testing to ensure that diamonds contain the correct functions and facets and to test code that uses diamonds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Another Way. Transparency With Events
&lt;/h2&gt;

&lt;p&gt;The loupe functions are not the only way to find out what functions and facets a diamond has.&lt;/p&gt;

&lt;p&gt;Anytime a function/facet is added/replaced/removed on a diamond the &lt;code&gt;DiamondCut&lt;/code&gt; event is emitted that records exactly what changed in a diamond.&lt;/p&gt;

&lt;p&gt;All the &lt;code&gt;DiamondCut&lt;/code&gt; events for a diamond can be queried and an algorithm executed to determine what facets and functions currently exists for a diamond.&lt;/p&gt;

&lt;p&gt;You might wonder why we have two ways to do the same thing.&lt;/p&gt;

&lt;p&gt;First, the &lt;code&gt;DiamondCut&lt;/code&gt; event provides something that the loupe functions don't: A historical record of all upgrades done on a diamond. The historical record can be used to verify the state, correctness and security of a diamond over time.&lt;/p&gt;

&lt;p&gt;So you might wonder why have loupe functions when events can be used to get the current functions and facets used by a diamond.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Have Loupe Functions When You can Use Events?
&lt;/h2&gt;

&lt;p&gt;To be clear, this isn't a debate of events vs external functions. The &lt;code&gt;DiamondCut&lt;/code&gt; events are a given and there is no restriction on their use.  The debate is this: &lt;strong&gt;Why have events &lt;em&gt;and&lt;/em&gt; loupe functions?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's look at the tradeoffs of having/not having loupe functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More choice&lt;/strong&gt; People that want to use event systems, such as the &lt;a href="https://thegraph.com/"&gt;The Graph&lt;/a&gt;, or event database systems, to determine the contents of diamonds can do so. People who want to call the loupe external functions on diamonds to get the same data, can do so. Having events and the loupe functions make diamonds easier to use for more people because they can choose how to get the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier adoption by services and tools&lt;/strong&gt; Services such as Etherscan, blockchain explorers, web applications, programming libraries and other software may prefer or require the use of events or external functions. Having both options increases the capability to integrate with  tools and services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;More transparent, reliable and available&lt;/strong&gt; If an event system is not available or up-to-date or is slow or has any other problem, then the loupe functions can be used. If external functions can't be called in a particular context then an event system or database can be used. Having both methods available increases the reliability, availability and transparency of diamonds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simple and easy&lt;/strong&gt; The loupe functions are simple and easy to use. They are regular external contract functions that are called with regular client contract libraries like web3.js or ethers.js. No special custom software or third party software or library or dependency is needed to call the loupe functions, since they are regular contract functions. &lt;br&gt;&lt;br&gt;
Keeping data, code and logic within the diamond loupe functions simplifies client software that needs the data.&lt;br&gt;&lt;br&gt;
Software that uses events has to rely on custom software or a third-party library to query all the &lt;code&gt;DiamondCut&lt;/code&gt; events and execute logic to determine the current functions and facets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secure&lt;/strong&gt; The code for the &lt;code&gt;diamondCut&lt;/code&gt; function and the diamond loupe functions is carefully looked at by Solidity developers and security experts. These functions are simple enough for a competent Solidity developer to read and understand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;In theory the loupe functions can be executed on-chain.&lt;/strong&gt; In theory the loup functions in the &lt;a href="https://github.com/mudgen/diamond-3"&gt;diamond-3&lt;/a&gt; implementation are gas-efficient enough to be called and used in transactions. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loupe functions add code to a diamond.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;However a DiamondLoupeFacet only needs to be deployed once and can be reused by many diamonds.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/mudgen/diamond-1"&gt;diamond-1&lt;/a&gt; implementation does the following to implement loupe functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stores an array of function selectors. When a new function is added its selector is added to the function selectors array. When a function is removed its selector is removed from the function selectors array.&lt;/li&gt;
&lt;li&gt;The loupe functions are implemented like this:

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;facetAddress(bytes4 _functionSelector)&lt;/code&gt; The facet address that is associated with the &lt;code&gt;_functionSelector&lt;/code&gt; is found and returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetAddresses&lt;/code&gt; The function selectors are looped through to find all the facet addresses used by the diamond. An array of facet addresses is returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetFunctionSelectors(address _facet)&lt;/code&gt; The function selectors are looped through to find all the selectors that belong to the facet specified by &lt;code&gt;_facet&lt;/code&gt;. An array of selectors is returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facets()&lt;/code&gt; The function selectors are looped through to find all the facet addresses and function selectors used by the diamond. These are returned.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://github.com/mudgen/diamond-2"&gt;diamond-2&lt;/a&gt; implementation is implemented the same way as diamond-1 except that its code is more complicated because it is gas-optimized.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/mudgen/diamond-3"&gt;diamond-3&lt;/a&gt; implementation does the following to implement loupe functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Stores an array of facet addresses. For each facet address an array of function selectors is stored. When a new facet is added it is added to the array of facet addresses. When a facet is removed it is removed from the array of facet addresses. When a function is added its selector is added to an array of function selectors. When a function is removed its selector is removed from an array of function selectors.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The loupe functions are very simple and implemented like this:

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;facetAddress(bytes4 _functionSelector)&lt;/code&gt; The facet address that is associated with the &lt;code&gt;_functionSelector&lt;/code&gt; is found and returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetAddresses&lt;/code&gt; The array of facet addresses is returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facetFunctionSelectors(address _facet)&lt;/code&gt; The array of function selectors for the facet is returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;facets()&lt;/code&gt; The array of facet addresses is looped through to get each facet address and its function selectors. These are returned.&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that the loupe functions are read-only and are isolated in their own facet. They do not affect other facets of a diamond. Because of this the loupe functions do not increase complexity of the main application code or other facets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loupe functions require more gas for adding/replacing/removing functions&lt;/strong&gt; Loupe functions require that some data be stored in the diamond so that function selectors and facet addresses can be retrieved. The &lt;a href="https://github.com/mudgen/diamond-2"&gt;diamond-2&lt;/a&gt; implementation is the most efficient for adding/replacing/removing functions. It stores 8 function selectors in a single 32-byte contract storage slot and avoids storage reads and writes.&lt;/p&gt;

&lt;p&gt;I don't have gas metrics for diamond implementations that don't have loupe functions.  But I do have some gas metrics for diamond implementations that do have loupe functions. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;diamond-1 implementation&lt;/strong&gt; To add 20 functions from a single facet costs 617,348 gas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;diamond-2 implementation&lt;/strong&gt; To add 20 functions from a single facet costs 536,246 gas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;diamond-3 implementation&lt;/strong&gt; To add 20 functions from a single facet costs 683,000 gas.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Overall
&lt;/h2&gt;

&lt;p&gt;I think having events &lt;em&gt;and&lt;/em&gt; loupe functions is worth it. I've been working on &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535 Diamonds&lt;/a&gt; and diamond implementations to be useful for myself and you and others. So I am interested in your input about this. &lt;/p&gt;

</description>
      <category>smartcontracts</category>
      <category>solidity</category>
      <category>ethereum</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>How Diamond Storage Works</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Fri, 18 Sep 2020 12:57:03 +0000</pubDate>
      <link>https://dev.to/mudgen/how-diamond-storage-works-90e</link>
      <guid>https://dev.to/mudgen/how-diamond-storage-works-90e</guid>
      <description>&lt;p&gt;Diamond storage is a contract storage strategy that is used in &lt;a href="https://blog.openzeppelin.com/proxy-patterns/"&gt;proxy contract patterns&lt;/a&gt; and &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;diamonds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It greatly simplifies organizing and using state variables in proxy contracts and diamonds.&lt;/p&gt;

&lt;p&gt;Diamond storage relies on Solidity structs that contain sets of state variables that are easy to read and write.&lt;/p&gt;

&lt;p&gt;A struct can be defined with state variables and then used in a particular position in contract storage.  The position can be determined by a hash of a unique string. The string acts like a namespace for the struct. For example a diamond storage string for a struct could be &lt;code&gt;com.mycompany.projectx.mystruct&lt;/code&gt;.  That will look familiar to you if you have used programming languages that use namespaces.&lt;/p&gt;

&lt;p&gt;Namespaces are used in some programming languages to package data and code together as separate reusable units. Diamond storage packages sets of state variables as separate, reusable data units in contract storage. &lt;/p&gt;

&lt;p&gt;Let's look at a simple example of diamond storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;library&lt;/span&gt; &lt;span class="n"&gt;MyStructStorage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;MYSTRUCT_POSITION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.mycompany.projectx.mystruct"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MyStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;var1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;bytes&lt;/span&gt; &lt;span class="n"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;mapping&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;myStructStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; 
    &lt;span class="k"&gt;pure&lt;/span&gt; 
    &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyStruct&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;mystruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MYSTRUCT_POSITION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;assembly&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;mystruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diamond storage defined above can be used like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;external&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;MyStructStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MyStruct&lt;/span&gt; &lt;span class="k"&gt;storage&lt;/span&gt; &lt;span class="n"&gt;mystruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="n"&gt;MyStructStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;myStructStorage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="n"&gt;mystruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;var1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;var3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mystruct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;var3&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;

  &lt;span class="c1"&gt;// etc
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of using a hash of a string other schemes can be used to create random positions in contract storage. Here is a scheme that could be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight solidity"&gt;&lt;code&gt;&lt;span class="kt"&gt;bytes32&lt;/span&gt; &lt;span class="k"&gt;constant&lt;/span&gt; &lt;span class="n"&gt;MYSTRUCT_POSITION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nb"&gt;keccak256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encodePacked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;ERC1155&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;interfaceId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;ERC1155&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="kt"&gt;address&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Diamond storage is easy to use correctly, but like any tool it needs to be used correctly.&lt;/p&gt;

&lt;p&gt;Don't make these mistakes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Do not use the same namespace string for different structs.  Because the two structs will overwrite each other in storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't do the following: Deploy a contract that uses a particular struct. Then upgrade your contract with a modified version of the struct that is stored at the same location and with new state variables added or state variables removed in the beginning or middle. This is similar to storing two different structs at the same location in contract storage. However it is safe to add new state variables to the end of structs that are already being used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't put structs directly in structs unless you are sure you won't want to add new state variables to the end of the inner structs.  You won't be able to add new state variables to inner structs in upgrades.  But you can put structs in mappings, and still extend the structs in the future. To understand this more read about how state variables are laid out in contract storage here: &lt;a href="https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html"&gt;https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These mistakes are easy to avoid by being aware of them and keeping track of what namespaced strings are used. Also a naming convention can be used to give structs unique strings.&lt;/p&gt;

&lt;p&gt;Here are some additional references that cover diamond storage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mudgen/understanding-diamonds-on-ethereum-1fb"&gt;Understanding Diamonds on Ethereum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mudgen/solidity-libraries-can-t-have-state-variables-oh-yes-they-can-3ke9"&gt;Solidity Libraries Can't Have State Variables -- Oh Yes They Can!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/1milliondevs/new-storage-layout-for-proxy-contracts-and-diamonds-98d01d0eadb"&gt;New Storage Layout For Proxy Contracts and Diamonds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535: Diamond Standard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Diamond storage is also called common storage. Smart contract developer &lt;a href="https://medium.com/@plaxion"&gt;Jules Goddard&lt;/a&gt; writes about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/coinmonks/smart-contracts-sharing-common-data-777310263ac0"&gt;Smart Contracts Sharing Common Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/coinmonks/sharing-common-data-using-libraries-6573857d328c"&gt;Sharing Common Data Using Libraries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ethereum</category>
      <category>smartcontracts</category>
    </item>
    <item>
      <title>Should Diamond Loupe Functions Return Tightly Packed Data?</title>
      <dc:creator>Nick Mudge</dc:creator>
      <pubDate>Mon, 31 Aug 2020 22:03:55 +0000</pubDate>
      <link>https://dev.to/mudgen/should-diamond-loupe-functions-return-tightly-packed-data-5jg</link>
      <guid>https://dev.to/mudgen/should-diamond-loupe-functions-return-tightly-packed-data-5jg</guid>
      <description>&lt;h2&gt;
  
  
  Quick Background Material
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Diamond:&lt;/strong&gt; A diamond is a contract with functionality from multiple contracts that can share internal functions, libraries and state variables. Diamonds implement &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535 Diamond Standard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Facet:&lt;/strong&gt; The word facet comes from the diamond industry. It is a side, or flat surface of a diamond. A diamond can have many facets. In EIP-2535 Diamond Standard a facet is a contract that supplies a diamond with external functions. A diamond gets its external functions from facets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loupe:&lt;/strong&gt; A loupe is a magnifying glass that is used to look at diamonds. In EIP-2535 Diamond Standard the loupe is four standard functions that return what functions and facets a diamond currently has.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Tightly Packed Encoding vs ABI Encoding
&lt;/h2&gt;

&lt;p&gt;Currently, three of the diamond loupe functions return a tightly packed bytes array. &lt;/p&gt;

&lt;p&gt;The great thing about a tightly packed bytes array is that it doesn't waste bytes. A tightly packed bytes array doesn't contain any useless bytes containing the value 0, unlike ABI encoded arrays.&lt;/p&gt;

&lt;p&gt;The alternative to a tightly packed bytes array is an ABI encoded array.&lt;/p&gt;

&lt;p&gt;ABI encoded arrays are the default data encoding used by Solidity contracts. They are more standard than tightly packed bytes arrays and are easy to use. You or something has to encode/decode tightly packed bytes arrays. Ethereum contracts and tools handle all the encoding/decoding of ABI encoded arrays for us. &lt;/p&gt;

&lt;p&gt;But ABI encoded arrays are very inefficient, wasting bytes. ABI encoding uses 32 bytes for many values when that many bytes are not needed.&lt;/p&gt;

&lt;p&gt;Let's look at some loupe functions:&lt;/p&gt;

&lt;h3&gt;
  
  
  facetAddresses loupe function
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;facetAddresses&lt;/code&gt; loupe function returns a bytes array of all facet addresses currently used by a diamond. The bytes array is tightly packed so every byte in the array is used.&lt;/p&gt;

&lt;p&gt;Instead of returning a bytes array of addresses the &lt;code&gt;facetAddresses&lt;/code&gt; function could return an ABI encoded array of addresses. &lt;/p&gt;

&lt;p&gt;Let's compare the two approaches:  Let's say that a diamond has 10 facet addresses. An address is 20 bytes in size.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using a tightly packed bytes array the size is 200 bytes. Because 10 * 20 = 200.&lt;/li&gt;
&lt;li&gt;Using an ABI encoded array of addresses the size is 320 bytes. Because 32 * 10 = 320. Each value in the array has 32 bytes and only 20 bytes of each value is used. For many values ABI encoding uses 32 bytes whether they need them or not.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  facetFunctionSelectors loupe function
&lt;/h3&gt;

&lt;p&gt;The loupe function &lt;code&gt;facetFunctionSelectors&lt;/code&gt; returns a tightly packed bytes array of all function selectors currently used by a diamond. &lt;/p&gt;

&lt;p&gt;Instead of using a tightly packed bytes array it could return an ABI encoded array of bytes4 values.&lt;/p&gt;

&lt;p&gt;Let's compare the two approaches:  Let's say that a diamond has 100 function selectors. Each function selector is 4 bytes in size.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using a tightly packed bytes array the size is 400 bytes. Because 100 * 4 = 400.&lt;/li&gt;
&lt;li&gt;Using an ABI encoded array of bytes4 the size is 3200 bytes. Because 100 * 32 = 3200. Each value in the array has 32 bytes even though only 4 of the bytes are used in each value. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  facets() loupe function
&lt;/h3&gt;

&lt;p&gt;This function returns an array of tightly packed bytes arrays. Each bytes array holds a facet address and the function selectors associated with the facet address.  I'll let you or someone else figure out or make a comparison of tightly packed encoding and ABI encoding for this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  So What Should Diamonds Use?
&lt;/h2&gt;

&lt;p&gt;Tightly packed encoding is efficient.&lt;/p&gt;

&lt;p&gt;ABI encoding is inefficient.&lt;/p&gt;

&lt;p&gt;But ABI encoding is very standard and used by all Ethereum tools and software. ABI encoding is easier to use and write software with. It is nice. Maybe that matters more than the efficiency of data encoding.&lt;/p&gt;

&lt;p&gt;I originally chose tightly packed bytes array return values for EIP-2535 Diamond Standard because I envisioned that there would be thousands of diamonds in the world and off-chain client software continuously calling the loupe functions to provide information about diamonds. Tightly packed bytes arrays would reduce bandwidth costs and perhaps offer other scaling advantages. But in a world where computing resources are already cheap and getting cheaper, maybe it doesn't matter. Maybe easier software now matters more. &lt;/p&gt;

&lt;p&gt;Easier to write software can have less bugs.&lt;/p&gt;

&lt;p&gt;So what do you know and think?   Should EIP-2535 Diamond Standard be changed to use ABI encoded array return values for the loupe functions?  Or should it continue to use tightly packed bytes arrays?&lt;/p&gt;

&lt;h1&gt;
  
  
  UPDATE 6 September 2020
&lt;/h1&gt;

&lt;p&gt;Thanks to all the developers &lt;a href="https://twitter.com/mudgen/status/1300560237204824065"&gt;who provided their feedback and input&lt;/a&gt; about whether the loupe function return values should be ABI encoded or tightly packed.&lt;/p&gt;

&lt;p&gt;It was interesting to discover that developers were as mixed about it as myself. &lt;/p&gt;

&lt;p&gt;I removed the tightly packed encoding of loupe function return values from &lt;a href="https://eips.ethereum.org/EIPS/eip-2535"&gt;EIP-2535 Diamond Standard&lt;/a&gt;. Loupe function return values now use ABI encoding.&lt;/p&gt;

&lt;p&gt;I made this change because at this time the data efficiency of tightly packed encoding isn't needed. In the future if it is needed or more useful then a new standard for efficient loupe functions can be written and used. In addition, at any time developers can write their own diamond related information retrieval functions with whatever data encoding efficiency they desire and use them while at the same time providing the four standard loupe functions.&lt;/p&gt;

&lt;p&gt;ABI encoded return values are a bit easier to work with, a bit easier to learn and understand. In addition, something unexpected was discovered. &lt;/p&gt;

&lt;p&gt;Recent research has shown that it is possible to make all the diamond loupe functions gas-efficient enough to be executed in on-chain transactions. ABI encoding simplifies the code to do this and may save gas.&lt;/p&gt;

&lt;p&gt;Currently the &lt;a href="https://github.com/mudgen/Diamond"&gt;diamond reference implementation&lt;/a&gt; is gas-optimized to use the least gas for adding/replacing/removing any number of functions. The loupe functions in the diamond reference implementation are great for off-chain software to use to show what functions and facets a diamonds use. But it costs too much gas to call the loupe functions in on-chain transactions. But it doesn't have to be this way.&lt;/p&gt;

&lt;p&gt;It is possible to instead make the loupe functions gas-optimized for execution in on-chain transactions.&lt;/p&gt;

&lt;p&gt;It is also possible to make the loupe functions gas-optimized for adding/replacing/removing functions and for execution in on-chain transactions. It would require a lot of code and be complicated but I think it is worth doing. &lt;/p&gt;

&lt;p&gt;I think it would be interesting and awesome to have gas-efficient diamonds where you can query and process its functions in on-chain transactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Find a job developing smart contracts using Solidity at &lt;a href="https://delegatecall.careers"&gt;delegatecall.careers&lt;/a&gt;&lt;/em&gt;
&lt;/h3&gt;

</description>
      <category>ethereum</category>
      <category>blockchain</category>
      <category>diamonds</category>
      <category>solidity</category>
    </item>
  </channel>
</rss>
