Inspiration

I'm pretty sure someone on NFT twitter put forth an idea for a "meta NFT" that would work similar to the GIMP example on the bottom of this. I was thinking about that a bit and thought that Chainlink tools would at least be able to serve as a proof of concept for something like that.

What it does

This project allows a user to create a Family Photo NFT (FAM). A Family Photo is an ERC-721 where each token stores pointers to other ERC-721 NFTs. A user will mint a new FAM which opens it up for that user or other users to "add" their own NFTs to it. "Add" being used loosely here - there isn't any actual token transfer. At some point, the minting user can decide to "finalize" the FAM they minted, which will generate an image for that FAM based on all the NFTs added to it. This is done via a custom Chainlink External Adapter currently deployed to Kovan (until my Linkpool node expires) Right now mainly IPFS image URI, URLs, or JSON are supported ways to find that image. Then, if a person who added their NFT to a FAM ever moves that NFT from their wallet, the FAM will automatically regenerate a new image with that NFT blacked out (well - darkened out). This is triggered via a Keeper job currently running on Kovan.

How we built it

I built this using Solidity, Python, and React and used tools like Brownie (VSCode), AWS Lambda, Linkpool running my External Adapter, and Chainlink Keepers on Kovan. I used plenty of example code from the Solidity Beginner to Expert freecodecamp, various Chainlink tutorials, and various Stackoverflow posts.

Challenges we ran into

This was my first real Smart Contract project so there was a bit of a learning curve to get proper syntax and structuring to work throughout the project.

Some interesting challenges were getting large responses to work with my Chainlink node and thus getting my External Adapter to properly trigger and handle my token URIs (Chainlink "Large Responses" tutorial helped a lot with this). In addition, it was tough to get my Keeper job to handle an array of data but I found that Linkpool's Keeper job on mainnet was actually doing something similar to what I wanted to do so I was able to copy their approach.

Accomplishments that we're proud of

I felt great about even finishing this project since this was my first time doing this. And getting an External Adapter AND a Keeper job up and running :).

What we learned

I learned a lot about the structure of NFTs and about how powerful External Adapter jobs can be since they're just running a bunch of Python in the cloud - you can pretty much do anything and that's very cool.

What's next for Family Photo

There's a lot of cool things that could be done to enhance this project. To start, there are definitely gas optimizations that could be done since I never really got a chance to go back and try to optimize what I'm doing.

It would be fun to add support for ERC-1155s and for CryptoPunks. I think that this could be a cool thing for NFT (Profile Pic)-based DAO-like groups like Bored Ape Yacht Club members to mint Family Photos of groups of members to show that they all have "iron hands" and will never get rid of their NFTs. Given that might be a cool use-case for this project, it would be cool to be able for the original minting user to specify a given dimension of the resulting image so they can determine how they want to use it ahead of time - for example, your Twitter banner requires a different image ratio than something like a profile picture.

I also wanted to get into using Filecoin instead of IPFS but didn't have time to get that running. Ideally if you're storing images to NFTs like this you have something safely persistent other than IPFS. On a related note, in a real deployment you'd probably want NFT-contributing users to send LINK/FIL or payment to convert to LINK and FIL along when they add their NFT to a Family Photoin order to cover future costs of maintaining the NFTs.

In my mind, the top really cool enhancements to this project are: 1) Cross-chain pointers via CCIP - since my NFTs are just storing pointers to NFTs, why not deploy this contract on a less gas-intensive L1 or L2 like Avalanche or Arbitrum and just point to NFTs on Ethereum mainnet? Most of the big NFT projects at this point are on mainnet but gas costs would be too prohibitive to allow this project to really work there. Since my EA is ultimately handling the work to handle my pointers and image manipulation, I wonder if I could use it to point across multiple chains too. 2) Think of something like GIMP as the image manipulation tool here rather than simply tiling out the image URIs. Given a really cool image manipulation layer on top of the frontend, you could do really cool collages of NFTs all mashed on top of each other in unique ways that then still black out if a user moves them.

Built With

Share this project:

Updates