Skip to content

Latest commit

 

History

History
242 lines (163 loc) · 7.55 KB

File metadata and controls

242 lines (163 loc) · 7.55 KB

Foundry NFT

This is a section of the Cyfrin Foundry Solidity Course.

⭐️ (7:40:56) | Lesson 11: Foundry NFT

We go through creating 2 different kinds of NFTs.

  1. An IPFS Hosted NFT
  2. An SVG NFT (Hosted 100% on-chain)

NFT Happy NFT Shiba NFT Frown


Getting Started

Requirements

  • git
    • You'll know you did it right if you can run git --version and you see a response like git version x.x.x
  • foundry
    • You'll know you did it right if you can run forge --version and you see a response like forge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)

Quickstart

git clone https://github.com/Cyfrin/foundry-nft-f23
cd foundry-nft-f23
forge install
forge build

Optional Gitpod

If you can't or don't want to run and install locally, you can work with this repo in Gitpod. If you do this, you can skip the clone this repo part.

Open in Gitpod

Usage

Start a local node

make anvil

Deploy

This will default to your local node. You need to have it running in another terminal in order for it to deploy.

make deploy

Deploy - Other Network

See below

Testing

We talk about 4 test tiers in the video.

  1. Unit
  2. Integration
  3. Forked
  4. Staging

This repo we cover #1 and #3.

forge test

or

forge test --fork-url $SEPOLIA_RPC_URL

Test Coverage

forge coverage

Deployment to a testnet or mainnet

  1. Setup environment variables

You'll want to set your SEPOLIA_RPC_URL and PRIVATE_KEY as environment variables. You can add them to a .env file, similar to what you see in .env.example.

  • PRIVATE_KEY: The private key of your account (like from metamask). NOTE: FOR DEVELOPMENT, PLEASE USE A KEY THAT DOESN'T HAVE ANY REAL FUNDS ASSOCIATED WITH IT.
  • SEPOLIA_RPC_URL: This is url of the goerli testnet node you're working with. You can get setup with one for free from Alchemy

Optionally, add your ETHERSCAN_API_KEY if you want to verify your contract on Etherscan.

  1. Get testnet ETH

Head over to faucets.chain.link and get some tesnet ETH. You should see the ETH show up in your metamask.

  1. Deploy (IPFS NFT)
make deploy ARGS="--network sepolia"
  1. Deploy (SVG NFT)
make deploySvg ARGS="--network sepolia"

Scripts

After deploy to a testnet or local net, you can run the scripts.

Using cast deployed locally example:

cast send <RAFFLE_CONTRACT_ADDRESS> "enterRaffle()" --value 0.1ether --private-key <PRIVATE_KEY> --rpc-url $SEPOLIA_RPC_URL

or, to create a ChainlinkVRF Subscription:

make createSubscription ARGS="--network sepolia"

Base64

To get the base64 of an image, you can use the following command:

echo "data:image/svg+xml;base64,$(base64 -i ./images/dynamicNft/happy.svg)"

Then, you can get the base64 encoding of the json object by placing the imageURI into happy_image_uri.json then running:

echo "data:application/json;base64,$(base64 -i ./images/dynamicNft/happy_image_uri.json)"

Estimate gas

You can estimate how much gas things cost by running:

forge snapshot

And you'll see and output file called .gas-snapshot

Formatting

To run code formatting:

forge fmt

Thank you!

If you appreciated this, feel free to follow me or donate!

ETH/Arbitrum/Optimism/Polygon/etc Address: 0x9680201d9c93d65a3603d2088d125e955c73BD65

Patrick Collins Twitter Patrick Collins YouTube Patrick Collins Linkedin Patrick Collins Medium

Test Data

happy svg base65= cmnd : base64 -i img/happy.svg:

data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHhtbG5z PSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgICA8Y2lyY2xlIGN4PSIxMDAiIGN5PSIx MDAiIGZpbGw9InllbGxvdyIgcj0iNzgiIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iMyIg Lz4KICAgIDxnIGNsYXNzPSJleWVzIj4KICAgICAgICA8Y2lyY2xlIGN4PSI2MSIgY3k9IjgyIiBy PSIxMiIgLz4KICAgICAgICA8Y2lyY2xlIGN4PSIxMjciIGN5PSI4MiIgcj0iMTIiIC8+CiAgICA8 L2c+CiAgICA8cGF0aCBkPSJtMTM2LjgxIDExNi41M2MuNjkgMjYuMTctNjQuMTEgNDItODEuNTIt LjczIiBzdHlsZT0iZmlsbDpub25lOyBzdHJva2U6IGJsYWNrOyBzdHJva2Utd2lkdGg6IDM7IiAv Pgo8L3N2Zz4=

Sad Svg:

data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHdpZHRoPSIxMDI0cHgi IGhlaWdodD0iMTAyNHB4IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB4bWxucz0iaHR0cDovL3d3 dy53My5vcmcvMjAwMC9zdmciPgogICAgPHBhdGggZmlsbD0iIzMzMyIKICAgICAgICBkPSJNNTEy IDY0QzI2NC42IDY0IDY0IDI2NC42IDY0IDUxMnMyMDAuNiA0NDggNDQ4IDQ0OCA0NDgtMjAwLjYg NDQ4LTQ0OFM3NTkuNCA2NCA1MTIgNjR6bTAgODIwYy0yMDUuNCAwLTM3Mi0xNjYuNi0zNzItMzcy czE2Ni42LTM3MiAzNzItMzcyIDM3MiAxNjYuNiAzNzIgMzcyLTE2Ni42IDM3Mi0zNzIgMzcyeiIg Lz4KICAgIDxwYXRoIGZpbGw9IiNFNkU2RTYiCiAgICAgICAgZD0iTTUxMiAxNDBjLTIwNS40IDAt MzcyIDE2Ni42LTM3MiAzNzJzMTY2LjYgMzcyIDM3MiAzNzIgMzcyLTE2Ni42IDM3Mi0zNzItMTY2 LjYtMzcyLTM3Mi0zNzJ6TTI4OCA0MjFhNDguMDEgNDguMDEgMCAwIDEgOTYgMCA0OC4wMSA0OC4w MSAwIDAgMS05NiAwem0zNzYgMjcyaC00OC4xYy00LjIgMC03LjgtMy4yLTguMS03LjRDNjA0IDYz Ni4xIDU2Mi41IDU5NyA1MTIgNTk3cy05Mi4xIDM5LjEtOTUuOCA4OC42Yy0uMyA0LjItMy45IDcu NC04LjEgNy40SDM2MGE4IDggMCAwIDEtOC04LjRjNC40LTg0LjMgNzQuNS0xNTEuNiAxNjAtMTUx LjZzMTU1LjYgNjcuMyAxNjAgMTUxLjZhOCA4IDAgMCAxLTggOC40em0yNC0yMjRhNDguMDEgNDgu MDEgMCAwIDEgMC05NiA0OC4wMSA0OC4wMSAwIDAgMSAwIDk2eiIgLz4KICAgIDxwYXRoIGZpbGw9 IiMzMzMiCiAgICAgICAgZD0iTTI4OCA0MjFhNDggNDggMCAxIDAgOTYgMCA0OCA0OCAwIDEgMC05 NiAwem0yMjQgMTEyYy04NS41IDAtMTU1LjYgNjcuMy0xNjAgMTUxLjZhOCA4IDAgMCAwIDggOC40 aDQ4LjFjNC4yIDAgNy44LTMuMiA4LjEtNy40IDMuNy00OS41IDQ1LjMtODguNiA5NS44LTg4LjZz OTIgMzkuMSA5NS44IDg4LjZjLjMgNC4yIDMuOSA3LjQgOC4xIDcuNEg2NjRhOCA4IDAgMCAwIDgt OC40QzY2Ny42IDYwMC4zIDU5Ny41IDUzMyA1MTIgNTMzem0xMjgtMTEyYTQ4IDQ4IDAgMSAwIDk2 IDAgNDggNDggMCAxIDAtOTYgMHoiIC8+Cjwvc3ZnPg==

CAST CALL FUNCTION COMMANDS: cast call 0x5FbDB2315678afecb367f032d93F642f64180aa3 "tokenURI(uint256) (string)" 0 --private-key $DEFAULT_ANVIL_KEY --rpc-url $RPC_URL