Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions clients/ops-l2/genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,18 @@
},
"70997970C51812dc3A010C7d01b50e0d17dc79C8": {
"balance": "0x200000000000000000000000000000000000000000000000000000000000000"
},
"0000000000000000000000000000000000000314": {
"balance": "0x0",
"code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063a223e05d1461006a578063abd1a0cf1461008d578063abfced1d146100d4578063e05c914a14610110578063e6768b451461014c575b610000565b346100005761007761019d565b6040518082815260200191505060405180910390f35b34610000576100be600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506101a3565b6040518082815260200191505060405180910390f35b346100005761010e600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506101ed565b005b346100005761014a600480803590602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610236565b005b346100005761017960048080359060200190919080359060200190919080359060200190919050506103c4565b60405180848152602001838152602001828152602001935050505060405180910390f35b60005481565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b5050565b7f6031a8d62d7c95988fa262657cd92107d90ed96e08d8f867d32f26edfe85502260405180905060405180910390a17f47e2689743f14e97f7dcfa5eec10ba1dff02f83b3d1d4b9c07b206cbbda66450826040518082815260200191505060405180910390a1817fa48a6b249a5084126c3da369fbc9b16827ead8cb5cdc094b717d3f1dcd995e2960405180905060405180910390a27f7890603b316f3509577afd111710f9ebeefa15e12f72347d9dffd0d65ae3bade81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a18073ffffffffffffffffffffffffffffffffffffffff167f7efef9ea3f60ddc038e50cccec621f86a0195894dc0520482abf8b5c6b659e4160405180905060405180910390a28181604051808381526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a05b5050565b6000600060008585859250925092505b935093509390505600a165627a7a72305820aaf842d0d0c35c45622c5263cbb54813d2974d3999c8c38551d7c613ea2bc1170029",
"storage": {
"0x0000000000000000000000000000000000000000000000000000000000000000": "0x1234",
"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9": "0x01"
}
},
"0000000000000000000000000000000000000315": {
"balance": "0x9999999999999999999999999999999",
"code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063ef2769ca1461003e575b610000565b3461000057610078600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061007a565b005b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f1935050505015610106578173ffffffffffffffffffffffffffffffffffffffff167f30a3c50752f2552dcc2b93f5b96866280816a986c0c0408cb6778b9fa198288f826040518082815260200191505060405180910390a25b5b50505600a165627a7a72305820637991fabcc8abad4294bf2bb615db78fbec4edff1635a2647d3894e2daf6a610029"
}
},
"number": "0x0",
Expand Down
255 changes: 255 additions & 0 deletions simulators/optimism/devnet/abi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
package main

import (
"context"
"math/big"
"math/rand"
"strings"
"time"

"github.com/ethereum-optimism/hive/simulators/optimism/devnet/testcontract"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
)

//go:generate abigen -abi ./contractABI.json -pkg testcontract -type Contract -out ./testcontract/contract.go

// callContractTest uses the generated ABI binding to call methods in the
// pre-deployed contract.
func callContractTest(t *TestEnv) {
contract, err := testcontract.NewContractCaller(predeployedContractAddr, t.Eth)
if err != nil {
t.Fatalf("Unable to instantiate contract caller: %v", err)
}

opts := &bind.CallOpts{Pending: true}
value, err := contract.Ui(opts)
if err != nil {
t.Fatalf("Unable to fetch `ui` variable: %v", err)
}

expected, _ := new(big.Int).SetString("0x1234", 0)
if expected.Cmp(value) != 0 {
t.Fatalf("UI variable has invalid value, want %d, got %d", expected, value)
}

expected.SetString("0x1", 0)
value, err = contract.GetFromMap(opts, predeployedContractWithAddress)
if err != nil {
t.Fatalf("Unable to fetch map value: %v", err)
}
if expected.Cmp(value) != 0 {
t.Errorf("Invalid value retrieve from address=>uint mapping, want %d, got %d", expected, value)
}

expA, expB, expC := big.NewInt(1111), big.NewInt(2222), big.NewInt(3333)
a, b, c, err := contract.ConstFunc(opts, expA, expB, expC)
if err != nil {
t.Fatalf("Unable to call ConstFunc: %v", err)
}

if expA.Cmp(a) != 0 {
t.Errorf("A has invalid value, want %d, got %d", expA, a)
}
if expB.Cmp(b) != 0 {
t.Errorf("B has invalid value, want %d, got %d", expB, b)
}
if expC.Cmp(c) != 0 {
t.Errorf("C has invalid value, want %d, got %d", expC, c)
}
}

// transactContractTest deploys a new contract and sends transactions to it and
// waits for logs.
func transactContractTest(t *TestEnv) {
var (
address = t.Vault.createAccount(t, big.NewInt(params.Ether))
nonce = uint64(0)

expectedContractAddress = crypto.CreateAddress(address, nonce)
gasPrice = big.NewInt(30 * params.GWei)
gasLimit = uint64(1200000)

contractABI, _ = abi.JSON(strings.NewReader(predeployedContractABI))
intArg = big.NewInt(rand.Int63())
addrArg = address
)

rawTx := types.NewContractCreation(nonce, big0, gasLimit, gasPrice, deployCode)
deployTx, err := t.Vault.signTransaction(address, rawTx)
nonce++
if err != nil {
t.Fatalf("Unable to sign deploy tx: %v", err)
}

// deploy contract
if err := t.Eth.SendTransaction(t.Ctx(), deployTx); err != nil {
t.Fatalf("Unable to send transaction: %v", err)
}

t.Logf("Deploy ABI Test contract transaction: 0x%x", deployTx.Hash())

// fetch transaction receipt for contract address
var contractAddress common.Address
receipt, err := waitForTxConfirmations(t, deployTx.Hash(), 5)
if err != nil {
t.Fatalf("Unable to retrieve receipt %v: %v", deployTx.Hash(), err)
}

// ensure receipt has the expected address
if expectedContractAddress != receipt.ContractAddress {
t.Fatalf("Contract deploy on different address, expected %x, got %x", expectedContractAddress, contractAddress)
}

t.Logf("ABI test contract deployed on 0x%x", receipt.ContractAddress)

// send transaction to events method
payload, err := contractABI.Pack("events", intArg, addrArg)
if err != nil {
t.Fatalf("Unable to prepare tx payload: %v", err)
}

eventsTx := types.NewTransaction(nonce, predeployedContractAddr, big0, 500000, gasPrice, payload)
tx, err := t.Vault.signTransaction(address, eventsTx)
nonce++
if err != nil {
t.Fatalf("Unable to sign deploy tx: %v", err)
}
if err := t.Eth.SendTransaction(t.Ctx(), tx); err != nil {
t.Fatalf("Unable to send transaction: %v", err)
}

t.Logf("Waiting for receipt for events tx %v", tx.Hash())

// wait for transaction
receipt, err = waitForTxConfirmations(t, tx.Hash(), 0)
if err != nil {
t.Fatalf("Unable to send transaction to events method: %v", err)
}

var (
intArgBytes = common.LeftPadBytes(intArg.Bytes(), 32)
addrArgBytes = common.LeftPadBytes(addrArg.Bytes(), 32)
)

if len(receipt.Logs) != 6 {
t.Fatalf("Want 6 logs, got %d", len(receipt.Logs))
}

validateLog(t, tx, *receipt.Logs[0], predeployedContractAddr, receipt.Logs[0].Index+0, contractABI.Events["E0"], nil)
validateLog(t, tx, *receipt.Logs[1], predeployedContractAddr, receipt.Logs[0].Index+1, contractABI.Events["E1"], intArgBytes)
validateLog(t, tx, *receipt.Logs[2], predeployedContractAddr, receipt.Logs[0].Index+2, contractABI.Events["E2"], intArgBytes)
validateLog(t, tx, *receipt.Logs[3], predeployedContractAddr, receipt.Logs[0].Index+3, contractABI.Events["E3"], addrArgBytes)
validateLog(t, tx, *receipt.Logs[4], predeployedContractAddr, receipt.Logs[0].Index+4, contractABI.Events["E4"], addrArgBytes)
validateLog(t, tx, *receipt.Logs[5], predeployedContractAddr, receipt.Logs[0].Index+5, contractABI.Events["E5"], intArgBytes, addrArgBytes)
}

// transactContractSubscriptionTest deploys a new contract and sends transactions to it and
// waits for logs. It uses subscription to track logs.
func transactContractSubscriptionTest(t *TestEnv) {
var (
address = t.Vault.createAccountWithSubscription(t, big.NewInt(params.Ether))
nonce = uint64(0)

expectedContractAddress = crypto.CreateAddress(address, nonce)
gasPrice = big.NewInt(30 * params.GWei)
gasLimit = uint64(1200000)

contractABI, _ = abi.JSON(strings.NewReader(predeployedContractABI))
intArg = big.NewInt(rand.Int63())
addrArg = address

logs = make(chan types.Log)
)

// deploy contract
rawTx := types.NewContractCreation(nonce, big0, gasLimit, gasPrice, deployCode)
deployTx, err := t.Vault.signTransaction(address, rawTx)
nonce++
if err != nil {
t.Fatalf("Unable to sign deploy tx: %v", err)
}

ctx, _ := context.WithTimeout(context.Background(), rpcTimeout)
if err := t.Eth.SendTransaction(ctx, deployTx); err != nil {
t.Fatalf("Unable to send transaction: %v", err)
}

t.Logf("Deploy ABI Test contract transaction: 0x%x", deployTx.Hash())

// fetch transaction receipt for contract address
receipt, err := waitForTxConfirmations(t, deployTx.Hash(), 5)
if err != nil {
t.Fatalf("Unable to retrieve receipt %v: %v", deployTx.Hash(), err)
}

// ensure receipt has the expected address
if expectedContractAddress != receipt.ContractAddress {
t.Fatalf("Contract deploy on different address, expected %x, got %x", expectedContractAddress, receipt.ContractAddress)
}

t.Logf("ABI test contract deployed on 0x%x", receipt.ContractAddress)

// setup log subscription
ctx, _ = context.WithTimeout(context.Background(), rpcTimeout)
q := ethereum.FilterQuery{Addresses: []common.Address{receipt.ContractAddress}}
sub, err := t.Eth.SubscribeFilterLogs(ctx, q, logs)
if err != nil {
t.Fatalf("Unable to create log subscription: %v", err)
}

contractAddress := receipt.ContractAddress
t.Logf("Log filter created on contract 0x%x", contractAddress)

defer sub.Unsubscribe()

contract, err := testcontract.NewContractTransactor(receipt.ContractAddress, t.Eth)
if err != nil {
t.Fatalf("Could not instantiate contract instance: %v", err)
}

// send transaction to events method
opts := &bind.TransactOpts{
From: address,
Nonce: new(big.Int).SetUint64(nonce),
Signer: t.Vault.signTransaction,
}
tx, err := contract.Events(opts, intArg, addrArg)
if err != nil {
t.Fatalf("Could not send events transaction: %v", err)
}

t.Logf("Send events transaction 0x%x", tx.Hash())

// wait for logs
var collectedLogs []types.Log
timer := time.NewTimer(60 * time.Second)
for len(collectedLogs) < 6 {
select {
case log := <-logs:
collectedLogs = append(collectedLogs, log)
case err := <-sub.Err():
t.Fatalf("Received error from subscription: %v", err)
case <-timer.C:
t.Fatal("Waiting for logs took too long")
}
}

// check logs
var (
intArgBytes = common.LeftPadBytes(intArg.Bytes(), 32)
addrArgBytes = common.LeftPadBytes(addrArg.Bytes(), 32)
)

validateLog(t, tx, collectedLogs[0], contractAddress, collectedLogs[0].Index+0, contractABI.Events["E0"], nil)
validateLog(t, tx, collectedLogs[1], contractAddress, collectedLogs[0].Index+1, contractABI.Events["E1"], intArgBytes)
validateLog(t, tx, collectedLogs[2], contractAddress, collectedLogs[0].Index+2, contractABI.Events["E2"], intArgBytes)
validateLog(t, tx, collectedLogs[3], contractAddress, collectedLogs[0].Index+3, contractABI.Events["E3"], addrArgBytes)
validateLog(t, tx, collectedLogs[4], contractAddress, collectedLogs[0].Index+4, contractABI.Events["E4"], addrArgBytes)
validateLog(t, tx, collectedLogs[5], contractAddress, collectedLogs[0].Index+5, contractABI.Events["E5"], intArgBytes, addrArgBytes)
}
Loading