# **Understanding Diamond Contracts: Week 12 at Blockfuse** ## **Introduction to Diamond Contracts** Smart contracts are powerful tools, but scaling them can be tricky. As applications grow, maintaining flexibility and upgradeability becomes a challenge. That’s where Diamond Contracts comes in—they offer a modular approach that makes it easier to manage and expand complex systems. A **Diamond Contract** is a smart contract design pattern that allows multiple contract facets (modules) to work together under one main contract, called the **Diamond**. This structure enables modular development, making it easier to add, update, and manage functionalities without deploying an entirely new contract. In Week 12 at Blockfuse, we built a **Diamond Contract** with two facets and I worked on: - **UserProfileFacet**: Handles user profile management. - **NFTConFacet**: Manages NFT-related functionalities. This documentation explains how I structured the Diamond Contract and implemented its facets. --- ## **1. Diamond Contract Architecture** A Diamond Contract consists of: - **The Diamond Contract**: The main entry point, directing function calls to appropriate facets. - **Facets**: Modular contracts handling different functionalities. - **Diamond Storage**: A shared storage structure ensuring facets can access state variables. - **Diamond Cut**: A mechanism for adding, updating, or removing facets dynamically. ### **Diamond Contract Implementation** The core Diamond contract manages function delegation: ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./libraries/LibDiamondStorage.sol"; import "./interfaces/IDiamondCut.sol"; contract Diamond is IDiamondCut { constructor(address _contractOwner) { LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage(); ds.contractOwner = _contractOwner; } fallback() external payable { LibDiamondStorage.DiamondStorage storage ds = LibDiamondStorage.diamondStorage(); address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress; require(facet != address(0), "Diamond: 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()) } } } receive() external payable {} } ``` ### **How It Works** - **`fallback()` function**: Directs function calls to the appropriate facet using `delegatecall`. - **Storage pattern**: Uses **LibDiamondStorage** to store function selectors and their corresponding facet addresses. --- ## **2. Facets: Expanding Functionality** ### **UserProfileFacet: Managing User Profiles** This facet allows users to set and update their profile information. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract UserProfileFacet { string public userName; string public userBio; string public userEmail; uint256 public userAge; address public userWallet; string public userLocation; string public userWebsite; string public userAvatar; string public userTwitter; string public userGithub; function setUserName(string memory _name) external { userName = _name; } function setUserBio(string memory _bio) external { userBio = _bio; } function setUserEmail(string memory _email) external { userEmail = _email; } function setUserAge(uint256 _age) external { userAge = _age; } function setUserWallet(address _wallet) external { userWallet = _wallet; } function setUserLocation(string memory _location) external { userLocation = _location; } function setUserWebsite(string memory _website) external { userWebsite = _website; } function setUserAvatar(string memory _avatar) external { userAvatar = _avatar; } function setUserTwitter(string memory _twitter) external { userTwitter = _twitter; } function setUserGithub(string memory _github) external { userGithub = _github; } } ``` ### **NFTConFacet: NFT Management** This facet handles NFT-related operations, such as setting names, minting details, and royalty information. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract NFTConFacet { string public nftName; string public nftSymbol; string public nftBaseURI; uint256 public maxSupply; uint256 public currentSupply; address public admin; uint256 public mintPrice; string public nftDescription; string public nftLicense; string public royaltyInfo; function setNftName(string memory _name) external { nftName = _name; } function setNftSymbol(string memory _symbol) external { nftSymbol = _symbol; } function setBaseURI(string memory _uri) external { nftBaseURI = _uri; } function setMaxSupply(uint256 _maxSupply) external { maxSupply = _maxSupply; } function setCurrentSupply(uint256 _supply) external { currentSupply = _supply; } function setAdmin(address _admin) external { admin = _admin; } function setMintPrice(uint256 _price) external { mintPrice = _price; } function setNftDescription(string memory _desc) external { nftDescription = _desc; } function setNftLicense(string memory _license) external { nftLicense = _license; } function setRoyaltyInfo(string memory _royalty) external { royaltyInfo = _royalty; } } ``` --- ## **3. Key Takeaways from Building a Diamond Contract** ### ✅ **Scalability & Modularity** - The Diamond pattern allows us to add or modify functionalities without redeploying the entire contract. ### ✅ **Efficient Storage Management** - Using **LibDiamondStorage**, we ensure facets share a common storage structure. ### ✅ **Gas Optimization** - Unlike traditional upgradeable contracts, Diamond Contracts use **delegatecall**, reducing redundant state storage. ### ✅ **Challenges Faced & Lessons Learned** - **Facet Integration:** Ensuring proper function delegation was tricky at first, but understanding `fallback()` and `delegatecall` helped. - **State Management:** Avoiding conflicts in storage layout between facets required careful structuring. --- ## **Conclusion** Diamond Contracts offer a powerful way to build scalable and upgradeable smart contracts. This week at Blockfuse, I built a **Diamond Contract** with two key facets: **UserProfileFacet** and **NFTConFacet**. **Got feedback or questions? Drop them in the comments!** 🚀