Tutorial on youtube Written tutorial version
This project mints Dynamic NFTs that change based on the market price of an asset pair (for example, the BTC/USD asset price). When prices go up, its a bull trend and when the go down its a bear trend. We run Chainlink Keepers to have our smart contract automatically called at specified intervals so that on-chain logic checks the Chainlink Price Feed to see if there has been a change in price. Accordingly the minted NFTs dynamically alternate between the images below.
The entire project is designed for ease of use by those new to Web3 and can be run from a Remix in-browser IDE and network environment.
Though this code base is minimally designed for use in Remix, it's always great to push yourself to expand your skills! We encourage you to learn and use more advanced tools like Hardhat and Truffle by
- cloning the Hardhat Starter Kit or the Truffle Starter Kit repos,
- dropping the smart contracts you write for this project into those repos,
- adapting the deploy scripts, interaction scripts and tests as scaffolded in those starter kits.
- Note : those starter kits include all the configuration you need to consider for deploying to test networks and also for Ethereum main nets. Be sure to read through the READMEs there to get a sense of what needs doing!
You can check out videos from the Chainlink Spring 2022 Hackathon on YouTube, especially the trainings on
You can even dig into Chainlink Smart Contract Examples to find more clever ways of extending your code!
All you need to run this code is the Remix IDE running in your browser and a Metamask wallet. While this repo includes mocks for you to "mimic" Chainlink oracle services, for your Assignment you will need to deploy to the Rinkeby test network.
When on test networks you will need test Ether and test LINK tokens in your Metamask wallet.
⚠️ Be sure to use only test ethereum accounts in Metamask when developing. You don't want to lose or spend real money!
This repo is organized in "layers". Each branch below represents the subsequent stage of the code buildup.
main
: has the starting code and the IPFS picture and json files. Also has the Dynamic NFT (ERC721) smart contract code.price-feeds
has the code that adds Chainlink Data Feeds logic and functionality along with the implementation of the Keepers interface so that our NFT Contract is Keepers compatible. It also has the mock Price Feeds smart contract calledMockPriceFeed.sol
which can be used to mock what calls to the actual Chainlink price feed would do. An example of what the return value from a price feed looks like is:int256 3034715771688
which denotes the price up to 8 decimals.
⚠️ When using Keepers, the logic in the callback function is for demo purposes only. It currently loops which is inefficient and costs a lot of gas (which gets converted to LINK). So, when registering your contract as an Upkeep, put in at least 500,000 as your callback gas limit. You may need to increase that depending on the then-current cost of ETH/LINK on the day (even on testnets).
randomness
contains the code for the assignment.
Update the NFT contract code to make the following happen:
- track the current market trend (hint: use an enum like
enum MarketTrend{BULL, BEAR}
) - update
performUpkeep
so that it tracks the latest market trend based on thegetLatestPrice()
and if there is a price change, it calls another function (egrequestRandomnessForNFTUris()
) that initiates the process of calling a Chainlink VRF V2 Coordinator for a random number. - implement
fulfillRandomWords()
as per the VRF documentation - test thoroughly in-browser, and then deploy to either Rinkeby or Polygon Mumbai test networks. We suggest you only use Rinkeby or Polygon Mumbai as you may have a smoother experience
A suggested implementation of the assignment is in the branch called randomness
.
Once deployed to one of the testnets mentioned above, your NFT should be viewable on Opensea testnets.
Note: if the dynamic NFT is taking time to change on OpenSea that's not unusual. In that even just call your contracts tokenUri()
method and check what IPFS URI is being pointed to. If it changes, then your code is working but OpenSea's cache may not show the new image for a while, even if you do a force-update on Open Sea. However, you should see the name of the NFT update even if the image is lagging.
Thank you for being curious and hungry to participate in the new Web3 movement! If you have any questions, reach out on Twitter or tag me on LinkedIn.
[Updated 14 June 2022]
Added basic testing on the main
branch to test deployment of the Bull&Bear.sol
NFT contract. Tests use mocha, chai, , ethers and waffle
. Please do yarn install
using the updated package.json
to pull down the developer dependencies needed to run the tests.
To run tests, from the project root, please run yarn hardhat test
.
[Updated 15 June 2022]
In the price-feeds
branch, extended the tests to include MockPriceFeed
. Note that the pragma and imported mock was updated to v0.7 to overcome the error that "interfaces cannot inherit interfaces" that was thrown on v0.6. Also added tests for keepers logic that uses the price feeds to dynamically update NFT data.