Skip to content

Commit

Permalink
Init remote contract generation (#8281)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacesailor24 authored Dec 15, 2023
1 parent 54d5ab5 commit 816e425
Show file tree
Hide file tree
Showing 7 changed files with 639 additions and 5 deletions.
28 changes: 28 additions & 0 deletions op-bindings/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ monorepo-base := $(shell dirname $(realpath .))
contracts-dir := $(monorepo-base)/packages/contracts-bedrock
contracts-list := ./artifacts.json
log-level := info
ETHERSCAN_APIKEY_ETH ?=
ETHERSCAN_APIKEY_OP ?=

all: version mkdir bindings

Expand All @@ -21,6 +23,21 @@ bindings: bindgen-local

bindings-build: bindgen-generate-local

bindgen: compile bindgen-generate-all

bindgen-generate-all:
go run ./bindgen/ \
generate \
--metadata-out ./$(pkg) \
--bindings-package $(pkg) \
--contracts-list $(contracts-list) \
--log.level $(log-level) \
all \
--source-maps-list MIPS,PreimageOracle \
--forge-artifacts $(contracts-dir)/forge-artifacts \
--etherscan.apikey.eth $(ETHERSCAN_APIKEY_ETH) \
--etherscan.apikey.op $(ETHERSCAN_APIKEY_OP)

bindgen-local: compile bindgen-generate-local

bindgen-generate-local:
Expand All @@ -34,6 +51,17 @@ bindgen-generate-local:
--source-maps-list MIPS,PreimageOracle \
--forge-artifacts $(contracts-dir)/forge-artifacts

bindgen-remote:
go run ./bindgen/ \
generate \
--metadata-out ./$(pkg) \
--bindings-package $(pkg) \
--contracts-list $(contracts-list) \
--log.level $(log-level) \
remote \
--etherscan.apikey.eth $(ETHERSCAN_APIKEY_ETH) \
--etherscan.apikey.op $(ETHERSCAN_APIKEY_OP)

mkdir:
mkdir -p $(pkg)

Expand Down
99 changes: 99 additions & 0 deletions op-bindings/artifacts.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,104 @@
"ISemver",
"StorageSetter",
"SuperchainConfig"
],
"remote": [
{
"name": "MultiCall3",
"verified": true,
"deployments": {
"eth": "0xcA11bde05977b3631167028862bE2a173976CA11",
"op": "0xcA11bde05977b3631167028862bE2a173976CA11"
}
},
{
"name": "Create2Deployer",
"verified": true,
"deployments": {
"eth": "0xF49600926c7109BD66Ab97a2c036bf696e58Dbc2"
}
},
{
"name": "Safe_v130",
"verified": true,
"deployments": {
"eth": "0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552",
"op": "0x69f4D1788e39c87893C980c06EdF4b7f686e2938"
},
"deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"name": "SafeL2_v130",
"verified": true,
"deployments": {
"eth": "0x3E5c63644E683549055b9Be8653de26E0B4CD36E",
"op": "0xfb1bffC9d739B8D520DaF37dF666da4C687191EA"
},
"deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"name": "MultiSendCallOnly_v130",
"verified": true,
"deployments": {
"eth": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D",
"op": "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B"
},
"deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"name": "SafeSingletonFactory",
"verified": false,
"deployments": {
"eth": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7",
"op": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7"
},
"abi": "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]"
},
{
"name": "DeterministicDeploymentProxy",
"verified": false,
"deployments": {
"eth": "0x4e59b44847b379578588920cA78FbF26c0B4956C",
"op": "0x4e59b44847b379578588920cA78FbF26c0B4956C"
},
"abi": "[{\"payable\":true,\"stateMutability\":\"payable\",\"type\":\"fallback\",\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"creationCode\",\"type\":\"bytes\"}]}]"
},
{
"name": "MultiSend_v130",
"verified": true,
"deployments": {
"op": "0x998739BFdAAdde7C933B942a68053933098f9EDa"
},
"deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000"
},
{
"name": "Permit2",
"verified": true,
"deployments": {
"eth": "0x000000000022D473030F116dDEE9F6B43aC78BA3",
"op": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
},
"deploymentSalt": "0000000000000000000000000000000000000000d3af2663da51c10215000000",
"deployer": "0x4e59b44847b379578588920cA78FbF26c0B4956C"
},
{
"name": "SenderCreator",
"verified": false,
"deployments": {
"eth": "0x7fc98430eaedbb6070b35b39d798725049088348",
"op": "0x7fc98430eaedbb6070b35b39d798725049088348"
},
"initBytecode": "0x6080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
"abi": "[{\"inputs\": [{\"internalType\": \"bytes\",\"name\": \"initCode\",\"type\": \"bytes\"}],\"name\": \"createSender\",\"outputs\": [{\"internalType\": \"address\",\"name\": \"sender\",\"type\": \"address\"}],\"stateMutability\": \"nonpayable\",\"type\": \"function\"}]"
},
{
"name": "EntryPoint",
"verified": true,
"deployments": {
"eth": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
"op": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
},
"deploymentSalt": "0000000000000000000000000000000000000000000000000000000000000000"
}
]
}
124 changes: 124 additions & 0 deletions op-bindings/bindgen/generator_remote.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"context"
"fmt"
"os"

"github.com/ethereum-optimism/optimism/op-bindings/etherscan"
"github.com/ethereum/go-ethereum/common"
)

type bindGenGeneratorRemote struct {
bindGenGeneratorBase
contractDataClients struct {
eth contractDataClient
op contractDataClient
}
tempArtifactsDir string
}

type contractDataClient interface {
FetchAbi(ctx context.Context, address string) (string, error)
FetchDeployedBytecode(ctx context.Context, address string) (string, error)
FetchDeploymentTxHash(ctx context.Context, address string) (string, error)
FetchDeploymentTx(ctx context.Context, txHash string) (etherscan.TxInfo, error)
}

type deployments struct {
Eth common.Address `json:"eth"`
Op common.Address `json:"op"`
}

type remoteContract struct {
Name string `json:"name"`
Verified bool `json:"verified"`
Deployments deployments `json:"deployments"`
DeploymentSalt string `json:"deploymentSalt"`
Deployer common.Address `json:"deployer"`
ABI string `json:"abi"`
InitBytecode string `json:"initBytecode"`
}

type remoteContractMetadata struct {
remoteContract
Package string
InitBin string
DeployedBin string
}

func (generator *bindGenGeneratorRemote) generateBindings() error {
contracts, err := readContractList(generator.logger, generator.contractsListPath)
if err != nil {
return fmt.Errorf("error reading contract list %s: %w", generator.contractsListPath, err)
}
if len(contracts.Remote) == 0 {
return fmt.Errorf("no contracts parsed from given contract list: %s", generator.contractsListPath)
}

return generator.processContracts(contracts.Remote)
}

func (generator *bindGenGeneratorRemote) processContracts(contracts []remoteContract) error {
var err error
generator.tempArtifactsDir, err = mkTempArtifactsDir(generator.logger)
if err != nil {
return err
}
defer func() {
err := os.RemoveAll(generator.tempArtifactsDir)
if err != nil {
generator.logger.Error("Error removing temporary artifact directory", "path", generator.tempArtifactsDir, "err", err.Error())
} else {
generator.logger.Debug("Successfully removed temporary artifact directory")
}
}()

for _, contract := range contracts {
generator.logger.Info("Generating bindings and metadata for remote contract", "contract", contract.Name)

contractMetadata := remoteContractMetadata{
remoteContract: remoteContract{
Name: contract.Name,
Deployments: contract.Deployments,
DeploymentSalt: contract.DeploymentSalt,
ABI: contract.ABI,
Verified: contract.Verified,
},
Package: generator.bindingsPackageName,
}

var err error
switch contract.Name {
case "MultiCall3", "Safe_v130", "SafeL2_v130", "MultiSendCallOnly_v130",
"EntryPoint", "SafeSingletonFactory", "DeterministicDeploymentProxy":
err = generator.standardHandler(&contractMetadata)
case "Create2Deployer":
err = generator.create2DeployerHandler(&contractMetadata)
case "MultiSend_v130":
err = generator.multiSendHandler(&contractMetadata)
case "SenderCreator":
// The SenderCreator contract is deployed by EntryPoint, so the transaction data
// from the deployment transaction is for the entire EntryPoint deployment.
// So, we're manually providing the initialization bytecode
contractMetadata.InitBin = contract.InitBytecode
err = generator.senderCreatorHandler(&contractMetadata)
case "Permit2":
// Permit2 has an immutable Solidity variable that resolves to block.chainid,
// so we can't use the deployed bytecode, and instead must generate it
// at some later point not handled by BindGen.
// DeployerAddress is intended to be used to help deploy Permit2 at it's deterministic address
// to a chain set with the required id to be able to obtain a diff minimized deployed bytecode
contractMetadata.Deployer = contract.Deployer
err = generator.permit2Handler(&contractMetadata)
default:
err = fmt.Errorf("unknown contract: %s, don't know how to handle it", contract.Name)
}

if err != nil {
return err
}
}

return nil
}
Loading

0 comments on commit 816e425

Please sign in to comment.