alchemy course
These are my notes from a course series by Alchemy
My GitHub Repo
Week 1: How to develop an NFT smart contract (ERC721) w/ alchemy
What is a smart contract? A piece of software that runs on a decentralized network of nodes (servers)
What is needed?
- solidity (language)
- node (alchemy)
- dev environment
- cryptocurrency
Goals: How to write a smart contract, get test eth, how to use alchemy, deploy to blockchain, how to interacts with NFTs on openseawriting a smart contract
using OpenZepplin and Remix IDE
- using the wizard allows you to write a smart contract without self-coding
- “NAME” is the project name, “SYMBOL” is coin symbol
Features:
- Mintable: yes, of course
- Auto increment IDs: individual id’s for each object
- Enumerable: checks value of accounts (whether or not a wallet/account has the token i think?)
- URI storage: metadata storage (i.e. exact token ID)
- Ownable: specifies ownership of project, not individual NFT
- Countable: NFTs are countable
you can always check the documentation on the openzepplin for troubleshooting now OPEN IN REMIX
modifying a smart contract with remix
- what is remix? “IDE” integrated developer environment, made to deploy solidity smart contracts
- first line ` // SPDX-License-Identifier: MIT ` specifies contract is open source but not to be used for commercial purpose
- private contract
Counters.Counter private _tokenIdCounter
indicates variables that are not going to be accessible externally - the mint function:
function safeMint(address to, string memory uri) public onlyOwner { uint256 tokenId = _tokenIdCounter.current(); _tokenIdCounter.increment(); _safeMint(to, tokenId); _setTokenURI(tokenId, uri); }
in these parts, variables specify that the mint happens directly to address, it is a public function (accessible to external users interacting with my smart contract),
onlyOwner
right now means that only the contract owner is allowed to mint… so we deleted that, as well as other lines indicatingownable
(see below) - deleted lines:
import "@openzeppelin/contracts@4.6.0/access/Ownable.sol";
- regarding the overrides, the notable one is the
function tokenURI(uint256 tokenId)
as it allows platforms like Opensea to get the URI of your token -
internal
variables/functions readable by smart contracts inheriting from ours -
view
variables/functions are only reading from the blockchain (not writing), marking asview
is a no gas interaction with the blockchain
modifications: - setting max supply (of 10,000)
Counters.Counter private _tokenIdCounter; uint256 MAX_SUPPLY = 10000;
- sold out message when max supply is reached
function safeMint(address to, string memory uri) public { uint256 tokenId = _tokenIdCounter.current(); require(tokenId <= MAX_SUPPLY, "I'm sorry all NFTs have been minted"); _tokenIdCounter.increment(); _safeMint(to, tokenId); _setTokenURI(tokenId, uri); }
The final contract:
/// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts@4.6.0/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts@4.6.0/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts@4.6.0/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract Talytest is ERC721, ERC721Enumerable, ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
uint256 MAX_SUPPLY = 10000;
constructor() ERC721("talytest", "TEST") {}
function safeMint(address to, string memory uri) public {
uint256 tokenId = _tokenIdCounter.current();
require(tokenId <= MAX_SUPPLY, "I'm sorry all NFTs have been minted");
_tokenIdCounter.increment();
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
}
// The following functions are overrides required by Solidity.
function _beforeTokenTransfer(address from, address to, uint256 tokenId)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId);
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
let’s deploy!
- create new app on Alchemy and copy the HTTP key
- in metamask, add new network “Alechmy Rinkeby” and paste the HTTP key into RPC url field
- getting rinkeby from faucet and link alchemy for additional 0.5eth deposit
back in remix - enter solidity compiler tab (left hand bar) and make sure compiler corresponds to contract line 2
pragma solidity ...
- turn on auto compile
- enter deploy & run transactions tab and connect to environment INJECTED WEB3, which will ask you for a wallet connection and ultimately connect you back to alchemy
- select CONTRACT by NAME (in my case, talytest), and then it’ll open your wallet to pay for gas to deploy it
- in “DEPLOYED CONTRACTS” tab dropdown, you can see the orange and blue functions… orange means it’s writing to blockchain, blue is viewing blockchain
minting
create metadata opensea metadata standard
- copy and paste the opensea metadata standard into a text editor (json file) i.e. Notepad++
- upload an image with filebase and create a new bucket with IPFS storage network (unchanging file)
- copy and paste the IPFS Gateway URL into the json file
"image": "https://ipfs.filebase.io/ipfs/bafkreiftim7yp4sfwaknbyio4uvjzwf6yka2boekuk56ybf3an6tfazhqa"
- input relevant traits and then save and upload the .json file into the same filebase bucket
- copy the metadata IPFS CID and paste into remix dropdown SAFEMINT variable to wallet address, make sure to add ipfs:// before the IPFS CID
- remix shows that I successfully minted, but it wont show up on opensea testnet…
OpenSea testnet still doesnt show it, but I got a tip to use rinkeby rarible and that was successful
Notes mentioning this note
W3
As a scientist, my primary interests are in the development of DeSci, but the deeper I fall into the space,...