# Introducing Ethereum Package Manager (EPM) **Published by:** [Ken Codes](https://paragraph.com/@ken/) **Published on:** 2022-10-07 **URL:** https://paragraph.com/@ken/ethereum-package-manager ## Content *The future of smart contract development is composability.* ## TL;DR Last year I was experimenting with keeping NFT metadata entirely on-chain when I hit the [24kb EVM smart contract size limit](https://ethereum.org/en/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/). This limitation led me to try various workarounds like deploying libraries and additional contracts that call each other. It was messy to maintain and a nightmare to iterate on the contract code. Searching for a better way, I stumbled on [the (EIP-2535) Diamond Proxy Pattern](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard), created by [Nick Mudge](https://twitter.com/mudgen), which changed everything. Upgradability, infinite contract size, shared contracts. My mind was blown. 🀯 Since then, I've used the Diamond Pattern in all my smart contracts. Along the way I've developed a bunch of command line scripts to swap out functions ("diamond cuts") and automate some of the more tedious parts of iterating on and testing contracts. **But it still felt clunky.** And that's why I developed EPM. ## The Vision πŸ‘€ With a few clicks on a webpage, combine smart contracts created by other people (or myself) into my own contract. Maximize re-usability, minimize attack surface, and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). ## Features πŸ’‘ With EPM you can deploy a Diamond Proxy, attach facets to it, and then get even more granular by toggling functions on or off! See it for yourself: *Note: You won’t be able to edit anything since you don’t own the contract.* ![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9BOZqewiVaItELpDhlBV%2Fuploads%2FuslBgkSepAVfKBhCTfOT%2FScreen%20Shot%202022-08-17%20at%209.53.49%20AM.png?alt=media&token=52bc26cc-d3a5-4d47-8205-8b73837a1473) ### Generate Code Another area of development I found tedious was generating Typescript types for my contracts. With EPM you can download the combined types or ABI (all facet ABIs concatenated) with a click. Just for good measure, there's also a code example of integrating into a React app. ![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9BOZqewiVaItELpDhlBV%2Fuploads%2FIJohDIB1zOB3Dd62FQiq%2FScreen%20Shot%202022-09-07%20at%209.53.42%20AM.png?alt=media&token=d7d501d6-23ac-4863-a600-3f82526ea8eb) ### Bundles Combine facets, toggle functions, and save that configuration for easy deployment by you or someone else! ![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9BOZqewiVaItELpDhlBV%2Fuploads%2Ftf0HVXTpGaKiX5P6VLgG%2FScreen%20Shot%202022-08-18%20at%208.12.05%20AM.png?alt=media&token=cb7f4428-a6db-49e0-a9b3-2402a318be07) ### Other Uses EPM supports uploading and deployment of **any smart contract**. That means you can also use it for non-diamond contracts. ![](https://files.gitbook.com/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9BOZqewiVaItELpDhlBV%2Fuploads%2FLU9XQ8F6XCH6rWwqV1QV%2FScreen%20Shot%202022-09-07%20at%2011.22.40%20AM.png?alt=media&token=6036ed37-7cf4-42ab-902e-4b3a98ff7e6a) ## Use Cases ### Inheritance By Overriding Functions I've been experimenting with a sort of inheritance between contracts by having a base contract that implements a function, say `handleSaleDistribution(...)`, and a second contract that implements the same function. I turn the function off in the base contract and on in the second contract. Then, from the base contract I can still call the method. These don't have to both be contracts written by you. It could be that `BaseFacet` was uploaded to EPM by someone else. You just need to create `OverrideFacet` with a single function. The catch with using this pattern is that it requires you to call the function a little differently in the base contract: **BaseFacet.sol** ```sol contract BaseFacet { function handleSaleDistribution(address msgSender) public payable { if (msg.value == 0) { return; } // By default, send the funds back to the sender // Important: Do not use msg.sender here which will be this contract instead of the user initiating the transaction payable(msgSender).transfer(msg.value); } function mint() public payable { // ... minting logic // IMPORTANT: Call the method using this pattern instead of directly BaseContract contract = BaseContract(address(this)); contract.handleSaleDistribution{value: msg.value}(msg.sender); } } ``` **OverrideFacet.sol** ```sol contract OverrideFacet { function handleSaleDistribution(address msgSender) public payable { if (msg.value == 0) { return; } // Send all funds to Gitcoin payable(0xde21F729137C5Af1b01d73aF1dC21eFfa2B8a0d6).transfer(msg.value); } } ``` ### Contract Administration A simpler use case would be keeping an NFT mint off until a contract admin manually flips the switch on by enabling the corresponding function on the Diamond. ### Shared Business Logic It may already be obvious, but it's worth reiterating that Diamond Facets *can be shared* by multiple Diamond Proxies! This reduces the amount of duplicate code that needs to be deployed and by extension lowers deployment costs. [Nick Mudge just wrote about this](https://eip2535diamonds.substack.com/p/reusable-on-chain-facets-for-smart) ![](https://2213238710-files.gitbook.io/\~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F9BOZqewiVaItELpDhlBV%2Fuploads%2F7pjiBjRUCLczq4yOkKaS%2Fimage.png?alt=media&token=faa47924-218a-432a-8872-267c8d92384a) ## Related Projects I'm part of [Meem](https://build.meem.wtf/), a group of amazing people working to define the relationships between assets and humans with smart contracts. One of our other projects is [Clubs](https://clubs.link/) which provides tools for online communities. Behind the scenes, [Clubs](https://clubs.link/) is using EPM and the [Meem API](https://meem.gitbook.io/meem-protocol/meem-api/graphql-query-api) to manage contracts and upgrades. That means you can start with a Clubs contract and customize it with EPM to suit your needs. For more info read how to [Customize your Clubs Contract with EPM](https://meem.gitbook.io/meem-protocol/epm/epm-walkthrough/customize-clubs-contract). ## EPM Documentation πŸ“š The most up to date information about EPM, Meem, and Clubs. [EPM Documentation](https://meem.gitbook.io/meem-protocol/epm/ethereum-package-manager) [API Endpoints](https://meem.gitbook.io/meem-protocol/meem-api/api-endpoints-reference) ## Considerations πŸ€” * Careless upgrades that use [Diamond Storage](https://dev.to/mudgen/how-diamond-storage-works-90e) can cause data corruption in the data stored in the contract (πŸ€¦β€β™‚οΈ speaking from experience here). It's important to understand exactly how storage works and follow best practices to prevent issues. ## Next Steps πŸš€ It’s still early and there's a bunch of improvements that can be made to EPM. Just a few that come to mind are... * Design / UX updates (in progress) * Support more constructor data types when deploying contracts * Verified contracts / creators * Show audits * Links to source code * Better "my contracts" contract management / searching * Facet compatibility info / warnings * Ensure upgrades do not destroy data * Decentralized data source * Currently Meem maintains the database for EPM but ideally it would live in a decentralized database or shared data storage like IPFS Have an idea? Want to help develop EPM? Let's chat! ## Links [EIP-2535 Further Reading](https://meem.gitbook.io/meem-protocol/epm/eip-2535-further-reading) [EIP-2535 Resources](https://github.com/mudgen/awesome-diamonds) > **Get in touch** > > Twitter: [@kengoldfarb](https://twitter.com/kengoldfarb) > > Email: [hello@kengoldfarb.com](mailto:hello@kengoldfarb.com) > > Github: [kengoldfarb](https://github.com/kengoldfarb) > > [Farcaster](https://www.farcaster.xyz/): @kencodes \ ## Publication Information - [Ken Codes](https://paragraph.com/@ken/): Publication homepage - [All Posts](https://paragraph.com/@ken/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@ken): Subscribe to updates - [Twitter](https://twitter.com/kengoldfarb): Follow on Twitter ## Optional - [Collect as NFT](https://paragraph.com/@ken/ethereum-package-manager): Support the author by collecting this post - [View Collectors](https://paragraph.com/@ken/ethereum-package-manager/collectors): See who has collected this post