# **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!** 🚀