Material for the Linea Dev Cook-Off Mini-Bootcamp
Join our Academy Telegram Group to participate in our future workshops and bootcamps.
Kickstart your blockchain journey with our Linea Dev Cook-Off series!
This tutorial is your gateway to mastering smart contract development using Solidity. Perfect for beginners or as a refresher, we'll guide you through everything from the basics of Solidity syntax to deploying your first ERC20 contract on Linea.
What You'll Learn:
- Solidity fundamentals: syntax, structure, functions, and variables;
- Using Remix for smart contract compilation and deployment;
- Advanced concepts: interfaces, inheritance, tokens, and utilizing the OpenZeppelin library;
- Deploying and interacting with an ERC20 contract in Linea, including Metamask integration.
- Basic understanding of blockchain technology;
- A browser with an internet connection;
- A Web3 wallet like Metamask.
- Complete the Setup your Wallet guide to interact with Linea
- Follow the Fund your accounts guide to add some testnet tokens to your wallet
- Preferably, you can use the Covalent faucet to get some testnet tokens
- Alternatively, you can Bridge Sepolia ETH to Linea Sepolia if you have some Sepolia ETH available
- Follow the Remix guide to deploy your first sample smart contract
- Visit the Documentation to learn the main features of Remix for smart contract development
- Create a new Workspace for this tutorial using the
Remix Default
option - Use the File Explorer to find and open a file named
1_Storage.sol
- Use the Solidity Compiler to compile the smart contract that is open in the editor
- Make sure the compiler version is set to
0.8.19
for this tutorial, since we are going to deploy the contracts on Linea - It's advised to turn on the Auto compile option to automatically compile the contract whenever you make changes
- Make sure the compiler version is set to
- Use the Deploy & Run Transactions tab to deploy the compiled smart contract
- You can use the default
Virtual Machine
environment to test deploying and interacting with the smart contracts in a quick and practical way, even if you don't have testnet tokens
- You can use the default
- Connect your browser wallet to Remix by selecting the
Injected Web3
environment- Make sure the environment is set to
Injected Web3
and the account is connected to your wallet (e.g., Metamask) - You can use the
Deploy
button to deploy the contract- Differently from the
Virtual Machine
environment, you will need testnet tokens to deploy the contract, and you will be prompted to confirm the transaction on your wallet
- Differently from the
- Make sure the environment is set to
- Interact with the deployed contract using the
Deployed Contracts
section
-
Visit the Solidity Documentation
-
Using Remix, create a new file named
FrogJump.sol
-
Put an
SPDX-License-Identifier
at the top of the file and apragma
statement to specify the compiler version according to the Layout of a Solidity Source File specifications -
Plan the Structure of the contract
- The deployer should deploy the contract and set a
name
to the frog - Anyone should be able to call a function to get the
name
of the frog
- The deployer should deploy the contract and set a
-
Create a
contract
definition for theFrogJump
contract -
Add a State Variable named
name
of type string, and put it aspublic
Visibility to allow anyone to easily read it- Marking a state variable as
public
automatically creates a Getter function for it - Marking a state variable as
public
doesn't allow writing to it directly from outside of thiscontract
, like in other OOP languages
- Marking a state variable as
-
Create a Constructor function to set the
name
of the frog-
The constructor should receive a
string
parameter and set thename
state variable -
Solidity requires us to pick a
data location
for passing strings as parameters, and we should usememory
for this case -
Your code should look like this:
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; contract FrogJump { string public name; constructor(string memory name_) { name = name_; } }
-
-
Compile the contract using Remix
-
Deploy to a
Virtual Machine
environment and test the contract -
Append the contract to add a
jumps
state variable- The
jumps
state variable should be an Unsigned Integer (uint256
) type and ofpublic
visibility
- The
-
Append the contract to add a
jump
function- To declare a Function, even before implementing the actual code, you must set the Visibility, State Mutability and Function Parameters and Return Variables (if any)
- You can visualize all this rules and flows at the Language Grammar
- To declare a Function, even before implementing the actual code, you must set the Visibility, State Mutability and Function Parameters and Return Variables (if any)
-
Implement the
jump
function- The
jump
function should increment thejumps
state variable by one every time it is called - Your code should look like this:
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; contract FrogJump { string public name; uint public jumps; constructor(string memory name_) { name = name_; } function jump() public { jumps++; } }
- The
-
Creating an Interface for
IFrog
andIJumper
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IFrog { function name() external view returns (string memory); function jumps() external view returns (uint256); } interface IJumper { function jump() external; } contract FrogJump is IFrog, IJumper { string public name; uint256 public jumps; constructor(string memory _name) { name = _name; } function jump() public { jumps++; } }
-
Create another contract named
PayFrogJump
that inherits fromIFrog
andIJumper
-
Create a Constant named
PRICE
of typeuint256
and set it to1000000000000000000
- Alternatively, you can use the
1 ether
unit to set the value in a more readable way
- Alternatively, you can use the
-
Make the
jump
function Payable -
Create an
IPayableJumper
interface similar toIJumper
but sets thejump
function aspayable
-
Modify the
jumps
increment to be a function of the amount of Ether sent to the function- You can use the
msg.value
transaction property to get the amount of Ether sent- The best practice is to use a Requirement (
require
) statement to check if the amount of Ether sent is equal to thePRICE
constant, or an exact multiple of it
- The best practice is to use a Requirement (
- Use a division to calculate the number of jumps based on the amount of Ether sent
- This is not a good practice since the division may result in a remainder, that will be rounded towards zero
- We are doing this way to visualize the problem in practice
interface IPayableJumper { function jump() external payable; } contract PayFrogJump is IFrog, IPayableJumper { string public name; uint256 public jumps; uint256 public constant PRICE = 1 ether; constructor(string memory _name) { name = _name; } function jump() public payable { jumps += msg.value / PRICE; } }
- You can use the
-
Compile and deploy the
PayFrogJump
contract using Remix -
Test the contract in a
Virtual Machine
environment by sending some Ether to thejump
function- Remember to choose the right contract in the
Contract
dropdown before deploying - Input a number of Ether that is a multiple of the
PRICE
constant in theValue
field and selectEther
in the unit dropdown before clicking in the redjump
button- You should notice the
jumps
value increasing by the amount of Ether sent divided by thePRICE
constant
- You should notice the
- If you send an amount of Ether that is not a multiple of the
PRICE
constant, the division will result in a remainder that will be rounded towards zero- For example, if you send
1.5 ether
(1500000000000000000 wei
), the division will result in1
, and thejumps
value will increase by1
- Another extreme example, if you send
999999999999999999 wei
, the division will result in0
, and thejumps
value will not increase, even though you sent almost1 ether
to the contract
- For example, if you send
- Remember to choose the right contract in the
- Change the
PRICE
constant to0.001 ether
or lower in thePayFrogJump
contract- Since we haven't coded an
withdraw
function, we will not be able to get the Ether back from the contract, so it's better to use a lower value for testing and avoid running out of testnet tokens
- Since we haven't coded an
- Compile the
PayFrogJump
contract using Remix - Deploy the contract to Linea using the
Injected Web3
environment- Confirm that you are connected to the
Linea Sepolia
testnet- You should see
Custom (59141) network
under theEnvironment
dropdown in Remix
- You should see
- Make sure you have some testnet tokens in your wallet
- Confirm the transactions on your wallet when prompted
- Confirm that you are connected to the
- You can view the status of your transaction on the Linea Sepolia Explorer
- Example PayFrogJump named
Crazy Frog
- Example PayFrogJump named
-
Get to know the Ethereum Improvement Proposals and the Application-level standards and conventions for Ethereum
-
Check the ERC-20: Token Standard
-
Create a new
ERC20
compliant contract namedFrogToken
- Instead of creating a new contract from scratch, we will use the OpenZeppelin Contracts library to create an ERC20 token
- Remix has a tool for creating workspaces with contract templates for OpenZeppelin Contracts
- When creating a new workspace, select the
ERC20
option under theOpenZeppelin
section, and then leave all options as default
-
Rename the
MyToken.sol
contract toFrogToken.sol
-
Change the code of the
FrogToken
contract to set thename
andsymbol
asFrogToken
andFROG
, respectively -
Implement a
premint
feature in contract to set the initial supply- You can use the Contracts Wizard to quickly generate the code for this smart contract
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol"; contract FrogToken is ERC20, ERC20Permit { constructor() ERC20("FrogToken", "FROG") ERC20Permit("FrogToken") { _mint(msg.sender, 1000 * 10 ** decimals()); } }
-
Compile the
FrogToken
contract using Remix -
Deploy the contract to Linea using the
Injected Web3
environment -
Add the
FrogToken
contract to your wallet- You can use the
+ Import Tokens
feature in Metamask to add theFrogToken
contract to your wallet - You will need the
Token Address
to add the token to your wallet- You can find the
Token Address
in theDeployed Contracts
section in Remix, and also in your past transactions on the Linea Sepolia Explorer
- You can find the
- You can use the
-
Interact with the token by sending to other wallets, checking the balance, and approving transactions
Unlock the potential of dApp development for the Linea Dev Cook-Off with Scaffold ETH!
This tutorial covers everything from blockchain interaction and Linea integration to deploying smart contracts and crafting user interfaces.
What You'll Learn:
- Effective testing with a local blockchain;
- Deploying and debugging contracts easily with Scaffold ETH;
- Creating engaging UIs with React and NextJS;
- Exploring Viem and Wagmi libraries;
- Practical tips for developing user-friendly dApps.
-
Install Git CLI
-
Install Yarn and learn how to use it
-
Install VSCode and learn how to use it
Recommendation: Before starting, make sure that you have the correct version of Node installed in your system.
You can check your current version by running node -v in your terminal.
- Use Node Version Manager to install and use Node
v20 LTS
version to avoid problems
# For Linux/MacOS
nvm install --lts
...
nvm use --lts
...
node -v
v20.11.1
Suggestion: use
nvm-windows
from Corey Butler's community package for Windows.
# For windows
nvm install lts
...
nvm use lts
...
node -v
v20.11.1
-
Clone the ScaffoldETH repository
git clone https://github.com/scaffold-eth/scaffold-eth-2.git cd scaffold-eth-2
-
Install the dependencies
yarn install
-
Start the local blockchain
yarn chain
-
Deploy the contracts
Suggestion: since your terminal is busy running the local blockchain, you can open a new terminal tab or window to run the next commands
yarn deploy
-
Start the frontend
yarn start
- You should see the frontend running at
http://localhost:3000/
- You should see the frontend running at
-
Import your contracts to the ScaffoldETH project
- Create a new file in the
packages/hardhat/contracts
directory and paste theFrogJump.sol
contract code from previous lesson in it
- Create a new file in the
-
Create a deployment script for your contract
- Create a new file named
01_deploy_frog.ts
in thepackages/hardhat/deploy
directory and paste the following code in it
const deployFrogJump: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer } = await hre.getNamedAccounts(); const { deploy } = hre.deployments; await deploy("FrogJump", { from: deployer, args: ["Froggy"], log: true, autoMine: true, }); }; export default deployFrogJump;
- Create a new file named
-
Change the
version
settings for thesolidity
compiler in thehardhat.config.ts
to be0.8.19
(line24
)- You can find this file in the
packages/hardhat
directory
- You can find this file in the
-
Deploy the
FrogJump
contract and interact with it in the frontend using thedebugger
page
- Visit Speedrun Ethereum
- Follow the Challenge #0: 🎟 Simple NFT Example
- Replace the
nftsMetadata.ts
file underpackages/nextjs/utils/simpleNFT
with the file in this repository- Credits to the Efrogs maintainers for the NFT Collection and Element Market for hosting the images
- You may want to edit the
NFTCard.tsx
component underpackages/nextjs/components/simpleNFT
folder to display the frog images correctly- For example, you can change the
className
of theNFT Image
to display a squared box by usingclassName="h-60 w-60"
(read more about this in the Tailwind docs)
- For example, you can change the
- Complete the challenge and deploy your dApp to Linea Sepolia testnet
- Verify your contract
- View your collection in Testnets Opensea
- (Optional) Deploy your dApp to a hosting service like Vercel or similar