Problem
An award given should be proveable even if that physical representation of the award was lost, yet if the physical object is lost did the award every really exist.
Solution NFT
Having a way to represent ownership to digital content on the web is a very powerful feature. The decentralized nature of the blockchain or what I like to call very slow peer-to-peer databases gives that implicit trust that a smart contract was minted and cannot be changed, thus can represent ownership.
What are NFT
ERC-721, a non fugebal token. ERC-721 has a tokenid and each token is unqiue and each token represents a unique asset. Has on-chain and off-chain attributes. on-chain is desired since the attributes are proven by the cryptographic function to pull it on the chain.
References
How do you create an NFT
Goto
- https://opensea.io/
- Create an account by connecting your wallet. There are a few I suggest walletconnect.
- Click the hamburger icon and click connect wallet. Click Wallet Connect
- Click Trust (I use trust for the iphone)
- Complete your profile by valledating your opensea account
- opensea wallet walletconnect to iphone wallet:
0xd4f15be249bb9432a3cf870df0b781ee9eefa445
- create a collection
- add image to a collection
- upload your image
- add meta data
- set tokenURI to your metadata.json file, the image attibute is what is used to provide a photo for the nft
- Get a contract url
Developer tools to interact with ETH
- Infura makes developer tools
- Golang Eth list of resources for go engineers
- HardHat A recommended JS developer framework for building smart contracts
- Truffle The oldest framework, that has set a lot of standards and precendent. Many of the projects on github are probably truffle projects
- Brownie This is a python framework, depends on Web3.py and is the highest used
- Go-Ethereum Official Golang implementation of the Ethereum protocol. GETH is the main ETH CLI client. Geth is the main entry point into the ETH network exposing endpoints on top HTTP, WEBSOCKETS, or IPC transports.
- GETH Tutorial This is a tutorial on how to set up GETH
- Go Smart Contract Deploy This shows how to deploy a smart contract.
Environmental Setup for Development
We are going to use brownie and Solidity to code our nft. Additionally we are going to use the contracts by openzeplin
$ mkdir nft-idea && cd nft-idea
$ brownie init
Create a .env file and add infuria token and wallet token to your environment
export WEB3_INFURA_PROJECT_ID= # allows rest api to eth network
export PRIVATE_KEY= #metamask private key so we can interact with the wallet
export ETHERSCAN_TOKEN= #support for verifing things show up on etherscan
Download IPFS
curl -O https://dist.ipfs.io/go-ipfs/v0.10.0/go-ipfs_v0.10.0_darwin-amd64.tar.gz
Run IPFS
ipfs deamon
At this point we have the ability to write Solidity and run brownie to compile it and brownie can run a soon to be created deploy script for the contract.
THe following directory structure is made:
tests # where we will put our integration and unit tests
scripts # location of the python code that browine will execute to deploy, mint, update metadata
reports #
interfaces # interfaces for existing deployed contracts which are interacted with
contracts # this is where our Solidity code is located
build #output of solc
Writing the Contract
We are creating a nft factory to push out a certain token type. Within that contract we can then mint nfts. What we will do is create our own factory contract and mint the nft with that contract.
This is accomplished by a few steps
- create the brownie project defined above
- in contracts create a contract
- in the workspace directory add env settings and a brownie config to rewrite paths to github repos from python
- brownie compile
brownie compile
Brownie v1.17.0 - Python development framework for Ethereum
Compiling contracts...
Solc version: 0.6.6
Optimizer: Enabled Runs: 200
EVM Version: Istanbul
Generating build data...
- OpenZeppelin/openzeppelin-contracts@3.4.0/ERC165
- OpenZeppelin/openzeppelin-contracts@3.4.0/IERC165
- OpenZeppelin/openzeppelin-contracts@3.4.0/SafeMath
- OpenZeppelin/openzeppelin-contracts@3.4.0/ERC721
- OpenZeppelin/openzeppelin-contracts@3.4.0/IERC721
- OpenZeppelin/openzeppelin-contracts@3.4.0/IERC721Enumerable
- OpenZeppelin/openzeppelin-contracts@3.4.0/IERC721Metadata
- OpenZeppelin/openzeppelin-contracts@3.4.0/IERC721Receiver
- OpenZeppelin/openzeppelin-contracts@3.4.0/Address
- OpenZeppelin/openzeppelin-contracts@3.4.0/Context
- OpenZeppelin/openzeppelin-contracts@3.4.0/EnumerableMap
- OpenZeppelin/openzeppelin-contracts@3.4.0/EnumerableSet
- OpenZeppelin/openzeppelin-contracts@3.4.0/Strings
- CompanyAward
The project has been compiled. Build artifacts saved at /Users/dathan/workspace/award-nft/build/contracts
~/workspace/award-nft (main) [minikube|]
$
Upload a metadata json file and set the uri to that for the generated token once deployed
Tests
Unit tests are supported by brownie, as well as integration tests. Using the pytest package, define the test in tests/unit
Gas
Gas is very interesting, the ability to esitimate is really variable since its based on the compute power of the code being executed.
- What the net has to say
- another one
- web3.py
- web3.py read’s the last block to get the gas estimate in some instances
Finally deploy
brownie run scripts/foreveraward/deploy_contract.py --network=mainnet
Brownie v1.17.0 - Python development framework for Ethereum
AwardNftProject is the active project.
Running 'scripts/foreveraward/deploy_contract.py::main'...
On Network mainnet deploying contract for account: 0x64835C348e974B38d573145374EF72FdA51A72b3 with a balance of 340272419488868684 estimate gas of 53000 used gas 0 -> for Token ForeverAward <brownie.network.contract.ContractContainer object at 0x10fae6ac0>
Transaction sent: 0xabd1ea0bed6e0548476012e7046bec47a6c780efe7351f6aa3472a8805ed2edb
Gas price: 91.204135375 gwei Gas limit: 2630912 Nonce: 4
ForeverAward.constructor confirmed Block: 14033417 Gas used: 2391739 (90.91%)
ForeverAward deployed at: 0x42c9749AEf7e77D6930A82f148e457D8C991A2e8
Waiting for https://api.etherscan.io/api to process contract...
Verification submitted successfully. Waiting for result...
Verification pending...
Verification complete. Result: Pass - Verified
My Contract is live here