Big Update: New Goerli Faucet Located Here. Kovan, Ropsten, and Rinkeby have been deprecated.
You'll need to verify via Twitter to get ETH & LINK. You can find Backup Faucets here.
Additionally, lesson 7 uses Chainlink VRF v1 instead of v2, you can find the docs for Chainlink VRFv1 here.
Welcome to the repository for the Ultimate Solidity, Blockchain, and Smart Contract - Beginner to Expert Full Course | Python Edition FreeCodeCamp course!
- Table of Contents
- Resources For This Course
- Lesson 0: Welcome To Blockchain
- Lesson 1: Welcome to Remix! Simple Storage
- Lesson 2: Storage Factory
- Lesson 3: Fund Me
- Lesson 4: Web3.py Simple Storage
- Lesson 5: Brownie Simple Storage
- Lesson 6: Brownie Fund Me
- Lesson 7: SmartContract Lottery
- Lesson 8: Chainlink Mix
- Lesson 9: ERC20s, EIPs, and Token Standards
- Lesson 10: Defi & Aave
- Lesson 11: NFTs
- Lesson 12: Upgrades
- Bonus Lesson 13: Full Stack Defi
- Closing and Summary
- Github Discussions
- Ask questions and chat about the course here!
- Stack Exchange Ethereum
- Great place for asking technical questions about Ethereum
- StackOverflow
- Great place for asking technical questions overall
- Setup your windows environment
- Learn how to install all the tools you will need for this course on a windows machine
- Chronological Issues from the Video
- A list of known hiccups/issues you may encounter while implementing the content from the video
- Bitcoin Whitepaper
- Ethereum Whitepaper
- Hybrid Smart Contracts
- Blockchain Oracles
- What is a blockchain
- Metamask
- Etherscan
- Goerli Etherscan
- Rinkeby Etherscan
- Kovan Etherscan
- Goerli Faucet
- Rinkeby Faucet (Check the link token contracts page)
- NOTE: You can always find the most up to date faucets at faucets.chain.link.
- OR, use the Kovan ETH Faucet, just be sure to swap your metamask to kovan!
- Gas and Gas Fees
- Wei, Gwei, and Ether Converter
- ETH Gas Station
- Blockchain Demo
- Public / Private Keys
- Layer 2 and Rollups
- Decentralized Blockchain Oracles
- Block Rewards
- Run Your Own Ethereum Node
Lesson 1: Welcome to Remix! Simple Storage
💻 Code: https://github.com/PatrickAlphaC/simple_storage
Everything in this section can be read about in the Solidity Documentation
- Versioning
- Compiling
- Contract Declaration
- Types & Declaring Variables
uint256
,int256
,bool
,string
,address
,bytes32
- Default Initializations
- Comments
- Functions
- Deploying a Contract
- Calling a public state-changing Function
- Visibility
- Scope
- View & Pure Functions
- Structs
- Intro to Storage
- Arrays - Dynamic & Fixed sized
- Compiler Errors and Warnings
- Memory
- Mappings
- SPDX License
- Recap
- A testnet or mainnet
- Find a faucet here
- Connecting Metamask
- Interacting with Deployed Contracts
- The EVM
Lesson 2: Storage Factory
💻 Code: https://github.com/PatrickAlphaC/storage_factory
- Factory Pattern
- Imports
- Deploy a Contract From a Contract
- Interact With a Deployed Contract
- Recap
Lesson 3: Fund Me
💻 Code: https://github.com/PatrickAlphaC/fund_me
- Payable
- Wei/Gwei/Eth Converter
- msg.sender & msg.value
- Decentralized Oracle Network Chainlink
- Blockchains can't make API calls
- Centralized Nodes are Points of Failure
- data.chain.link
- Getting External Data with Chainlink Oracles
- Decimals/Floating Point Numbers in Solidity
- latestRoundData
- Importing from NPM in Remix
- Interfaces
- Introduction to ABIs
- Getting Price Feed Addresses
- getPrice
- Tuples
- Unused Tuple Variables
- Matching Units (WEI/GWEI/ETH)
- getConversionRate
- Matching Units (Continued)
- SafeMath & Integer Overflow
- using keyword
- Libraries
- SafeMath PSA
- Setting a Threshold
- Require
- Revert
- Withdraw Function
- Transfer
- Balance
- this
- Contract Owners
- Constructor
- ==
- Modifiers
- Resetting
- for loop
- Array Length
- Forcing a Transaction
- Recap
Lesson 4: Web3.py Simple Storage
💻 Code: https://github.com/PatrickAlphaC/web3_py_simple_storage
- Developer Bootcamp Setup Instructions (metamask, vscode, python, nodejs..)
- VSCode
- VSCode Crash Course
- Extensions
- Short Cuts:
- Python
- Install Troubleshooting
- Terminal
- Making a directory/Folder
- Opening the folder up with VSCode
- Creating a new file
- Syntax Highlights
- Remember to save!
- Setting linting compile version
- VSCode Solidity Settings
- Formatting & Format on Save
- Solidity Prettier
- Python Black
- pip
- Reading our solidity file
- Running a Python Script in the Terminal
- MaxOS Shortcuts
- Windows Shortcuts
- Linux Shortcuts
- Compiling in Python
- py-solc-x
- compile_standard
- Colorized Brackets
- JSON ABI
- Saving Compiled Code
- Formatting JSON
- Deploying in Python
- Get Bytecode
- Get ABI
- Choose Blockchain to Deploy To
- Local Ganache Chain
- Web3.py
- HTTP / RPC Provider
- Private Keys MUST start with "0x"
- Contract Object
- Building a Transaction
- Account Nonce
- Calling "Constructor"
- Transaction Parameters
- Signing the Transaction
- NEVER put your private key directly in your code
- Setting Environment Variables (Windows, Linux, MacOS)
- Exported Environment Variables Only Last the Duration of the Shell/Terminal
- Private Key PSA
- .env file
- .gitignore
- Loading .env File in Python
- Viewing our Transaction / Deployment in Ganache
- Waiting for Block Confirmations
- 2 Things you always need
- Contract Address
- Contract ABI
- Getting address from transaction receipt
- Calling a view function with web3.py
- Call vs Transact
- Updating State with Web3.py
- ganache-cli
- Installing Ganache
- Working with ganache-cli
- Open a new terminal in the same window
- Deploying to a testnet
- Infura
- Alchemy
- Using Infura RPC URL / HTTP Provider
- Chain Ids
- Wow this seems like a lot of work... Is there a better way?
Lesson 5: Brownie Simple Storage
💻 Code: https://github.com/PatrickAlphaC/brownie_simple_storage
- Installing Brownie
- Install pipx
- pipx install eth-brownie
- Testing Successful Install
- A new Brownie project with
brownie init
- Project Basic Explanation
- Adding
SimpleStorage.sol
to thecontracts
folder - Compiling with
brownie compile
- Brownie deploy script
def main
is brownie's entry point
- brownie defaults to a
development
ganache
chain that it creates - Placing functions outside of the
main
function - brownie
accounts
- 3 Ways to Add Accounts
accounts[0]
: Brownie's "default" ganache accounts- Only works for local ganache
accounts.load("...")
: Brownie's encrypted command line (MOST SECURE)- Run
brownie accounts new <name>
and enter your private key and a password
- Run
accounts.add(config["wallets"]["from_key"])
: Storing Private Keys as an environment variable, and pulling from ourbrownie-config.yaml
- You'll need to add
dotenv: .env
to yourbrownie-config.yaml
and have a.env
file
- You'll need to add
- 3 Ways to Add Accounts
- Importing a Contract
- Contract.Deploy
- View Function Call in Brownie
- State-Changing Function Call in Brownie / Contract Interaction
transaction.wait(1)
test_simple_storage.py
- Arrange, Act, Assert
assert
brownie test
test_updating_storage
- Pytest / Brownie Test Tips
- Deploy to a Testnet
brownie networks list
- Development vs Ethereum
- Development is temporary
- Ethereum networks persist
- RPC URL / HTTP Provider in Brownie
- The network flag
list index out of range
get_account()
networks.show_active()
- build/deployments
- Accessing previous deployments
- Interacting with contracts deployed in our brownie project
brownie console
Lesson 6: Brownie Fund Me
💻 Code: https://github.com/PatrickAlphaC/brownie_fund_me
- Setup
- Dependencies
- chainlink-brownie-contracts
- remappings
- Deploy Script (V1)
helpful_scripts.py
__init__.py
- Deploy to Rinkeby
- Contract Verification (
publish_source
)- The Manual Way
- "Flattening"
- The Programatic Way
- Getting an Etherscan API Key
ETHERSCAN_TOKEN
- Interacting with Etherscan
- The Manual Way
- Deploying to Local Chains
- Introduction to Mocking
- Constructor Parameters
networks
in ourbrownie-config.yaml
- Copying Mock Contracts from chainlink-mix
- Deploying and using our mock
- Refactoring
- Deploying to a persistent ganache
- brownie attach
- Adding a persistent brownie network
- resetting a network build
- Whoops! Let's fix an issue...
- Fund Script
- Withdraw Script
test_can_fund_and_withdraw
- default networks
- pytest
pip install pytest
- pytest.skip
- brownie exceptions
mainnet-fork
- Custom mainnet fork
- Adding a development brownie network
brownie networks add development mainnet-fork-dev cmd=ganache-cli host=http://127.0.0.1 fork='https://infura.io/v3/$WEB3_INFURA_PROJECT_ID' accounts=10 mnemonic=brownie port=8545
- Alchemy
brownie test --network mainnet-fork
- brownie ganache vs local ganache vs mainnet-fork vs testnet...
- Installing Git
- Creating a repository
- First time with git
- Adding our project to github
- Tweet it out!
test_only_owner_can_withdraw()
gives below error if the selected network is Ganache UI::
E ValueError: Execution reverted during call: 'VM Exception while processing transaction: revert'. This transaction will likely revert. If you wish to broadcast, include `allow_revert:True` as a transaction parameter.
Lesson 7: SmartContract Lottery
💻 Code: https://github.com/PatrickAlphaC/smartcontract-lottery
- Add a
README.md
- Defining the project
- Is it decentralized?
- basic setup
- Main Functions
- address payable[]
- getEntranceFee & Setup
- Chainlink Price Feed
- brownie-config
- SPDX
- Matching Units of Measure
- Can't just divide
- Test early and often
- Quick Math Sanity Check
- deleting networks
- Alchemy again
- Enum
startLottery
- Openzeppelin... Is this the first openzeppelin reference?
- Openzeppelin Contracts Github
- Randomness
- Pseudorandomness
block
keywordblock.difficulty
block.timestamp
keccack256
- True Randomness with Chainlink VRF
- Chainlink VRF Remix Version
- Inheriting Constructors
- Oracle Gas & Transaction Gas
- Why didn't we pay gas on the price feeds?
- Chainlink Node Fees
- Request And Receive Introduction
- Kovan Faucets
- Funding Chainlink Contracts
- Request And Receive Explanation
- A Clarification
endLottery
returns (type variableName)
fulfillRandomness
override
- Modulo Operation (Mod Operation %)
- Paying the lottery winner
- Resetting the lottery
deploy_lottery.py
get_account()
refactoredget_contract
contract_to_mock
Contract.from_abi
- Adding the parameters to deploying to lottery
vrfCoordinatorMock
and adding mocksLinkToken
and Mocks- Successful Ganache Deployment!
- Python Lottery Scripts/Functions
start_lottery
- Brownie tip: Remember to
tx.wait(1)
your last transaction enter_lottery
end_lottery
- Funding with LINK
- brownie interfaces
- Waiting for callback
- Integration Tests & Unit Tests
- Test all lines of code
test_get_entrance_fee
pytest.skip
(again)test_cant_enter_unless_started
test_can_start_and_enter_lottery
test_can_pick_winner_correctly
- Events and Logs
callBackWithRandomness
topics
- conftest.py
Lesson 8: Chainlink Mix
💻 Code: https://github.com/smartcontractkit/chainlink-mix
Lesson 9: ERC20s, EIPs, and Token Standards
💻 Code: https://github.com/PatrickAlphaC/erc20-brownie-py
- ERC20/EIP20 Standard
- What is an ERC20?
- Creating an ERC20
- OpenZeppelin ERC20
- Solidity 0.8
- I Challenge you to code this yourself!
deploy_token.py
- Copy paste
helpful_scripts.py
- Viewing our token in metamask
- Adding to an exchange
Lesson 10: Defi & Aave
*NOTE: This repo is now archived as kovan is no longer supported. You can still follow along with the learning, but know the code may not work the same on a different testnet.
💻 Code: https://github.com/PatrickAlphaC/aave_brownie_py_freecode
- Defipulse
- Defillama
- Aave Testnet Site
- Paraswap
- Decentralized Exchange
- Kovan ETH
- What is Aave?
- Borrowing and Lending
- Connecting to Aave
- Depositing Tokens / Lending
- Checking your transaction is correct
- WETH Gateway
- Interest Bearing Token (aToken)
- Collateral
- DAI
- Stablecoin
- Wrapped Bitcoin (wBTC)
- Why borrow tokens?
- Blockchain Fintech Tutorial
- DISCLAIMER ABOUT BORROWING
- Borrowing Tokens
- Liquidations
- Your health factor must be above 1
- Solvent
- Stable vs Variable Interest Rate
- Repaying our borrows/loans
- Reward token / governance token
- Governance
- Quant Defi Engineer
- Aave Documentation
- Setup
- Converting ETH -> WETH
get_weth.py
- IWETH
- Kovan WETH Token Address: 0xd0a1e359811322d97991e03f863a0c30c2cf029c
- Mainnet WETH Token Address: 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
- Converting WETH -> ETH with
withdraw
aave_borrow.py
- LendingPool
- LendingPoolAddressProvider
- LendingPool and LendingPoolAddressProvider Addresses
- Fixing import dependencies
- Aave Github
- ERC20 Approve Function
- IERC20 from Patrick's repo
deposit
- getUserAccountData
- Liquidation Threshold
- Risk Parameters
- Borrowing DAI
- Getting DAI Conversion Rate
- borrow
- Mainnet DAI Address: 0x6b175474e89094c44da98b954eedeac495271d0f
- Aave Testnet Token Addresses
- Repaying
- Kovan Run
- Viewing the transactions
Lesson 11: NFTs
💻 Code: https://github.com/PatrickAlphaC/nft-demo
- End-to-end article
- What is an NFT?
- ERC721
- Token URI
- Token Metadata Example
- IPFS
- brownie mix
- Initial Setup
SimpleCollectible.sol
- OpenZeppelin ERC721
- Pug Image
- NFT Constructor
- NFT is a type of factory pattern
createCollectible
_safeMint
- TokenURI & Metadata
- Opensea listing example
- Is this decentralized?
- Ethereum Size and dStorage
- You need to have your NFT attributes both on-chain and inside your tokenURI metadata
deploy_and_create.py
- TokenURI used for the demo: https://ipfs.io/ipfs/Qmd9MCGtdVz2miNumBHDbvj8bigSgTwnr4SbyH6DNnpWdt?filename=0-PUG.json
- IPFS Companion
- Rinkeby Deployment
- Opensea Example
- What else with NFTs?
AdvancedCollectible.sol
- Dungeons and Dragons Example
- Double Inherited Constructors
createCollectible
(Advanced)tokenIdToBreed
- Working with in-flight Chainlink VRF requests
- Download the NFT images from the nft-mix
setTokenURI
_isApprovedOrOwner
- Emit events when you update mappings
indexed
event keyword
- Move
OPENSEA_URL
tohelpful_scripts
- Deploying AdvancedCollectible
- Opensea testnet is only compatible with Rinkeby
- Rinkeby Chainlink VRF Contract Addresses
- Speeding through adding functions from previous projects
- Deploy to Rinkeby
create_collectible.py
- A quick unit test
- A quick integration test
create_metadata.py
get_breed
- Metadata Folder
metadata_template
- NFT Metadata Attributes
- Checking if Metadata file already exists
- Uploading to IPFS
upload_to_ipfs
- Download IPFS Command Line
- Download IPFS Desktop
- HTTP IPFS Docs
ipfs daemon
- Pinata
- Pinata Docs
- Refactoring to not re-upload to IPFS
- Setting the TokenURI
- End-To-End Manual Testnet Test
- Viewing on Opensea
Lesson 12: Upgrades
💻 Code: https://github.com/PatrickAlphaC/upgrades-mix
- Original Video
- Smart Contracts can be upgraded!
- Does this mean they are not immutable?
- Trail of Bits on Upgradeable Smart Contracts
- The "Not Really Upgrading" / Parameterization Method
- The Social Yeet / Migration Method
- Contract Migration
- Proxies
- DelegateCall
- Terminology:
- Implementation Contract
- Proxy Contract
- User
- Admin
- Gotchas:
- Storage Clashes
- Function Selector
- Function Selector Clashes
- Proxy Patterns:
- Setup
Box.sol
BoxV2.sol
- Getting the proxy contracts
- Openzeppelin Proxy Github
01_deploy_box.py
- Hooking up a proxy to our implementation contract
- (Optional) Creating a Gnosis Safe
- Initializers
- Encoding Initializer Function
- Assigning ABI to a proxy
- Running the script
- Upgrade Python Function
- Testing our proxy
- Testing our upgrades
Bonus Lesson 13: Full Stack Defi
Note: This section is archived as kovan is now deprecated. If you're looking to learn more Full-stack, check out the full stack portions of the hardhat/javascript video.
Link to hardhat/javascript video with more full-stack examples: https://github.com/smartcontractkit/full-blockchain-solidity-course-js
💻 Code: https://github.com/PatrickAlphaC/defi-stake-yield-brownie-freecode
- FreeCodeCamp React
- What are we building?
- Setup
DappToken.sol
TokenFarm.sol
tokenIsAllowed
addAllowedTokens
- mapping of a mapping
stakeTokens
issueTokens
getUserTotalValue
getUserSingleTokenValue
getTokenValue
setPriceFeedContract
unStakeTokens
- Can this be reentrancy attacked?
deploy.py
- Deploying DappToken
- Deploying TokenFarm
- Adding allowed tokens
- ERC20 Kovan Faucet
- If the link above does not work, you can get another ERC20 token using this faucet: Weenus ERC20 Faucet
- Mocking our ERC20s
test_set_price_feed_contract
test_stake_tokens
- Fixtures
test_issue_tokens
- Now you try on tests!
- Front End Introduction
- Typescript
- React
- useDapp
- npx
- yarn
create-react-app
- Layout
- Testing Front End
- yarn && yarn start
- Connecting our wallets
- Install useDapp
- Header Component
- Connect Button
- Material-UI
- Making our button nicer
Main.tsx
- Sending
brownie-config
&build
folder to our UI - Helper Config
- TypeScript error suppression
- Getting addresses
- Ethers
- Only support kovan
- Sending
YourWallet
supportedTokens
- State Hooks
- Showing tokens
WalletBalance
ethersproject/units
BalanceMsg
- Stake Form
- Calling
approve
useContractFunction
useEffect
- Notifications
- Make it pretty
- Alerts
Shoutout to Matt for the help on the front end!
- Best Practices
- Attacks
- Damn Vulnerable Defi
- Ethernaut
- Some Auditors
- CryptoZombies
- Dapp University
- ChainShot
- Ivan on Tech
- Eat the Blocks
- Patrick Collins
- Austin Griffith
- Nader Dabit
- Ethereum.org
Be sure to check out project grant programs!
And make today an amazing day!