Skip to content

Latest commit

 

History

History

getting-started

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Getting started developing for Optimism

Discord Twitter Follow

This tutorial teaches you the basics of Optimism development. Optimism is EVM equivalent, meaning we run a slightly modified version of the same geth you run on mainnet. Therefore, we the differences between Optimism development and Ethereum development are minor. But a few differences do exist.

Optimism endpoint URL

To access any Ethereum type network you need an endpoint. We recommend you get one from Alchemy, our preferred provider. See here for step by step directions on using Alchemy.

Alternatively, we have other great providers that support our networks.

Network choice

For development purposes we recommend you use either a local development node or Optimism Goerli. That way you don't need to spend real money. If you need ETH on Optimism Goerli for testing purposes, you can use this faucet.

The tests examples below all use Optimism Goerli.

Interacting with Optimism contracts

We have Hardhat's Greeter contract on Optimism Goerli, at address 0x106941459A8768f5A92b770e280555FAF817576f. You can verify your development stack configuration by interacting with it.

As you can see in the different development stacks below, the way you deploy contracts and interact with them on Optimism is almost identical to the way you do it with L1 Ethereum. The most visible difference is that you have to specify a different endpoint (of course). The list of other differences is here.

Hardhat

In Hardhat you use a configuration similar to this one.

Connecting to Optimism

Follow these steps to add Optimism Goerli support to an existing Hardhat project.

  1. Define your network configuration in .env:

    # Put the mnemonic for an account on Optimism here
    MNEMONIC=test test test test test test test test test test test junk
    
    # API KEY for Alchemy
    ALCHEMY_API_KEY=
    
    # URL to access Optimism Goerli (if not using Alchemy)
    OPTIMISM_GOERLI_URL=
  2. Add dotenv to your project:

    yarn add dotenv
  3. Edit hardhat.config.js:

    1. Use .env for your blockchain configuration:

      require('dotenv').config()
    2. Get the correct URL from the configuration:

      const optimismGoerliUrl =
         process.env.ALCHEMY_API_KEY ?
            `https://opt-goerli.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}` :
            process.env.OPTIMISM_GOERLI_URL
    3. Add a network definition in module.exports.networks:

    "optimism-goerli": {
       url: optimismGoerliUrl,
       accounts: { mnemonic: process.env.MNEMONIC }
    }   

Greeter interaction

  1. Run the console:

    cd hardhat
    yarn
    yarn hardhat console --network optimism-goerli
  2. Connect to the Greeter contract:

    Greeter = await ethers.getContractFactory("Greeter")
    greeter = await Greeter.attach("0x106941459A8768f5A92b770e280555FAF817576f")
  3. Read information from the contract:

    await greeter.greet()
  4. Submit a transaction, wait for it to be processed, and see that it affected the state.

    tx = await greeter.setGreeting(`Hardhat: Hello ${new Date()}`)
    rcpt = await tx.wait()  
    await greeter.greet()

Deploying a contract

To deploy a contract from the Hardhat console:

Greeter = await ethers.getContractFactory("Greeter")
greeter = await Greeter.deploy("Greeter from hardhat")
console.log(`Contract address: ${greeter.address}`)
await greeter.greet()

Truffle

In Truffle you use a configuration similar to this one.

Connecting to Optimism

Follow these steps to add Optimism Goerli support to an existing Truffle project.

  1. Define your network configuration in .env:

    # Put the mnemonic for an account on Optimism here
    MNEMONIC=test test test test test test test test test test test junk
    
    # API KEY for Alchemy
    ALCHEMY_API_KEY=
    
    # URL to access Optimism Goerli (if not using Alchemy)
    OPTIMISM_GOERLI_URL=
  2. Add dotenv and @truffle/hdwallet-provider to your project:

    yarn add dotenv @truffle/hdwallet-provider
  3. Edit truffle-config.js:

    1. Uncomment this line:

      const HDWalletProvider = require('@truffle/hdwallet-provider')
    2. Use .env for your network configuration:

      require('dotenv').config()
    3. Get the correct URL:

      const optimismGoerliUrl =
         process.env.ALCHEMY_API_KEY ?
            `https://opt-goerli.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}` :
            process.env.OPTIMISM_GOERLI_URL
    4. Add a network definition in module.exports.networks:

      "optimism-goerli": {
         provider: () => new HDWalletProvider(
            process.env.MNEMONIC,
            optimismGoerliUrl),
         network_id: 420
      }

Greeter interaction

  1. Compile the contract and run the console:

    truffle compile
    truffle console --network optimism-goerli
  2. Connect to the Greeter contact:

    greeter = await Greeter.at("0x106941459A8768f5A92b770e280555FAF817576f")
  3. Read information from the contact:

    await greeter.greet()
  4. Submit a transaction, wait for it to be processed, and see that it affected the state.

    tx = await greeter.setGreeting(`Truffle: Hello ${new Date()}`)
    await greeter.greet()

Contract deployment

You deploy a new contract from the console:

greeter = await Greeter.new("Greeter from Truffle")
console.log(`Contract address: ${greeter.address}`)
await greeter.greet()

Remix

Connecting to Optimism

In Remix you access Optimism through your own wallet.

  1. Add Optimism Goerli to your wallet. If you use Metamask, follow the directions here (starting at step 4), with these parameters:

    Parameter Value
    Network Name Optimism Goerli
    New RPC URL Either a third party provider or https://goerli.optimism.io
    Chain ID 420
    Currency Symbol GOR
    Block Explorer URL https://blockscout.com/optimism/goerli
  2. Log on with your wallet to Optimism Goerli.

  3. Browse to Remix.

  4. Click the run icon ().

  5. Select the Environment Injected Web3 Provider.

  6. Accept the connection in the wallet.

Greeter interaction

  1. Click the run icon ().

  2. Make sure your environment is Injected Web3 and the network ID is 420.

  3. Click the files icon ().

  4. Download Greeter.sol and upload () it to Remix under contracts.

  5. Right-click contracts > Greeter.sol and select Compile.

  6. Open contracts > artifacts and see that there's a Greeter.json file. This file is the compiled version, the API for the contract, etc.

  7. Click the run icon ().

    If you do not have Goerli ETH, get some using Paradigm's faucet and transfer it to Optimism by sending it to address 0x636Af16bf2f682dD3109e60102b8E1A089FedAa8.

  8. Scroll down. In the At Address field, type the contract address (0x106941459A8768f5A92b770e280555FAF817576f). Then, click At Address. Expand the contract to see you can interact with it.

  9. Click greet and expand the transaction result in the console (bottom right).

  10. Type a greeting and then click setGreeting. Approve the transaction in your wallet. Note that if the greeting includes a comma you need to enclose it in quotes.

  11. See the results on the console and then click greet again to see the greeting changed.

Contract deployment

You deploy a new contract:

  1. Type a string for the greeter.

  2. Click Deploy.

  3. Confirm the transaction in the wallet.

Foundry

Greeter interaction

Foundry does not give us a JavaScript console, everything can be done from the shell command line.

  1. Set the RPC URL and the contract address.

    export ETH_RPC_URL= << Your Goerli URL goes here >>
    export GREETER=0x106941459A8768f5A92b770e280555FAF817576f   
  2. Call greet(). Notice that the response is provided in hex.

    cast call $GREETER "greet()"
  3. Call greet() again, and this time translate to ASCII

    cast call $GREETER "greet()" | cast --to-ascii
  4. Put your mnemonic in a file mnem.delme and send a transaction.

    cast send --mnemonic-path mnem.delme $GREETER "setGreeting(string)" '"hello"' --legacy
  5. Test that the greeting has changed:

    cast call $GREETER "greet()" | cast --to-ascii

Contract deployment

Use this command:

forge create --mnemonic-path ./mnem.delme Greeter \
   --constructor-args "Greeter from Foundry" --legacy

Using the Optimism contract library

This library is provided as an npm package, which is different from what forge expects. Here is how you can import it without importing the entire Optimism monorepo:

  1. Install the JavaScript tools if you don't already have them: Node.js and yarn.

  2. Install the @eth-optimism/contracts library under lib.

    cd lib
    yarn add @eth-optimism/contracts
  3. If you are using git, add node_modules to .gitignore.

  4. The remapping that forge deduces is not the same as what you would have with hardhat. To ensure source code compatibility, create a file (in the application's root directory) called remappings.txt with this content:

    @eth-optimism/=lib/node_modules/@eth-optimism/
    

You can now run forge build with contracts that use the Optimism contract library.

To see this in action:

  1. Install the JavaScript libraries
cd foundry/lib
yarn
  1. Test the application

    cd ..
    forge test

Waffle

Starting from Waffle v4.x.x you can use Waffle chai matchers to test your smart contracts directly on an Optimism node.

Prerequisites

The tutorial makes these assumptions:

  1. You have Node.js running on your computer, as well as yarn.
  2. You have make installed on your computer (you can verify this by running which make in the terminal).
  3. You have a Goerli Optimism address with enough funds on it. You can use these faucets to get some free test funds.
  4. You have general understanding of smart contracts development.

Instructions

  1. Insert your mnemonic in the line 15 of ...waffle/test/mock-contract.test.ts to use your address in the test.

  2. In the terminal, run the following commands:

    cd waffle
    yarn
    yarn build
    yarn test

    You should see 2 tests passing.

  3. Play around with the code! Check out other available matchers in the Waffle documentation.

Compatibility with other tools

Note that in the tutorial we've been compiling smart contracts using Waffle. If you prefer to compile your smart contracts using other tools (like Hardhat) you can install the appropriate packages and modify build script in the package.json file.

Best practices

It is best to start development with the EVM provided by the development stack. Not only is it faster, but such EVMs often have extra features, such as the ability to log messages from Solidity or a graphical user interface.

After you are done with that development, debug your decentralized application using either a development node or the Kovan test network. This lets you debug parts that that are Optimism specific such as calls to bridges to transfer assets between layers.

Only when you have a version that works well on a test network should you deploy to the production network, where every transaction has a cost.