Writing Your First Contract on Optimism
This tutorial assumes that you know how to program, but that you've never dealt with smart contracts, much less written one. This tutorial is broken into 3 parts:
- Wallet setup: wallet software for private keys to sign transactions on network
- Block chain setup: get testnet ETH to pay for transactions on network
- Solidity interaction: deploying and interacting with smart contracts on the network, using your wallet and testnet ETH
If you are already familiar with Solidity, go to the guide on Communicating between OP Mainnet and Ethereum Using Solidity for more information on how to use OP Mainnet and OP Goerli with the tools you already know.
Wallet Setup
Before you can use Ethereum, you need wallet software (opens in a new tab). In this tutorial, we use MetaMask (opens in a new tab), a browser extension, as our wallet. You can also use MetaMask on a mobile device (iOS or Android), but for software development it is best to use a notebook or desktop computer.
Make sure you have either Chrome, Firefox, Brave, or Edge
Browse to MetaMask (opens in a new tab) and install MetaMask for your browser
Click Get Started
Click Create a wallet and then I agree
Type a password, accept the terms, and click Create
Click Next, reveal the secret words, and write them down somewhere safe
- We plan to only use this wallet for testing, so the key phrase should not matter that much, but it's best to develop good habits from the beginning.
Let MetaMask help you confirm you have the correct written key phrase
Copy your address, you'll need it soon
Blockchain Setup
In this tutorial, we'll use OP Mainnet (opens in a new tab), an Ethereum Layer 2 blockchain, to run our contracts.
Deploying contracts and interacting with them costs gas (opens in a new tab), which has to be purchased with Ether (also known as ETH). On the production network that Ether costs money, it is part of the security mechanism of Ethereum. To avoid spending real money, we'll use OP Goerli, a test network built on top of Goerli. The test network also requires ETH, but it is test ETH you can get for free.
Use this faucet (opens in a new tab) to obtain OP Goerli test ETH
Follow five github (opens in a new tab) users or organizations to get past the anti-Sybil defense.
Add Goerli (opens in a new tab) to your wallet
- Click Connect on the web page and then Approve in MetaMask.
Permit the network switch
See if you have anything on OP Goerli
Interacting with a Solidity contract
The most common smart contract development language is called Solidity (opens in a new tab). Here we will use using an integrated development environment (IDE) called Remix (opens in a new tab). It has the significant advantage of requiring minimal set up because it runs in your browser.
Go to Remix (opens in a new tab)
Click the Files icon
and open contracts > 1_Storage.sol
Click the Compiler icon 
Click Compile 1_Storage.sol
Click the Run icon 
Select the Environment Injected Provider
In MetaMask, click Next and then Connect to accept the connection in the wallet
To add the smart contract into the blockchain, click Deploy (in Remix) and Confirm the transaction in MetaMask
Expand the contract STORAGE AT ... and scroll down to see what you can do
To retrieve the current stored number, click retrieve
- Note that as this is a read-only operation.
- It does not cost anything and does not require MetaMask confirmation.
See the retrieved number right below the retrieve button
To change the number, type a value next to store and then click it
-
Because this is a transaction that affects the blockchain state it costs ETH and requires you to Confirm on MetaMask.
View the transaction information
-
In the Remix console (bottom right quadrant of the window), expand the bottom entry to see the transaction information
Verify that the transaction is now part of the permanent blockchain record
- Copy the transaction hash from the remix console.
- Open OP Goerli on Etherscan (opens in a new tab).
- Search for the transaction hash. -- Note that it may take a few minutes for Etherscan to get updated.
Check again that the value has changed
-
Back in Remix, click retrieve again to see that the value has changed.
How does it work?
To understand the Storage
contract, let's go over it line by line
// SPDX-License-Identifier: GPL-3.0
The Solidity compiler expects every source file to have a license comment. See the list of supported licenses (opens in a new tab).
pragma solidity >=0.7.0 <0.9.0;
This line specifies the acceptable versions of the Solidity programming language. In this case we only allow 0.7.x and 0.8.x versions. This is important because Solidity is new and still developing rapidly, and therefore breaking changes (opens in a new tab) are necessary from time to time.
/**
* @title Storage
* @dev Store & retrieve value in a variable
*/
contract Storage {
Define a contract called Storage. A contract functions in many ways like a class in Object Oriented Programming (opens in a new tab). It contains variables and methods.
uint256 number;
This is a field variable. The type, uint, is a 256 bit unsigned integer. This is the standard type for evm (opens in a new tab) variables.
Note that all the fields in a contract are effectively public.
Ethereum code is executed by multiple computers in multiple locations, and can be verified by anybody.
This would be impossible if some part of the contract state had been unreadable.
A field variable being private
only means it cannot be ready by onchain code.
/**
* @dev Store value in variable
* @param num value to store
*/
function store(uint256 num) public {
This is a Solidity function definition (for a function without a return value). It includes:
- Function name (
store
) - Parameters (in this case there is only one,
num
) - A visibility modifier (in this case
public
, which makes the function callable from anywhere).
number = num;
}
The rest of the function is standard for languages derived from C.
/**
* @dev Return value
* @return value of 'number'
*/
function retrieve() public view returns (uint256){
This is another function definition, with a few differences:
- The function is defined as a
view
, which means it is a read-only function that doesn't change the state. As you have seen, calling this kind of function is free.
return number;
}
}
Next Steps
To learn more Solidity, we have a list of resources (opens in a new tab). If you learn best by reading source code, try here (opens in a new tab).