A Tour of Web 3: Ethereum & Smart Contracts with Solidity
Table of Contents
IntroductionThePrimeagen begins the course with a brief overview of Ethereum and a walkthrough of the course outline. The course will start with a basic "hello world" example and then pick up the pace with a lot of coding examples and the exploring of different types of contracts.
Getting Our Feet Wet
Create Your First Smart ContractThePrimeagen creates the project folder and installs hardhat which is the node module used to compile the contracts. The first Hello World contract is coded and compiled. Some common compile errors are also discussed in this segment.
Setup & Deploy to Test NetworkThePrimeagen installs the necessary testing dependencies and writes the unit test for the HelloWorld contract. The test checks to make sure the hello() method in the contract returns the string "Hello World".
Create a Deployment ScriptThePrimeagen uses hardhat to launch a local node-based network. Then a deployment script is written to deploy the contract to the local network. Twenty default accounts are auto-generated on the network for hardhat to use for any transactions. A question about the generation of the private keys is also covered in this segment.
Setup MetaMask ExtensionThePrimeagen installs the MetaMask browser extension. When the private key is imported and the localhost test network is selected, the extension will show the current Ethereum balance and track any activity.
Deploy Contract & Connect MetaMaskThePrimeagen codes a frontend to access the test network through the web browser. To access the contract, the page is supplied an address, and interface, and a provider. The provider is an ethereum object added to the window object by the MetaMask extension.
Web3 TerminologyThePrimeagen explains some common terminology like Web3, Ethereum, provider, contract, and wallet. The ethers library is abstracting the communication between the application and the network. The hardhat library provides the compiling, testing and deployment support.
Solidity Language BasicsThePrimeagen introduces the Solidity language and shares some common code structures like conditions, loops, and type declarations. Contracts are similar to classes. The base type in Solidity is a 256-bit unsigned integer.
Counter ContractThePrimeagen creates a counter contract as well as a deploy script. Unlike the hello world example, this contract changes state. The change in state creates a new block and triggers a gas fee.
Display Contract Count on WebsiteThePrimeagen refactors the website to display the count using the new view method and adds an increment button. The contract's address is moved into an environment variable to make it more reusable.
Signers & Waiting for TransactionsThePrimeagen adds a signer to the application which provides state-changing privileges. A signer is required because a provider only specifies how the contract can be accessessed and cannot change state. Since a transaction is asynchronous, the application needs to wait until the transaction is complete before updating the UI. Debugging NONCE errors is also covered in this segment.
Contract EventsThePrimeagen adds a CounterInc event to the contract. When the counter is updated, the event is emitted. Any connected clients will have the event pushed to them. Additional filters like the address of the sender can be included as well.
Alchemy Test NetworkThePrimeagen demonstrates how Alchemy is used to deploy the contract to a live test network. In this case, the test network is Rinkeby. An Alchemy API endpoint is specified in the hardhat.config.ts file. MetaMask then needs an authorized account for Rinkeby.
Gas OverviewThePrimeagen explains that the term "gas" refers to the transaction cost. The wei is the fundamental unit of ether. The gwei, or Gigawei is the typical measurement for gas.
Gas ReporterThePrimeagen demonstrates how to use the hardhat-gas-reporter module to estimate gas fees for a contract. The module is included in the hardhat config file. After the contract is created, a test script is written to call methods in the contract. The gas report is displayed in the console.
Game Contract SetupThePrimeagen begins building a basic RPG game and introduces some additional language features of Solidity. The contract is created and uses the enum type to manage the different player types. The payment modifier is added to any function that requires a monetary payment to be included with the function call.
Game Contract StorageThePrimeagen uses a mapping to store the heroes generated by the user. The mapping uses the address of the user as the key. The address will point to a list of uint values.
Generating Random NumbersThePrimeagen uses a random number generator to select a player attribute and assign a value. The attribute is then pushed into the addressToHeroes array. Issues with generating random numbers on the same block chain are also discussed in this segment.
Bits & Bit ShiftingThePrimeagen explains the differences between base10, base16, and base2 numbers. The left shift operator (<<) shifts the bits in a binary number to the left by adding zeros to the right of the number. It's the binary equivalent of multiplying a decimal number by 10.
Logical Operations on BitsThePrimeagen demonstrates how logical operators can be used to swap values or determine if a variable contains a certain value.
Reading from Storage MethodsThePrimeagen creates helper functions for reading the player attributes from memory. Since the attribute values are stored at specific byte locations within the mapping, the helper function left shifts to correct position and use the logical AND (&) operator to return the value.
Testing Storage MethodsThePrimeagen creates tests for a few player attributes. Since the attributes are randomly generated, the Hero contract is extended and the generateRandom method is overridden to return a value set by the test script.
Deploying ContractThePrimeagen shares a couple of the constraints around deploying contracts. There is a size limit of 24Kb and when a contract is updated, it gets a new address. Any previous transactions are associated with the old contract.
Diamond Pattern FallbacksThePrimeagen explains how the Diamond Pattern helps address contracts that are too large and scenarios where a contract needs to be updated. An external fallback method is created to handle any calls to methods that do not exist. In order for the fallback to work, non-existent methods should be defined in an interface.
Diamond Pattern Storage OverviewThePrimeagen demonstrates how memory is stored within the diamond pattern. Solidity attempts to pack bits as tight as possible. They will be added to storage in the order they are declared. Variables will share adjacent slots if they are small enough.
Diamond Pattern App StorageThePrimeagen creates an AppStorage struct to act as a common location for storing application data. The only issue with this storage solution is it has the potential to write into an already allocated storage block. The solution is to use assembly to select a random storage location.
Diamond Contract WalkthroughThePrimeagen clones a repository containing a diamond pattern template and walks through a more complex use case. Within the diamond pattern, a facet refers to a contract within the diamond. When a facet is cut, it is either added, removed, or changed. An init method is used to initialize a contract with the diamond's storage location rather than the individual contracts storage location.
Replacing Functions from the DiamondThePrimeagen replaces a function in contract A with a new return value. After the replacement, the function can still be called at the same address by using the diamond. If a function is removed, it can still be called using the diamond but an error will be thrown indicating the function no longer exists.
Q&AThePrimeagen answers questions about mutability in the blockchain, deploying new contracts, alternatives to the diamond pattern, and the public nature of code on the block chain.