Smart Contracts
For this course, we're assuming you have a general understanding of what the blockchain is and how it works. If you don't, we recommend you take a look at the Blockchain Fundamentals course first.
What are Smart Contracts?
Smart contracts are code deployed to the blockchain that will consistently execute the same way every time it gets called. Immutability is one of the reasons they are considered so powerful. On the other hand, in a rapidly evolving industry, being unable to change something once it has been deployed is not always the best solution. We'll explore more about this in other courses as it's a bit more advanced.
When a smart contract is deployed, it is assigned an address - similar to how you get an address when you create an account. Whenever you want to execute one of the functions in the contract, you will send the request to the contract’s address.
The reason they are called contracts is because they are like a contractual agreement that can not be changed.
Why are Smart Contracts Useful?
Smart contracts are useful when you want to have a decentralized and trustless system. They are also useful when you want to have a system that is always available and can not be shut down. This is because code deployed to the blockchain is ran by the nodes in the network. Building on our understanding of nodes, we know that if you'd want to shut down a smart contract, you'd have to shut down every node in the network. This is not possible in a decentralized network.
To emphasize the power of this, let's look at a real world example. Let's say you have an in-store credit account with some store. Since your credit only exists in that store, if they were to close your account or go bankrupt, you would lose all of your credit. This is a centralized system.
Now, let's say you have a smart contract that holds your credit. Since the smart contract is deployed to the blockchain, it can not be shut down. This means that your credit is always available and can not be taken away from you. (I'd like to point out that this is a very simple example and there are many other factors that would need to be considered in a real world scenario.)
How are Smart Contracts created?
Smart contracts are written in a programming language. The specific language depends on the blockchain itself and sometimes personal preference. For example, this is a table of the most popular languages for Ethereum smart contracts:
Chain | Languages |
---|---|
Ethereum | Solidity, Vyper, LLL, Serpent |
EOS | C++ |
NEO | C#, Java, Python |
Cardano | Haskell |
Tron | Solidity |
NEAR | Rust, Javascript |
This is not an exhaustive list, but it gives you an idea of the variety of languages that are used.
What are some examples of Smart Contracts?
There are many examples of smart contracts. Here are a few:
- A token contract (For example, an NFT contract or a fungible token contract).
- A smart contract that allows you to use your wallet and trade your currencies for other cryptocurrencies. (For example, an exchange.)
- A smart contract that holds your cryptocurrency. (For example, a wallet.)
Other examples:
- A smart contract that holds your credit for a store (as mentioned above).
- A smart contract that holds your identity information to be used in a decentralized application. (For example a Unique ID, KYC status, which country you're from, etc.)
How do Smart Contracts work?
Smart Contracts Diagram by Timo KlaaseeSo let's break it down:
- A transaction is submitted to the blockchain. This transaction contains the function that was called, as well as the parameters included.
- The transaction is validated by the nodes in the network. This includes checking the signature, checking the nonce, checking the gas price, and checking the gas limit.
- The transaction is executed and the result is recorded in a temporary state. This temporary state is not yet added to the blockchain as the gas is not yet deducted from the sender's account.
- Gas is deducted from the sender's account as the function is executed. This is to pay the nodes for the work they are doing. If the sender does not have enough gas, the transaction will fail.
- The block is included in the blockchain via consensus. This is done by the nodes in the network as we learned in the Blockchain Fundamentals course.
- The state trie (state database) is updated. This means that the transaction is now a part of the blockchain and is immutable.
What is Gas?
Gas refers to the fee that is paid to miners who process transactions. Currently, there are 2 "types" of gas in Ethereum:
- The base fee, which is the minimum amount of gas required to execute a transaction. The more complex your transaction is, the more gas will be required to execute it.
- An optional priority fee, which is an additional fee that can be paid to miners to prioritize your transaction. This is optional and is not required to execute a transaction, but it will influence how quickly your transaction is processed.
It's important to understand exactly what gas is, because when you are creating smart contracts, you want to make sure to optimize your code as much as possible, in order to keep the base fee as low as possible.
What is Gas Limit?
Gas limit refers to the maximum amount of gas that can be used to execute a transaction. This is set by the sender of the transaction. There is also a block limit, which is the maximum amount of gas that can be used in a block. This is set by miners.
It's important to understand that if a transaction fails, the sender will still need to pay the gas fee used during execution.
What is Gas Price?
Gas price refers to the amount of Ether that is paid per unit of gas. This is set by the sender of the transaction. Your execution time will be determined by your gas price relative to the network's gas price. You can think of it as a bidding system. The higher your gas price, the more likely your transaction will be processed quickly.
DO NOT just set this price to a very high value as you will pay a lot of fees. You can always check the current gas price on a site like Etherscan.
Setup for the Smart Contracts Development
Prerequisites
To set up your environment for smart contract development, you will need to install the following:
-
A text editor. I recommend Visual Studio Code. It's free and you can also install a Solidity extension to help you with your code.
-
An ethereum testnet wallet. You can create one on Metamask. You will need to install the Metamask extension on your browser. If you want to know more about wallets, how they work and how to create wallets on different blockchains, check out our Wallets Master Class course.
-
We will be using Hardhat to compile and deploy our smart contract. Hardhat is a development environment to compile, deploy, test, and debug your Ethereum software. It helps developers when building smart contracts and dApps locally before deploying to the Ethereum network. Follow this installation guide to install Hardhat on your computer: https://hardhat.org/getting-started/.
-
You will also require a Node.js installation. I'd recommend installing the latest LTS version.
-
Lastly, make sure to install npx by running the following command in your terminal:
1pnpm install -g npx # You can use npm or yarn if you prefer.
Creating a project structure
To create our project skeleton that will be used by all future courses, create a new folder in which you will initialize your project. I will be calling mine Crypto-Unveil-Smart-Contracts
. Then, navigate to the folder in your terminal and run the following command:
1npx hardhat init
Make sure to select Create a TypeScript project
when prompted. The rest should be fine as default.
IMPORTANT: Take note of the packages they tell you to install. It should be a hardhat package, as well as the hardhat-tools package. You will need to install these packages as dependencies in your project. You can do this by going into the folder and running the command they give you in the terminal. Remember to replace the package manager with the one you are using.
Once everything is done, you should have a project structure that looks like this:
1Crypto-Unveil-Smart-Contracts 2├── .gitignore 3├── hardhat.config.ts # This is where you will configure your hardhat project. 4├── package.json 5├── README.md 6├── tsconfig.json 7├── contracts # This is where you will write your smart contracts. 8│ └── Lock.sol 9├── scripts # This is where you will write your deployment scripts. 10│ └── deploy.ts 11├── test # This is where you will write your tests for your smart contracts. 12│ └── Lock.ts
Installing other dependencies
- For our testing we will be using chai and mocha, so install it with
1pnpm install chai mocha @types/chai @types/mocha
- We will be using a library with secure and reusable smart contracts to build from. The library is called OpenZeppelin. Install it with:
1pnpm install @openzeppelin/contracts
If you're ever creating a smart contract, please try and use a base from OpenZeppelin as they are audited and secure. It's always better to start from a secure and audited base than to start from scratch. It also saves a lot of time.
- We will also be using various node libaries you can install with the following command:
1pnpm install typescript ts-node @types/node dotenv
Cleaning up the project
Now let's clean up our folders and make sure we have everything we need to start developing our contracts.
In the contracts folder:
- Delete the
Lock.sol
file.
In the test folder:
- Delete the
Lock.ts
file.
Setting up .env, config and hardhat.config files
Create a .env
file in the root folder of your directory (at the same level as the hardhat.config
file) and add the following:
1// Keys 2ALCHEMY_API_KEY={alchemy key here} # We use Alchemy as our provider to deploy our contract 3SEPOLIA_PRIVATE_KEY={private key here} # This is the private key of our testnet wallet (for metamask you can find this in your account details **DO NOT SHARE THIS**) 4ETHERSCAN_API_KEY={etherscan key here} # We use Etherscan to verify our contract
Note: You can get your Alchemy key from https://www.alchemy.com/. You can get your Etherscan key from https://etherscan.io/.
We're also going to be creating a config file. Create a config.ts file in the root folder of your directory and add the following:
1import dotenv from "dotenv"; 2dotenv.config({ path: __dirname + "/.env" }); 3const configs = { 4 // keys 5 alchemy_key: process.env.ALCHEMY_API_KEY, 6 sepolia_key: process.env.SEPOLIA_PRIVATE_KEY, 7 etherscan_key: process.env.ETHERSCAN_API_KEY, 8}; 9 10export default configs;
Now, in the hardhat.config.ts
file, add the following code:
1import "@nomicfoundation/hardhat-toolbox"; 2import configs from "./config"; 3const { 4 alchemy_key, 5 alchemy_key_polygon, 6 goerli_key, 7 eth_private_key, 8 etherscan_key, 9 polygonscan_key, 10} = configs; 11 12/** @type import('hardhat/config').HardhatUserConfig */ 13module.exports = { 14 solidity: "0.8.18", 15 16 networks: { 17 sepolia: { 18 url: `https://eth-sepolia.g.alchemy.com/v2/${alchemy_key}`, 19 accounts: [sepolia_key], 20 }, 21 // ...more networks here 22 }, 23 24 etherscan: { 25 apiKey: { 26 sepolia: etherscan_key, 27 // ...more keys here 28 }, 29 }, 30};
We are importing our config file and using the keys from our config file to configure our deployment.
If you want to add more networks, you can do so by adding more networks like sepolia
in the networks
object. Just add the url of the provider and the private key of the wallet you want to use to deploy your contract.
Conclusion
In this course, we learned about smart contracts, why they are useful, how they work, and how to optimize them. We also learned about gas, gas limit, and gas price. You also learned how to set up a development environment for smart contract development.
Next up you can learn how to create and mint your own NFT from scratch or maybe learn to create and mint your own ERC20 token. Check out the next courses available in the Smart Contracts Series!