diff --git a/.github/workflows/espresso-devnet-tests.yaml b/.github/workflows/espresso-devnet-tests.yaml index e8c8acc7262a1..283a169d4445c 100644 --- a/.github/workflows/espresso-devnet-tests.yaml +++ b/.github/workflows/espresso-devnet-tests.yaml @@ -67,8 +67,8 @@ jobs: - name: Run Key Rotation test run: go test -timeout 30m -p 1 -count 1 -run 'TestKeyRotation' -v ./espresso/devnet-tests/... - # - name: Run Change Batch Inbox Owner test - # run: go test -timeout 30m -p 1 -count 1 -run 'TestChangeBatchInboxOwner -v ./espresso/devnet-tests/... + - name: Run Change Batch Inbox Owner test + run: go test -timeout 30m -p 1 -count 1 -run 'TestChangeBatchInboxOwner' -v ./espresso/devnet-tests/... - name: Save Nix cache uses: nix-community/cache-nix-action/save@v6 diff --git a/espresso/.env b/espresso/.env index e118a8de685f1..26de758565de3 100644 --- a/espresso/.env +++ b/espresso/.env @@ -34,6 +34,12 @@ OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf # cast wallet address --private-key $OPERATOR_PRIVATE_KEY OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +# BatchAuthenticator owner address for contract ownership (index 3 from mnemonic) +# cast wallet address --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/3" +BATCH_AUTHENTICATOR_OWNER_ADDRESS=0x90F79bf6EB2c4f870365E785982E1f101E93b906 +# cast wallet private-key --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/3" +BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY=0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6 + # cast wallet address --mnemonic "test test ... junk" --hd-path "m/44'/60'/0'/0/1" PROPOSER_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8 diff --git a/espresso/devnet-tests/devnet_tools.go b/espresso/devnet-tests/devnet_tools.go index 522814f553777..3f23cb2204c3d 100644 --- a/espresso/devnet-tests/devnet_tools.go +++ b/espresso/devnet-tests/devnet_tools.go @@ -9,6 +9,7 @@ import ( "math/big" "os" "os/exec" + "path/filepath" "reflect" "strconv" "strings" @@ -27,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" + "github.com/joho/godotenv" env "github.com/ethereum-optimism/optimism/espresso/environment" "github.com/ethereum-optimism/optimism/op-e2e/config/secrets" @@ -44,6 +46,18 @@ type Devnet struct { L2VerifRollup *sources.RollupClient } +// LoadEnvFile loads environment variables from a .env file +func LoadEnvFile(filename string) error { + return godotenv.Load(filename) +} + +// LoadDevnetEnv loads the espresso/.env file for devnet tests +func LoadDevnetEnv() error { + // Get the path to the espresso/.env file relative to the test directory + envPath := filepath.Join("..", ".env") + return LoadEnvFile(envPath) +} + func NewDevnet(ctx context.Context, t *testing.T) *Devnet { if testing.Short() { diff --git a/espresso/devnet-tests/key_rotation_test.go b/espresso/devnet-tests/key_rotation_test.go index e9d3084b751c0..cf9a39fd67fd0 100644 --- a/espresso/devnet-tests/key_rotation_test.go +++ b/espresso/devnet-tests/key_rotation_test.go @@ -2,15 +2,20 @@ package devnet_tests import ( "context" + "os" + "strings" "testing" "github.com/ethereum-optimism/optimism/op-batcher/bindings" + "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-service/eth" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" ) func TestRotateBatcherKey(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -52,6 +57,10 @@ func TestRotateBatcherKey(t *testing.T) { } func TestChangeBatchInboxOwner(t *testing.T) { + // Load environment variables from .env file + err := LoadDevnetEnv() + require.NoError(t, err, "Failed to load .env file") + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -68,18 +77,44 @@ func TestChangeBatchInboxOwner(t *testing.T) { config, err := d.RollupConfig(ctx) require.NoError(t, err) - // Change the BatchAuthenticator's owner batchAuthenticator, err := bindings.NewBatchAuthenticator(config.BatchAuthenticatorAddress, d.L1) require.NoError(t, err) - tx, err := batchAuthenticator.TransferOwnership(&bind.TransactOpts{}, d.secrets.Addresses().Bob) + + // Get L1 chain ID for transaction signing + l1ChainID, err := d.L1.ChainID(ctx) require.NoError(t, err) - _, err = d.SendL1Tx(ctx, tx) + + // Check current owner first + currentOwner, err := batchAuthenticator.Owner(&bind.CallOpts{}) + require.NoError(t, err) + + // Check that the new owner is different from the current one + bobAddress := d.secrets.Addresses().Bob + require.NotEqual(t, currentOwner, bobAddress) + + // Use batch authenticator owner key to sign the transaction + batchAuthenticatorPrivateKeyHex := os.Getenv("BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY") + require.NotEmpty(t, batchAuthenticatorPrivateKeyHex, "BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY must be set") + t.Logf("Using BATCH_AUTHENTICATOR_OWNER_PRIVATE_KEY from environment: %s...", batchAuthenticatorPrivateKeyHex[:10]) + + batchAuthenticatorKey, err := crypto.HexToECDSA(strings.TrimPrefix(batchAuthenticatorPrivateKeyHex, "0x")) + require.NoError(t, err) + + batchAuthenticatorOwnerOpts, err := bind.NewKeyedTransactorWithChainID(batchAuthenticatorKey, l1ChainID) + require.NoError(t, err) + + // Call TransferOwnership + tx, err := batchAuthenticator.TransferOwnership(batchAuthenticatorOwnerOpts, bobAddress) + require.NoError(t, err) + + // Wait for transaction receipt and check if it succeeded + _, err = wait.ForReceiptOK(ctx, d.L1, tx.Hash()) require.NoError(t, err) // Ensure the owner has been changed newOwner, err := batchAuthenticator.Owner(&bind.CallOpts{}) require.NoError(t, err) - require.Equal(t, newOwner, d.secrets.Addresses().Bob) + require.Equal(t, newOwner, bobAddress) // Check that everything still functions require.NoError(t, d.RunSimpleL2Burn()) diff --git a/espresso/environment/6_batch_inbox_test.go b/espresso/environment/6_batch_inbox_test.go index afe12971a9c44..37d4044e15cdb 100644 --- a/espresso/environment/6_batch_inbox_test.go +++ b/espresso/environment/6_batch_inbox_test.go @@ -2,10 +2,12 @@ package environment_test import ( "context" + "crypto/ecdsa" "math/big" "testing" "time" + "github.com/ethereum-optimism/optimism/op-batcher/bindings" env "github.com/ethereum-optimism/optimism/espresso/environment" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/geth" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/setuputils" @@ -13,12 +15,76 @@ import ( "github.com/ethereum-optimism/optimism/op-service/txmgr" "github.com/ethereum-optimism/optimism/op-service/txmgr/metrics" ethereum "github.com/ethereum/go-ethereum" + "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/log" "github.com/stretchr/testify/require" ) +// Test private key for PreApprovedBatcher (TEE batcher) +const preApprovedBatcherPrivateKey = "5fede428b9506dee864b0d85aefb2409f4728313eb41da4121409299c487f816" + +func setupBatchInboxEnv(ctx context.Context, t *testing.T) (*e2esys.System, *bindings.BatchInbox, *big.Int) { + t.Helper() + launcher := new(env.EspressoDevNodeLauncherDocker) + system, _, err := launcher.StartE2eDevnet(ctx, t, + env.Config(func(cfg *e2esys.SystemConfig) { + cfg.DisableBatcher = true + }), + ) + require.NoError(t, err) + + l1 := system.NodeClient(e2esys.RoleL1) + chainID, err := l1.ChainID(ctx) + require.NoError(t, err) + + inbox, err := bindings.NewBatchInbox(system.RollupConfig.BatchInboxAddress, l1) + require.NoError(t, err) + + // Fund the PreApprovedBatcher account if needed + pk, _ := crypto.HexToECDSA(preApprovedBatcherPrivateKey) + addr := crypto.PubkeyToAddress(pk.PublicKey) + if balance, _ := l1.BalanceAt(ctx, addr, nil); balance.Sign() == 0 { + nonce, _ := l1.PendingNonceAt(ctx, crypto.PubkeyToAddress(system.Cfg.Secrets.Deployer.PublicKey)) + gasPrice, _ := l1.SuggestGasPrice(ctx) + tx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + To: &addr, + Value: big.NewInt(1e18), + Gas: 21000, + GasPrice: gasPrice, + }) + signedTx, _ := types.SignTx(tx, types.NewEIP155Signer(chainID), system.Cfg.Secrets.Deployer) + l1.SendTransaction(ctx, signedTx) + bind.WaitMined(ctx, l1, signedTx) + } + + return system, inbox, chainID +} + +func authForAddress(t *testing.T, system *e2esys.System, chainID *big.Int, addr common.Address) *bind.TransactOpts { + t.Helper() + for _, secret := range []*ecdsa.PrivateKey{ + system.Cfg.Secrets.Deployer, + system.Cfg.Secrets.Batcher, + system.Cfg.Secrets.Bob, + } { + if crypto.PubkeyToAddress(secret.PublicKey) == addr { + auth, _ := bind.NewKeyedTransactorWithChainID(secret, chainID) + return auth + } + } + // Check PreApprovedBatcher + if pk, _ := crypto.HexToECDSA(preApprovedBatcherPrivateKey); crypto.PubkeyToAddress(pk.PublicKey) == addr { + auth, _ := bind.NewKeyedTransactorWithChainID(pk, chainID) + return auth + } + t.Fatalf("no auth available for address %s", addr) + return nil +} + // TestE2eDevnetWithoutAuthenticatingBatches verifies BatchInboxContract behaviour when batches // aren't attested before being posted to batch inbox. To do this, we substitute BatchAuthenticatorAddress // in batcher config with a zero address, which will never revert as it has no contract deployed. @@ -108,6 +174,74 @@ func TestE2eDevnetWithoutAuthenticatingBatches(t *testing.T) { require.Error(t, err) } +func TestBatchInbox_SwitchActiveBatcher(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + system, inbox, chainID := setupBatchInboxEnv(ctx, t) + deployerAuth, _ := bind.NewKeyedTransactorWithChainID(system.Cfg.Secrets.Deployer, chainID) + tx, err := inbox.SwitchBatcher(deployerAuth) + require.NoError(t, err) + _, err = bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx) + require.NoError(t, err) +} + +func TestBatchInbox_ActiveNonTeeBatcherAllowsPosting(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + system, inbox, chainID := setupBatchInboxEnv(ctx, t) + deployerAuth, _ := bind.NewKeyedTransactorWithChainID(system.Cfg.Secrets.Deployer, chainID) + tx, err := inbox.SwitchBatcher(deployerAuth) + require.NoError(t, err) + _, err = bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx) + require.NoError(t, err) + // Determine non-TEE batcher from contract and post with its key + nonTeeAddr, err := inbox.NonTeeBatcher(&bind.CallOpts{Context: ctx}) + require.NoError(t, err) + nonTeeAuth := authForAddress(t, system, chainID, nonTeeAddr) + tx2, err := inbox.PostCalldata(nonTeeAuth, []byte("hello")) + require.NoError(t, err) + receipt, err := bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx2) + require.NoError(t, err) + require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) +} + +func TestBatchInbox_InactiveBatcherReverts(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + system, inbox, chainID := setupBatchInboxEnv(ctx, t) + deployerAuth, _ := bind.NewKeyedTransactorWithChainID(system.Cfg.Secrets.Deployer, chainID) + tx, err := inbox.SwitchBatcher(deployerAuth) + require.NoError(t, err) + _, err = bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx) + require.NoError(t, err) + teeAddr, err := inbox.TeeBatcher(&bind.CallOpts{Context: ctx}) + require.NoError(t, err) + teeAuth := authForAddress(t, system, chainID, teeAddr) + teeAuth.GasLimit = 100000 // Bypass gas estimation + tx2, err := inbox.PostCalldata(teeAuth, []byte("unauth")) + require.NoError(t, err) + receipt, err := bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx2) + require.NoError(t, err) + require.Equal(t, types.ReceiptStatusFailed, receipt.Status) +} + +func TestBatchInbox_TEEBatcherRequiresAuthentication(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + system, inbox, chainID := setupBatchInboxEnv(ctx, t) + teeAddr, err := inbox.TeeBatcher(&bind.CallOpts{Context: ctx}) + require.NoError(t, err) + teeAuth := authForAddress(t, system, chainID, teeAddr) + // Disable gas estimation to force sending a transaction that will revert + teeAuth.GasLimit = 100000 + teeAuth.NoSend = false + tx, err := inbox.PostCalldata(teeAuth, []byte("needs-auth")) + require.NoError(t, err) + receipt, err := bind.WaitMined(ctx, system.NodeClient(e2esys.RoleL1), tx) + require.NoError(t, err) + require.Equal(t, types.ReceiptStatusFailed, receipt.Status) +} + // A wrapper for testing that proxies all calls to ETHBackend unchanged, // except EstimateGas and CallContract calls, which always "succeed" // without making any actual RPC calls. diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index d017b84ff5bcf..8a827be6be3ef 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -96,7 +96,7 @@ dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${P # contract addresses are deterministic. dasel put -f "${DEPLOYER_DIR}/state.json" -s create2Salt -v "0xaecea4f57fadb2097ccd56594f2f22715ac52f92971c5913b70a7f1134b68feb" -op-deployer apply --l1-rpc-url "${ANVIL_URL}" \ +BATCH_AUTHENTICATOR_OWNER_ADDRESS="${BATCH_AUTHENTICATOR_OWNER_ADDRESS}" op-deployer apply --l1-rpc-url "${ANVIL_URL}" \ --workdir "${DEPLOYER_DIR}" \ --private-key="${OPERATOR_PRIVATE_KEY}" diff --git a/go.mod b/go.mod index fb86c7e76f804..9715963ba9957 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require github.com/joho/godotenv v1.5.1 // indirect + require ( codeberg.org/go-fonts/liberation v0.5.0 // indirect codeberg.org/go-latex/latex v0.1.0 // indirect @@ -106,7 +108,6 @@ require ( github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/coder/websocket v1.8.13 github.com/consensys/bavard v0.1.27 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/log v0.1.0 // indirect diff --git a/go.sum b/go.sum index 9b4f87069c658..0b61b062daa30 100644 --- a/go.sum +++ b/go.sum @@ -473,6 +473,8 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= diff --git a/op-batcher/bindings/batch_authenticator.go b/op-batcher/bindings/batch_authenticator.go index eff1c42d7c6ad..3018f84be922a 100644 --- a/op-batcher/bindings/batch_authenticator.go +++ b/op-batcher/bindings/batch_authenticator.go @@ -31,8 +31,8 @@ var ( // BatchAuthenticatorMetaData contains all meta data concerning the BatchAuthenticator contract. var BatchAuthenticatorMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_espressoTEEVerifier\",\"type\":\"address\",\"internalType\":\"contractEspressoTEEVerifier\"},{\"name\":\"_preApprovedBatcher\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"authenticateBatchInfo\",\"inputs\":[{\"name\":\"commitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"decodeAttestationTbs\",\"inputs\":[{\"name\":\"attestation\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"espressoTEEVerifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractEspressoTEEVerifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nitroValidator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractINitroValidator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preApprovedBatcher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerSigner\",\"inputs\":[{\"name\":\"attestationTbs\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validBatchInfo\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint8\",\"indexed\":false,\"internalType\":\"uint8\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", - Bin: "0x60e0604052346100665761001a610014610169565b9061025b565b61002261006b565b611ba56102fc82396080518181816101bc01526112e5015260a05181818161081901528181610c3e01526111ca015260c05181818160f10152610ad90152611ba590f35b610071565b60405190565b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061009d90610075565b810190811060018060401b038211176100b557604052565b61007f565b906100cd6100c661006b565b9283610093565b565b5f80fd5b60018060a01b031690565b6100e7906100d3565b90565b6100f3906100de565b90565b6100ff816100ea565b0361010657565b5f80fd5b90505190610117826100f6565b565b610122816100de565b0361012957565b5f80fd5b9050519061013a82610119565b565b91906040838203126101645780610158610161925f860161010a565b9360200161012d565b90565b6100cf565b610187611ea18038038061017c816100ba565b92833981019061013c565b9091565b61019590516100ea565b90565b90565b6101af6101aa6101b4926100d3565b610198565b6100d3565b90565b6101c09061019b565b90565b6101cc906101b7565b90565b60e01b90565b6101de906100de565b90565b6101ea816101d5565b036101f157565b5f80fd5b90505190610202826101e1565b565b9060208282031261021d5761021a915f016101f5565b90565b6100cf565b5f0190565b61022f61006b565b3d5f823e3d90fd5b610240906101b7565b90565b61024c9061019b565b90565b61025890610243565b90565b60a05260805261028e602061027861027360a061018b565b6101c3565b63d80a4c289061028661006b565b9384926101cf565b8252818061029e60048201610222565b03915afa9081156102f6576102c3916102be915f916102c8575b50610237565b61024f565b60c052565b6102e9915060203d81116102ef575b6102e18183610093565b810190610204565b5f6102b8565b503d6102d7565b61022756fe60806040526004361015610013575b610918565b61001d5f356100cc565b80631b076a4c146100c75780631f568b18146100c257806354fd4d50146100bd578063715018a6146100b85780638da5cb5b146100b3578063a903a277146100ae578063ba58e82a146100a9578063f2fde38b146100a4578063f81f20831461009f578063fa14fe6d1461009a5763fc619e410361000e576108e4565b610869565b6107e2565b6106d9565b610661565b610585565b61041f565b6103ec565b6103b2565b61020c565b610185565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f9103126100ea57565b6100dc565b7f000000000000000000000000000000000000000000000000000000000000000090565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b61014361013e61014892610113565b61012c565b610113565b90565b6101549061012f565b90565b6101609061014b565b90565b61016c90610157565b9052565b9190610183905f60208501940190610163565b565b346101b5576101953660046100e0565b6101b16101a06100ef565b6101a86100d2565b91829182610170565b0390f35b6100d8565b7f000000000000000000000000000000000000000000000000000000000000000090565b6101e790610113565b90565b6101f3906101de565b9052565b919061020a905f602085019401906101ea565b565b3461023c5761021c3660046100e0565b6102386102276101ba565b61022f6100d2565b918291826101f7565b0390f35b6100d8565b601f801991011690565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b9061028290610241565b810190811067ffffffffffffffff82111761029c57604052565b61024b565b906102b46102ad6100d2565b9283610278565b565b67ffffffffffffffff81116102d4576102d0602091610241565b0190565b61024b565b906102eb6102e6836102b6565b6102a1565b918252565b5f7f312e302e30000000000000000000000000000000000000000000000000000000910152565b61032160056102d9565b9061032e602083016102f0565b565b610338610317565b90565b610343610330565b90565b61034e61033b565b90565b5190565b60209181520190565b90825f9392825e0152565b6103886103916020936103969361037f81610351565b93848093610355565b9586910161035e565b610241565b0190565b6103af9160208201915f818403910152610369565b90565b346103e2576103c23660046100e0565b6103de6103cd610346565b6103d56100d2565b9182918261039a565b0390f35b6100d8565b5f0190565b3461041a576103fc3660046100e0565b61040461096c565b61040c6100d2565b80610416816103e7565b0390f35b6100d8565b3461044f5761042f3660046100e0565b61044b61043a6109b9565b6104426100d2565b918291826101f7565b0390f35b6100d8565b5f80fd5b5f80fd5b5f80fd5b67ffffffffffffffff811161047e5761047a602091610241565b0190565b61024b565b90825f939282370152565b909291926104a361049e82610460565b6102a1565b938185526020850190828401116104bf576104bd92610483565b565b61045c565b9080601f830112156104e2578160206104df9335910161048e565b90565b610458565b90602082820312610517575f82013567ffffffffffffffff81116105125761050f92016104c4565b90565b610454565b6100dc565b5190565b60209181520190565b6105486105516020936105569361053f8161051c565b93848093610520565b9586910161035e565b610241565b0190565b90916105746105829360408401908482035f860152610529565b916020818403910152610529565b90565b346105b65761059d6105983660046104e7565b610abc565b906105b26105a96100d2565b9283928361055a565b0390f35b6100d8565b5f80fd5b5f80fd5b909182601f830112156105fd5781359167ffffffffffffffff83116105f85760200192600183028401116105f357565b6105bf565b6105bb565b610458565b909160408284031261065c575f82013567ffffffffffffffff8111610657578361062d9184016105c3565b929093602082013567ffffffffffffffff81116106525761064e92016105c3565b9091565b610454565b610454565b6100dc565b346106935761067d610674366004610602565b92919091610c36565b6106856100d2565b8061068f816103e7565b0390f35b6100d8565b6106a1816101de565b036106a857565b5f80fd5b905035906106b982610698565b565b906020828203126106d4576106d1915f016106ac565b90565b6100dc565b34610707576106f16106ec3660046106bb565b610dee565b6106f96100d2565b80610703816103e7565b0390f35b6100d8565b90565b6107188161070c565b0361071f57565b5f80fd5b905035906107308261070f565b565b9060208282031261074b57610748915f01610723565b90565b6100dc565b6107599061070c565b90565b9061076690610750565b5f5260205260405f2090565b1c90565b60ff1690565b61078c9060086107919302610772565b610776565b90565b9061079f915461077c565b90565b6107b8906107b36065915f9261075c565b610794565b90565b151590565b6107c9906107bb565b9052565b91906107e0905f602085019401906107c0565b565b346108125761080e6107fd6107f8366004610732565b6107a2565b6108056100d2565b918291826107cd565b0390f35b6100d8565b7f000000000000000000000000000000000000000000000000000000000000000090565b6108449061014b565b90565b6108509061083b565b9052565b9190610867905f60208501940190610847565b565b34610899576108793660046100e0565b610895610884610817565b61088c6100d2565b91829182610854565b0390f35b6100d8565b9190916040818403126108df576108b7835f8301610723565b92602082013567ffffffffffffffff81116108da576108d692016105c3565b9091565b610454565b6100dc565b34610913576108fd6108f736600461089e565b91611147565b6109056100d2565b8061090f816103e7565b0390f35b6100d8565b5f80fd5b6109246114a9565b61092c610959565b565b90565b61094561094061094a9261092e565b61012c565b610113565b90565b61095690610931565b90565b61096a6109655f61094d565b61152d565b565b61097461091c565b565b5f90565b5f1c90565b73ffffffffffffffffffffffffffffffffffffffff1690565b6109a46109a99161097a565b61097f565b90565b6109b69054610998565b90565b6109c1610976565b506109cc60336109ac565b90565b606090565b5f80fd5b60e01b90565b909291926109f36109ee82610460565b6102a1565b93818552602085019082840111610a0f57610a0d9261035e565b565b61045c565b9080601f83011215610a3257816020610a2f935191016109de565b90565b610458565b919091604081840312610a8f575f81015167ffffffffffffffff8111610a8a5783610a63918301610a14565b92602082015167ffffffffffffffff8111610a8557610a829201610a14565b90565b610454565b610454565b6100dc565b610aa99160208201915f818403910152610529565b90565b610ab46100d2565b3d5f823e3d90fd5b905f610b2492610aca6109cf565b50610ad36109cf565b50610afd7f0000000000000000000000000000000000000000000000000000000000000000610157565b610b1963a903a277610b0d6100d2565b968794859384936109d8565b835260048301610a94565b03915afa8015610b64575f80939091610b3d575b509190565b9050610b5c9192503d805f833e610b548183610278565b810190610a37565b91905f610b38565b610aac565b5f910312610b7357565b6100dc565b9190610b9281610b8b81610b9795610520565b8095610483565b610241565b0190565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60021115610bd257565b610b9b565b90610be182610bc8565b565b610bec90610bd7565b90565b610bf890610be3565b9052565b959492610c3494610c1e610c2c9360409560608b01918b83035f8d0152610b78565b9188830360208a0152610b78565b940190610bef565b565b929192610c627f000000000000000000000000000000000000000000000000000000000000000061083b565b906335ecb4c190929493600191833b15610ce457610ca1610c96935f97938894610c8a6100d2565b9a8b998a9889976109d8565b875260048701610bfc565b03925af18015610cdf57610cb3575b50565b610cd2905f3d8111610cd8575b610cca8183610278565b810190610b69565b5f610cb0565b503d610cc0565b610aac565b6109d4565b610cfa90610cf56114a9565b610dbe565b565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b610d566026604092610355565b610d5f81610cfc565b0190565b610d789060208101905f818303910152610d49565b90565b15610d8257565b610d8a6100d2565b7f08c379a000000000000000000000000000000000000000000000000000000000815280610dba60048201610d63565b0390fd5b610dec90610de781610de0610dda610dd55f61094d565b6101de565b916101de565b1415610d7b565b61152d565b565b610df790610ce9565b565b610e0491369161048e565b90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b90610e3e8261051c565b811015610e5057600160209102010190565b610e07565b90565b90565b610e6f610e6a610e7492610e55565b61012c565b610e58565b90565b7fff000000000000000000000000000000000000000000000000000000000000001690565b610ea69051610e77565b90565b60f81c90565b60ff1690565b610ec9610ec4610ece92610eaf565b61012c565b610eaf565b90565b610edd610ee291610ea9565b610eb5565b90565b610ef9610ef4610efe9261092e565b61012c565b610eaf565b90565b90565b610f18610f13610f1d92610f01565b61012c565b610eaf565b90565b90565b610f37610f32610f3c92610f20565b61012c565b610eaf565b90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b610f78610f7e91610eaf565b91610eaf565b019060ff8211610f8a57565b610f3f565b60f81b90565b610fa9610fa4610fae92610eaf565b610f8f565b610e77565b90565b5f7f496e76616c6964207369676e6174757265000000000000000000000000000000910152565b610fe56011602092610355565b610fee81610fb1565b0190565b6110079060208101905f818303910152610fd8565b90565b611013906101de565b90565b61101f8161100a565b0361102657565b5f80fd5b9050519061103782611016565b565b906020828203126110525761104f915f0161102a565b90565b6100dc565b6110609061014b565b90565b61106c816107bb565b0361107357565b5f80fd5b9050519061108482611063565b565b9060208282031261109f5761109c915f01611077565b90565b6100dc565b5f7f496e76616c6964207369676e6572000000000000000000000000000000000000910152565b6110d8600e602092610355565b6110e1816110a4565b0190565b6110fa9060208101905f8183039101526110cb565b90565b5f1b90565b9061110e60ff916110fd565b9181191691161790565b611121906107bb565b90565b90565b9061113c61113761114392611118565b611124565b8254611102565b9055565b91611155906111a092610df9565b61117961117461116f836111696040610e5b565b90610e34565b610e9c565b610ed1565b8061118c6111865f610ee5565b91610eaf565b1480156113f3575b6113b8575b508261158e565b806111bb6111b56111b05f61094d565b6101de565b916101de565b1461137c5761120460206111ee7f000000000000000000000000000000000000000000000000000000000000000061083b565b63d80a4c28906111fc6100d2565b9384926109d8565b82528180611214600482016103e7565b03915afa80156113775761123560209161125f935f9161134a575b50611057565b630123d0c19061125485926112486100d2565b958694859384936109d8565b8352600483016101f7565b03915afa80156113455761127b915f91611317575b50156107bb565b90816112db575b5061129f5761129d90611298600191606561075c565b611127565b565b6112a76100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806112d7600482016110e5565b0390fd5b905061130f6113097f00000000000000000000000000000000000000000000000000000000000000006101de565b916101de565b14155f611282565b611338915060203d811161133e575b6113308183610278565b810190611086565b5f611274565b503d611326565b610aac565b61136a9150833d8111611370575b6113628183610278565b810190611039565b5f61122f565b503d611358565b610aac565b6113846100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806113b460048201610ff2565b0390fd5b6113cf6113d4916113c9601b610f23565b90610f6c565b610f95565b6113ec826113e66040935f1a93610e5b565b90610e34565b535f611199565b50806114086114026001610f04565b91610eaf565b14611194565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b61144160208092610355565b61144a8161140e565b0190565b6114639060208101905f818303910152611435565b90565b1561146d57565b6114756100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806114a56004820161144e565b0390fd5b6114d36114b46109b9565b6114cd6114c76114c26115af565b6101de565b916101de565b14611466565b565b906114f473ffffffffffffffffffffffffffffffffffffffff916110fd565b9181191691161790565b6115079061014b565b90565b90565b9061152261151d611529926114fe565b61150a565b82546114d5565b9055565b61153760336109ac565b61154282603361150d565b906115766115707f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936114fe565b916114fe565b9161157f6100d2565b80611589816103e7565b0390a3565b6115ac916115a49161159e610976565b506115e7565b919091611836565b90565b6115b7610976565b503390565b5f90565b90565b6115d76115d26115dc926115c0565b61012c565b610e58565b90565b5f90565b5f90565b6115ef610976565b506115f86115bc565b506116028261051c565b61161561160f60416115c3565b91610e58565b145f1461165a57611654916116286115df565b506116316115df565b5061163a6115e3565b506020810151606060408301519201515f1a909192611a74565b91909190565b50506116655f61094d565b90600290565b6005111561167557565b610b9b565b906116848261166b565b565b60207f7565000000000000000000000000000000000000000000000000000000000000917f45434453413a20696e76616c6964207369676e6174757265202776272076616c5f8201520152565b6116e06022604092610355565b6116e981611686565b0190565b6117029060208101905f8183039101526116d3565b90565b60207f7565000000000000000000000000000000000000000000000000000000000000917f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201520152565b61175f6022604092610355565b61176881611705565b0190565b6117819060208101905f818303910152611752565b90565b5f7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800910152565b6117b8601f602092610355565b6117c181611784565b0190565b6117da9060208101905f8183039101526117ab565b90565b5f7f45434453413a20696e76616c6964207369676e61747572650000000000000000910152565b6118116018602092610355565b61181a816117dd565b0190565b6118339060208101905f818303910152611804565b90565b806118496118435f61167a565b9161167a565b145f146118535750565b80611867611861600161167a565b9161167a565b145f146118aa576118766100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806118a66004820161181e565b0390fd5b806118be6118b8600261167a565b9161167a565b145f14611901576118cd6100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806118fd600482016117c5565b0390fd5b8061191561190f600361167a565b9161167a565b145f14611958576119246100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806119546004820161176c565b0390fd5b61196b611965600461167a565b9161167a565b1461197257565b61197a6100d2565b7f08c379a0000000000000000000000000000000000000000000000000000000008152806119aa600482016116ed565b0390fd5b6119c26119bd6119c792610e58565b61012c565b610e58565b90565b6119d66119db9161097a565b6119ae565b90565b90565b6119f56119f06119fa926119de565b61012c565b610e58565b90565b90565b611a14611a0f611a19926119fd565b61012c565b610eaf565b90565b611a259061070c565b9052565b611a3290610eaf565b9052565b611a6b611a7294611a61606094989795611a57608086019a5f870190611a1c565b6020850190611a29565b6040830190611a1c565b0190611a1c565b565b929190611a7f610976565b50611a886115bc565b50611a92836119ca565b611ac4611abe7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a06119e1565b91610e58565b11611b855780611add611ad7601b610f23565b91610eaf565b141580611b69575b611b5657611b045f936020959293611afb6100d2565b94859485611a36565b838052039060015afa15611b5157611b1c5f516110fd565b80611b37611b31611b2c5f61094d565b6101de565b916101de565b14611b4157905f90565b50611b4b5f61094d565b90600190565b610aac565b50505050611b635f61094d565b90600490565b5080611b7e611b78601c611a00565b91610eaf565b1415611ae5565b50505050611b925f61094d565b9060039056fea164736f6c634300081c000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_espressoTEEVerifier\",\"type\":\"address\",\"internalType\":\"contractEspressoTEEVerifier\"},{\"name\":\"_preApprovedBatcher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"authenticateBatchInfo\",\"inputs\":[{\"name\":\"commitment\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"_signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"decodeAttestationTbs\",\"inputs\":[{\"name\":\"attestation\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"espressoTEEVerifier\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractEspressoTEEVerifier\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nitroValidator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractINitroValidator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"owner\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"preApprovedBatcher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"registerSigner\",\"inputs\":[{\"name\":\"attestationTbs\",\"type\":\"bytes\",\"internalType\":\"bytes\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"renounceOwnership\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"transferOwnership\",\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"validBatchInfo\",\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"event\",\"name\":\"OwnershipTransferred\",\"inputs\":[{\"name\":\"previousOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"newOwner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"}],\"anonymous\":false}]", + Bin: "0x60e0604052346100665761001a610014610176565b91610269565b61002261006b565b611a2861041e82396080518181816101ae0152611214015260a0518181816107f201528181610bef0152611113015260c05181818160f10152610aa30152611a2890f35b610071565b60405190565b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061009d90610075565b810190811060018060401b038211176100b557604052565b61007f565b906100cd6100c661006b565b9283610093565b565b5f80fd5b60018060a01b031690565b6100e7906100d3565b90565b6100f3906100de565b90565b6100ff816100ea565b0361010657565b5f80fd5b90505190610117826100f6565b565b610122816100de565b0361012957565b5f80fd5b9050519061013a82610119565b565b90916060828403126101715761016e610157845f850161010a565b93610165816020860161012d565b9360400161012d565b90565b6100cf565b610194611e4680380380610189816100ba565b92833981019061013c565b909192565b6101a390516100ea565b90565b90565b6101bd6101b86101c2926100d3565b6101a6565b6100d3565b90565b6101ce906101a9565b90565b6101da906101c5565b90565b60e01b90565b6101ec906100de565b90565b6101f8816101e3565b036101ff57565b5f80fd5b90505190610210826101ef565b565b9060208282031261022b57610228915f01610203565b90565b6100cf565b5f0190565b61023d61006b565b3d5f823e3d90fd5b61024e906101c5565b90565b61025a906101a9565b90565b61026690610251565b90565b906102a7929161027761031b565b60a052608052602061029161028c60a0610199565b6101d1565b63d80a4c289061029f61006b565b9485926101dd565b825281806102b760048201610230565b03915afa8015610316576102d96102de916102e6945f916102e8575b50610245565b61025d565b60c0526103ad565b565b610309915060203d811161030f575b6103018183610093565b810190610212565b5f6102d3565b503d6102f7565b610235565b61032b610326610410565b6103ad565b565b5f1c90565b60018060a01b031690565b61034961034e9161032d565b610332565b90565b61035b905461033d565b90565b5f1b90565b9061037460018060a01b039161035e565b9181191691161790565b610387906101c5565b90565b90565b906103a261039d6103a99261037e565b61038a565b8254610363565b9055565b6103b65f610351565b6103c0825f61038d565b906103f46103ee7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09361037e565b9161037e565b916103fd61006b565b8061040781610230565b0390a3565b5f90565b61041861040c565b50339056fe60806040526004361015610013575b6108f1565b61001d5f356100cc565b80631b076a4c146100c75780631f568b18146100c257806354fd4d50146100bd578063715018a6146100b85780638da5cb5b146100b3578063a903a277146100ae578063ba58e82a146100a9578063f2fde38b146100a4578063f81f20831461009f578063fa14fe6d1461009a5763fc619e410361000e576108bd565b610842565b6107bb565b6106b2565b61063a565b61055e565b6103f8565b6103c5565b61038b565b6101fe565b610177565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f9103126100ea57565b6100dc565b7f000000000000000000000000000000000000000000000000000000000000000090565b60018060a01b031690565b90565b61013561013061013a92610113565b61011e565b610113565b90565b61014690610121565b90565b6101529061013d565b90565b61015e90610149565b9052565b9190610175905f60208501940190610155565b565b346101a7576101873660046100e0565b6101a36101926100ef565b61019a6100d2565b91829182610162565b0390f35b6100d8565b7f000000000000000000000000000000000000000000000000000000000000000090565b6101d990610113565b90565b6101e5906101d0565b9052565b91906101fc905f602085019401906101dc565b565b3461022e5761020e3660046100e0565b61022a6102196101ac565b6102216100d2565b918291826101e9565b0390f35b6100d8565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061025b90610233565b810190811067ffffffffffffffff82111761027557604052565b61023d565b9061028d6102866100d2565b9283610251565b565b67ffffffffffffffff81116102ad576102a9602091610233565b0190565b61023d565b906102c46102bf8361028f565b61027a565b918252565b5f7f312e302e30000000000000000000000000000000000000000000000000000000910152565b6102fa60056102b2565b90610307602083016102c9565b565b6103116102f0565b90565b61031c610309565b90565b610327610314565b90565b5190565b60209181520190565b90825f9392825e0152565b61036161036a60209361036f936103588161032a565b9384809361032e565b95869101610337565b610233565b0190565b6103889160208201915f818403910152610342565b90565b346103bb5761039b3660046100e0565b6103b76103a661031f565b6103ae6100d2565b91829182610373565b0390f35b6100d8565b5f0190565b346103f3576103d53660046100e0565b6103dd610945565b6103e56100d2565b806103ef816103c0565b0390f35b6100d8565b34610428576104083660046100e0565b610424610413610984565b61041b6100d2565b918291826101e9565b0390f35b6100d8565b5f80fd5b5f80fd5b5f80fd5b67ffffffffffffffff811161045757610453602091610233565b0190565b61023d565b90825f939282370152565b9092919261047c61047782610439565b61027a565b93818552602085019082840111610498576104969261045c565b565b610435565b9080601f830112156104bb578160206104b893359101610467565b90565b610431565b906020828203126104f0575f82013567ffffffffffffffff81116104eb576104e8920161049d565b90565b61042d565b6100dc565b5190565b60209181520190565b61052161052a60209361052f93610518816104f5565b938480936104f9565b95869101610337565b610233565b0190565b909161054d61055b9360408401908482035f860152610502565b916020818403910152610502565b90565b3461058f576105766105713660046104c0565b610a86565b9061058b6105826100d2565b92839283610533565b0390f35b6100d8565b5f80fd5b5f80fd5b909182601f830112156105d65781359167ffffffffffffffff83116105d15760200192600183028401116105cc57565b610598565b610594565b610431565b9091604082840312610635575f82013567ffffffffffffffff8111610630578361060691840161059c565b929093602082013567ffffffffffffffff811161062b57610627920161059c565b9091565b61042d565b61042d565b6100dc565b3461066c5761065661064d3660046105db565b92919091610be7565b61065e6100d2565b80610668816103c0565b0390f35b6100d8565b61067a816101d0565b0361068157565b5f80fd5b9050359061069282610671565b565b906020828203126106ad576106aa915f01610685565b90565b6100dc565b346106e0576106ca6106c5366004610694565b610d85565b6106d26100d2565b806106dc816103c0565b0390f35b6100d8565b90565b6106f1816106e5565b036106f857565b5f80fd5b90503590610709826106e8565b565b9060208282031261072457610721915f016106fc565b90565b6100dc565b610732906106e5565b90565b9061073f90610729565b5f5260205260405f2090565b1c90565b60ff1690565b61076590600861076a930261074b565b61074f565b90565b906107789154610755565b90565b6107919061078c6001915f92610735565b61076d565b90565b151590565b6107a290610794565b9052565b91906107b9905f60208501940190610799565b565b346107eb576107e76107d66107d136600461070b565b61077b565b6107de6100d2565b918291826107a6565b0390f35b6100d8565b7f000000000000000000000000000000000000000000000000000000000000000090565b61081d9061013d565b90565b61082990610814565b9052565b9190610840905f60208501940190610820565b565b34610872576108523660046100e0565b61086e61085d6107f0565b6108656100d2565b9182918261082d565b0390f35b6100d8565b9190916040818403126108b857610890835f83016106fc565b92602082013567ffffffffffffffff81116108b3576108af920161059c565b9091565b61042d565b6100dc565b346108ec576108d66108d0366004610877565b91611090565b6108de6100d2565b806108e8816103c0565b0390f35b6100d8565b5f80fd5b6108fd6113a4565b610905610932565b565b90565b61091e61091961092392610907565b61011e565b610113565b90565b61092f9061090a565b90565b61094361093e5f610926565b61141a565b565b61094d6108f5565b565b5f90565b5f1c90565b60018060a01b031690565b61096f61097491610953565b610958565b90565b6109819054610963565b90565b61098c61094f565b506109965f610977565b90565b606090565b5f80fd5b60e01b90565b909291926109bd6109b882610439565b61027a565b938185526020850190828401116109d9576109d792610337565b565b610435565b9080601f830112156109fc578160206109f9935191016109a8565b90565b610431565b919091604081840312610a59575f81015167ffffffffffffffff8111610a545783610a2d9183016109de565b92602082015167ffffffffffffffff8111610a4f57610a4c92016109de565b90565b61042d565b61042d565b6100dc565b610a739160208201915f818403910152610502565b90565b610a7e6100d2565b3d5f823e3d90fd5b905f610aee92610a94610999565b50610a9d610999565b50610ac77f0000000000000000000000000000000000000000000000000000000000000000610149565b610ae363a903a277610ad76100d2565b968794859384936109a2565b835260048301610a5e565b03915afa8015610b2e575f80939091610b07575b509190565b9050610b269192503d805f833e610b1e8183610251565b810190610a01565b91905f610b02565b610a76565b5f910312610b3d57565b6100dc565b9190610b5c81610b5581610b61956104f9565b809561045c565b610233565b0190565b634e487b7160e01b5f52602160045260245ffd5b60021115610b8357565b610b65565b90610b9282610b79565b565b610b9d90610b88565b90565b610ba990610b94565b9052565b959492610be594610bcf610bdd9360409560608b01918b83035f8d0152610b42565b9188830360208a0152610b42565b940190610ba0565b565b929192610c137f0000000000000000000000000000000000000000000000000000000000000000610814565b906335ecb4c190929493600191833b15610c9557610c52610c47935f97938894610c3b6100d2565b9a8b998a9889976109a2565b875260048701610bad565b03925af18015610c9057610c64575b50565b610c83905f3d8111610c89575b610c7b8183610251565b810190610b33565b5f610c61565b503d610c71565b610a76565b61099e565b610cab90610ca66113a4565b610d55565b565b60207f6464726573730000000000000000000000000000000000000000000000000000917f4f776e61626c653a206e6577206f776e657220697320746865207a65726f20615f8201520152565b610d07602660409261032e565b610d1081610cad565b0190565b610d299060208101905f818303910152610cfa565b90565b15610d3357565b610d3b6100d2565b62461bcd60e51b815280610d5160048201610d14565b0390fd5b610d8390610d7e81610d77610d71610d6c5f610926565b6101d0565b916101d0565b1415610d2c565b61141a565b565b610d8e90610c9a565b565b610d9b913691610467565b90565b634e487b7160e01b5f52603260045260245ffd5b90610dbc826104f5565b811015610dce57600160209102010190565b610d9e565b90565b90565b610ded610de8610df292610dd3565b61011e565b610dd6565b90565b60ff60f81b1690565b610e089051610df5565b90565b60f81c90565b60ff1690565b610e2b610e26610e3092610e11565b61011e565b610e11565b90565b610e3f610e4491610e0b565b610e17565b90565b610e5b610e56610e6092610907565b61011e565b610e11565b90565b90565b610e7a610e75610e7f92610e63565b61011e565b610e11565b90565b90565b610e99610e94610e9e92610e82565b61011e565b610e11565b90565b634e487b7160e01b5f52601160045260245ffd5b610ec1610ec791610e11565b91610e11565b019060ff8211610ed357565b610ea1565b60f81b90565b610ef2610eed610ef792610e11565b610ed8565b610df5565b90565b5f7f496e76616c6964207369676e6174757265000000000000000000000000000000910152565b610f2e601160209261032e565b610f3781610efa565b0190565b610f509060208101905f818303910152610f21565b90565b610f5c906101d0565b90565b610f6881610f53565b03610f6f57565b5f80fd5b90505190610f8082610f5f565b565b90602082820312610f9b57610f98915f01610f73565b90565b6100dc565b610fa99061013d565b90565b610fb581610794565b03610fbc57565b5f80fd5b90505190610fcd82610fac565b565b90602082820312610fe857610fe5915f01610fc0565b90565b6100dc565b5f7f496e76616c6964207369676e6572000000000000000000000000000000000000910152565b611021600e60209261032e565b61102a81610fed565b0190565b6110439060208101905f818303910152611014565b90565b5f1b90565b9061105760ff91611046565b9181191691161790565b61106a90610794565b90565b90565b9061108561108061108c92611061565b61106d565b825461104b565b9055565b9161109e906110e992610d90565b6110c26110bd6110b8836110b26040610dd9565b90610db2565b610dfe565b610e33565b806110d56110cf5f610e47565b91610e11565b148015611308575b6112cd575b5082611479565b806111046110fe6110f95f610926565b6101d0565b916101d0565b146112ab5761114d60206111377f0000000000000000000000000000000000000000000000000000000000000000610814565b63d80a4c28906111456100d2565b9384926109a2565b8252818061115d600482016103c0565b03915afa80156112a65761117e6020916111a8935f91611279575b50610fa0565b630123d0c19061119d85926111916100d2565b958694859384936109a2565b8352600483016101e9565b03915afa8015611274576111c4915f91611246575b5015610794565b908161120a575b506111e8576111e6906111e16001916001610735565b611070565b565b6111f06100d2565b62461bcd60e51b8152806112066004820161102e565b0390fd5b905061123e6112387f00000000000000000000000000000000000000000000000000000000000000006101d0565b916101d0565b14155f6111cb565b611267915060203d811161126d575b61125f8183610251565b810190610fcf565b5f6111bd565b503d611255565b610a76565b6112999150833d811161129f575b6112918183610251565b810190610f82565b5f611178565b503d611287565b610a76565b6112b36100d2565b62461bcd60e51b8152806112c960048201610f3b565b0390fd5b6112e46112e9916112de601b610e85565b90610eb5565b610ede565b611301826112fb6040935f1a93610dd9565b90610db2565b535f6110e2565b508061131d6113176001610e66565b91610e11565b146110dd565b5f7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572910152565b6113566020809261032e565b61135f81611323565b0190565b6113789060208101905f81830391015261134a565b90565b1561138257565b61138a6100d2565b62461bcd60e51b8152806113a060048201611363565b0390fd5b6113ce6113af610984565b6113c86113c26113bd61149a565b6101d0565b916101d0565b1461137b565b565b906113e160018060a01b0391611046565b9181191691161790565b6113f49061013d565b90565b90565b9061140f61140a611416926113eb565b6113f7565b82546113d0565b9055565b6114235f610977565b61142d825f6113fa565b9061146161145b7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936113eb565b916113eb565b9161146a6100d2565b80611474816103c0565b0390a3565b6114979161148f9161148961094f565b506114d2565b919091611721565b90565b6114a261094f565b503390565b5f90565b90565b6114c26114bd6114c7926114ab565b61011e565b610dd6565b90565b5f90565b5f90565b6114da61094f565b506114e36114a7565b506114ed826104f5565b6115006114fa60416114ae565b91610dd6565b145f146115455761153f916115136114ca565b5061151c6114ca565b506115256114ce565b506020810151606060408301519201515f1a9091926118f7565b91909190565b50506115505f610926565b90600290565b6005111561156057565b610b65565b9061156f82611556565b565b60207f7565000000000000000000000000000000000000000000000000000000000000917f45434453413a20696e76616c6964207369676e6174757265202776272076616c5f8201520152565b6115cb602260409261032e565b6115d481611571565b0190565b6115ed9060208101905f8183039101526115be565b90565b60207f7565000000000000000000000000000000000000000000000000000000000000917f45434453413a20696e76616c6964207369676e6174757265202773272076616c5f8201520152565b61164a602260409261032e565b611653816115f0565b0190565b61166c9060208101905f81830391015261163d565b90565b5f7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800910152565b6116a3601f60209261032e565b6116ac8161166f565b0190565b6116c59060208101905f818303910152611696565b90565b5f7f45434453413a20696e76616c6964207369676e61747572650000000000000000910152565b6116fc601860209261032e565b611705816116c8565b0190565b61171e9060208101905f8183039101526116ef565b90565b8061173461172e5f611565565b91611565565b145f1461173e5750565b8061175261174c6001611565565b91611565565b145f1461177b576117616100d2565b62461bcd60e51b81528061177760048201611709565b0390fd5b8061178f6117896002611565565b91611565565b145f146117b85761179e6100d2565b62461bcd60e51b8152806117b4600482016116b0565b0390fd5b806117cc6117c66003611565565b91611565565b145f146117f5576117db6100d2565b62461bcd60e51b8152806117f160048201611657565b0390fd5b6118086118026004611565565b91611565565b1461180f57565b6118176100d2565b62461bcd60e51b81528061182d600482016115d8565b0390fd5b61184561184061184a92610dd6565b61011e565b610dd6565b90565b61185961185e91610953565b611831565b90565b90565b61187861187361187d92611861565b61011e565b610dd6565b90565b90565b61189761189261189c92611880565b61011e565b610e11565b90565b6118a8906106e5565b9052565b6118b590610e11565b9052565b6118ee6118f5946118e46060949897956118da608086019a5f87019061189f565b60208501906118ac565b604083019061189f565b019061189f565b565b92919061190261094f565b5061190b6114a7565b506119158361184d565b6119476119417f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0611864565b91610dd6565b11611a08578061196061195a601b610e85565b91610e11565b1415806119ec575b6119d9576119875f93602095929361197e6100d2565b948594856118b9565b838052039060015afa156119d45761199f5f51611046565b806119ba6119b46119af5f610926565b6101d0565b916101d0565b146119c457905f90565b506119ce5f610926565b90600190565b610a76565b505050506119e65f610926565b90600490565b5080611a016119fb601c611883565b91610e11565b1415611968565b50505050611a155f610926565b9060039056fea164736f6c634300081d000a", } // BatchAuthenticatorABI is the input ABI used to generate the binding from. @@ -44,7 +44,7 @@ var BatchAuthenticatorABI = BatchAuthenticatorMetaData.ABI var BatchAuthenticatorBin = BatchAuthenticatorMetaData.Bin // DeployBatchAuthenticator deploys a new Ethereum contract, binding an instance of BatchAuthenticator to it. -func DeployBatchAuthenticator(auth *bind.TransactOpts, backend bind.ContractBackend, _espressoTEEVerifier common.Address, _preApprovedBatcher common.Address) (common.Address, *types.Transaction, *BatchAuthenticator, error) { +func DeployBatchAuthenticator(auth *bind.TransactOpts, backend bind.ContractBackend, _espressoTEEVerifier common.Address, _preApprovedBatcher common.Address, _owner common.Address) (common.Address, *types.Transaction, *BatchAuthenticator, error) { parsed, err := BatchAuthenticatorMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployBatchAuthenticator(auth *bind.TransactOpts, backend bind.ContractBack return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchAuthenticatorBin), backend, _espressoTEEVerifier, _preApprovedBatcher) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchAuthenticatorBin), backend, _espressoTEEVerifier, _preApprovedBatcher, _owner) if err != nil { return common.Address{}, nil, nil, err } @@ -504,140 +504,6 @@ func (_BatchAuthenticator *BatchAuthenticatorTransactorSession) TransferOwnershi return _BatchAuthenticator.Contract.TransferOwnership(&_BatchAuthenticator.TransactOpts, newOwner) } -// BatchAuthenticatorInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the BatchAuthenticator contract. -type BatchAuthenticatorInitializedIterator struct { - Event *BatchAuthenticatorInitialized // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *BatchAuthenticatorInitializedIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(BatchAuthenticatorInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(BatchAuthenticatorInitialized) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *BatchAuthenticatorInitializedIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *BatchAuthenticatorInitializedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// BatchAuthenticatorInitialized represents a Initialized event raised by the BatchAuthenticator contract. -type BatchAuthenticatorInitialized struct { - Version uint8 - Raw types.Log // Blockchain specific contextual infos -} - -// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_BatchAuthenticator *BatchAuthenticatorFilterer) FilterInitialized(opts *bind.FilterOpts) (*BatchAuthenticatorInitializedIterator, error) { - - logs, sub, err := _BatchAuthenticator.contract.FilterLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return &BatchAuthenticatorInitializedIterator{contract: _BatchAuthenticator.contract, event: "Initialized", logs: logs, sub: sub}, nil -} - -// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_BatchAuthenticator *BatchAuthenticatorFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *BatchAuthenticatorInitialized) (event.Subscription, error) { - - logs, sub, err := _BatchAuthenticator.contract.WatchLogs(opts, "Initialized") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(BatchAuthenticatorInitialized) - if err := _BatchAuthenticator.contract.UnpackLog(event, "Initialized", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. -// -// Solidity: event Initialized(uint8 version) -func (_BatchAuthenticator *BatchAuthenticatorFilterer) ParseInitialized(log types.Log) (*BatchAuthenticatorInitialized, error) { - event := new(BatchAuthenticatorInitialized) - if err := _BatchAuthenticator.contract.UnpackLog(event, "Initialized", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // BatchAuthenticatorOwnershipTransferredIterator is returned from FilterOwnershipTransferred and is used to iterate over the raw logs and unpacked data for OwnershipTransferred events raised by the BatchAuthenticator contract. type BatchAuthenticatorOwnershipTransferredIterator struct { Event *BatchAuthenticatorOwnershipTransferred // Event containing the contract specifics and raw log diff --git a/op-batcher/bindings/batch_inbox.go b/op-batcher/bindings/batch_inbox.go index d2a23ae72234c..e9f2861a4f4aa 100644 --- a/op-batcher/bindings/batch_inbox.go +++ b/op-batcher/bindings/batch_inbox.go @@ -31,8 +31,8 @@ var ( // BatchInboxMetaData contains all meta data concerning the BatchInbox contract. var BatchInboxMetaData = &bind.MetaData{ - ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_batchAuthenticator\",\"type\":\"address\",\"internalType\":\"contractIBatchAuthenticator\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"nonpayable\"}]", - Bin: "0x60a060405234801561000f575f5ffd5b506040516106c33803806106c3833981810160405281019061003191906100da565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505050610105565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100988261006f565b9050919050565b5f6100a98261008e565b9050919050565b6100b98161009f565b81146100c3575f5ffd5b50565b5f815190506100d4816100b0565b92915050565b5f602082840312156100ef576100ee61006b565b5b5f6100fc848285016100c6565b91505092915050565b6080516105a06101235f395f818160be01526101b801526105a05ff3fe608060405234801561000f575f5ffd5b505f5f1b5f491461019b575f5f67ffffffffffffffff81111561003557610034610291565b5b6040519080825280601f01601f1916602001820160405280156100675781602001600182028036833780820191505090505b5090505f5f90505b5f5f1b8149146100b15781814960405160200161008d929190610339565b604051602081830303815290604052915080806100a990610396565b91505061006f565b5f828051906020012090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f81f2083826040518263ffffffff1660e01b815260040161011591906103ec565b602060405180830381865afa158015610130573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610154919061043e565b610193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161018a906104c3565b60405180910390fd5b50505061028f565b5f5f366040516101ac929190610513565b604051809103902090507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f81f2083826040518263ffffffff1660e01b815260040161020f91906103ec565b602060405180830381865afa15801561022a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024e919061043e565b61028d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161028490610575565b60405180910390fd5b505b005b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f81519050919050565b5f81905092915050565b8281835e5f83830152505050565b5f6102ea826102be565b6102f481856102c8565b93506103048185602086016102d2565b80840191505092915050565b5f819050919050565b5f819050919050565b61033361032e82610310565b610319565b82525050565b5f61034482856102e0565b91506103508284610322565b6020820191508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f819050919050565b5f6103a08261038d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036103d2576103d1610360565b5b600182019050919050565b6103e681610310565b82525050565b5f6020820190506103ff5f8301846103dd565b92915050565b5f5ffd5b5f8115159050919050565b61041d81610409565b8114610427575f5ffd5b50565b5f8151905061043881610414565b92915050565b5f6020828403121561045357610452610405565b5b5f6104608482850161042a565b91505092915050565b5f82825260208201905092915050565b7f496e76616c696420626c6f6220626174636800000000000000000000000000005f82015250565b5f6104ad601283610469565b91506104b882610479565b602082019050919050565b5f6020820190508181035f8301526104da816104a1565b9050919050565b828183375f83830152505050565b5f6104fa83856102c8565b93506105078385846104e1565b82840190509392505050565b5f61051f8284866104ef565b91508190509392505050565b7f496e76616c69642063616c6c64617461206261746368000000000000000000005f82015250565b5f61055f601683610469565b915061056a8261052b565b602082019050919050565b5f6020820190508181035f83015261058c81610553565b905091905056fea164736f6c634300081c000a", + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"_teeBatcher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_nonTeeBatcher\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"_batchAuthenticator\",\"type\":\"address\",\"internalType\":\"contractIBatchAuthenticator\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"fallback\",\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"activeIsTee\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"batchAuthenticator\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIBatchAuthenticator\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"nonTeeBatcher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"postBlobs\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"postCalldata\",\"inputs\":[{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"switchBatcher\",\"inputs\":[],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"teeBatcher\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"version\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"}]", + Bin: "0x60e060405234801561000f575f5ffd5b50604051610c52380380610c528339818101604052810190610031919061022e565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561009957505f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b6100d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100cf906102d8565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff168152505060015f5f6101000a81548160ff0219169083151502179055505050506102f6565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6101c282610199565b9050919050565b6101d2816101b8565b81146101dc575f5ffd5b50565b5f815190506101ed816101c9565b92915050565b5f6101fd826101b8565b9050919050565b61020d816101f3565b8114610217575f5ffd5b50565b5f8151905061022881610204565b92915050565b5f5f5f6060848603121561024557610244610195565b5b5f610252868287016101df565b9350506020610263868287016101df565b92505060406102748682870161021a565b9150509250925092565b5f82825260208201905092915050565b7f4261746368496e626f783a207a65726f206261746368657200000000000000005f82015250565b5f6102c260188361027e565b91506102cd8261028e565b602082019050919050565b5f6020820190508181035f8301526102ef816102b6565b9050919050565b60805160a05160c05161091d6103355f395f81816101f701526103c401525f8181610354015261042901525f81816103a001526103fd015261091d5ff3fe608060405234801561000f575f5ffd5b506004361061008a575f3560e01c8063b1bd428511610059578063b1bd42851461010f578063bc347f471461012d578063d909ba7c14610137578063e7584573146101555761008b565b80631ad40238146100ad57806354fd4d50146100c95780637098ae43146100e75780637877a9ed146100f15761008b565b5b6100ab5f3660405161009e9291906104de565b6040518091039020610173565b005b6100c760048036038101906100c2919061055f565b6102d2565b005b6100d16102f6565b6040516100de919061061a565b60405180910390f35b6100ef61032f565b005b6100f9610341565b6040516101069190610654565b60405180910390f35b610117610352565b60405161012491906106ac565b60405180910390f35b610135610376565b005b61013f61039e565b60405161014c91906106ac565b60405180910390f35b61015d6103c2565b60405161016a9190610720565b60405180910390f35b5f5f61017d6103e6565b915091508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101e690610783565b60405180910390fd5b80156102cd577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f81f2083846040518263ffffffff1660e01b815260040161024e91906107b9565b602060405180830381865afa158015610269573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061028d91906107fc565b6102cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102c390610871565b60405180910390fd5b5b505050565b6102f282826040516102e59291906104de565b6040518091039020610173565b5050565b6040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b61033f61033a610452565b610173565b565b5f5f9054906101000a900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f5f9054906101000a900460ff16155f5f6101000a81548160ff021916908315150217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f5f5f5f9054906101000a900460ff1615610427577f000000000000000000000000000000000000000000000000000000000000000060019150915061044e565b7f00000000000000000000000000000000000000000000000000000000000000005f915091505b9091565b5f60605f5b5f5f1b814914610493578181496040516020016104759291906108e9565b60405160208183030381529060405291508080600101915050610457565b81805190602001209250505090565b5f81905092915050565b828183375f83830152505050565b5f6104c583856104a2565b93506104d28385846104ac565b82840190509392505050565b5f6104ea8284866104ba565b91508190509392505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261051f5761051e6104fe565b5b8235905067ffffffffffffffff81111561053c5761053b610502565b5b60208301915083600182028301111561055857610557610506565b5b9250929050565b5f5f60208385031215610575576105746104f6565b5b5f83013567ffffffffffffffff811115610592576105916104fa565b5b61059e8582860161050a565b92509250509250929050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6105ec826105aa565b6105f681856105b4565b93506106068185602086016105c4565b61060f816105d2565b840191505092915050565b5f6020820190508181035f83015261063281846105e2565b905092915050565b5f8115159050919050565b61064e8161063a565b82525050565b5f6020820190506106675f830184610645565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106968261066d565b9050919050565b6106a68161068c565b82525050565b5f6020820190506106bf5f83018461069d565b92915050565b5f819050919050565b5f6106e86106e36106de8461066d565b6106c5565b61066d565b9050919050565b5f6106f9826106ce565b9050919050565b5f61070a826106ef565b9050919050565b61071a81610700565b82525050565b5f6020820190506107335f830184610711565b92915050565b7f4261746368496e626f783a20696e6163746976652062617463686572000000005f82015250565b5f61076d601c836105b4565b915061077882610739565b602082019050919050565b5f6020820190508181035f83015261079a81610761565b9050919050565b5f819050919050565b6107b3816107a1565b82525050565b5f6020820190506107cc5f8301846107aa565b92915050565b6107db8161063a565b81146107e5575f5ffd5b50565b5f815190506107f6816107d2565b92915050565b5f60208284031215610811576108106104f6565b5b5f61081e848285016107e8565b91505092915050565b7f4261746368496e626f783a20696e76616c6964206261746368000000000000005f82015250565b5f61085b6019836105b4565b915061086682610827565b602082019050919050565b5f6020820190508181035f8301526108888161084f565b9050919050565b5f81519050919050565b5f6108a38261088f565b6108ad81856104a2565b93506108bd8185602086016105c4565b80840191505092915050565b5f819050919050565b6108e36108de826107a1565b6108c9565b82525050565b5f6108f48285610899565b915061090082846108d2565b602082019150819050939250505056fea164736f6c634300081c000a", } // BatchInboxABI is the input ABI used to generate the binding from. @@ -44,7 +44,7 @@ var BatchInboxABI = BatchInboxMetaData.ABI var BatchInboxBin = BatchInboxMetaData.Bin // DeployBatchInbox deploys a new Ethereum contract, binding an instance of BatchInbox to it. -func DeployBatchInbox(auth *bind.TransactOpts, backend bind.ContractBackend, _batchAuthenticator common.Address) (common.Address, *types.Transaction, *BatchInbox, error) { +func DeployBatchInbox(auth *bind.TransactOpts, backend bind.ContractBackend, _teeBatcher common.Address, _nonTeeBatcher common.Address, _batchAuthenticator common.Address) (common.Address, *types.Transaction, *BatchInbox, error) { parsed, err := BatchInboxMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -53,7 +53,7 @@ func DeployBatchInbox(auth *bind.TransactOpts, backend bind.ContractBackend, _ba return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchInboxBin), backend, _batchAuthenticator) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(BatchInboxBin), backend, _teeBatcher, _nonTeeBatcher, _batchAuthenticator) if err != nil { return common.Address{}, nil, nil, err } @@ -202,6 +202,224 @@ func (_BatchInbox *BatchInboxTransactorRaw) Transact(opts *bind.TransactOpts, me return _BatchInbox.Contract.contract.Transact(opts, method, params...) } +// ActiveIsTee is a free data retrieval call binding the contract method 0x7877a9ed. +// +// Solidity: function activeIsTee() view returns(bool) +func (_BatchInbox *BatchInboxCaller) ActiveIsTee(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BatchInbox.contract.Call(opts, &out, "activeIsTee") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// ActiveIsTee is a free data retrieval call binding the contract method 0x7877a9ed. +// +// Solidity: function activeIsTee() view returns(bool) +func (_BatchInbox *BatchInboxSession) ActiveIsTee() (bool, error) { + return _BatchInbox.Contract.ActiveIsTee(&_BatchInbox.CallOpts) +} + +// ActiveIsTee is a free data retrieval call binding the contract method 0x7877a9ed. +// +// Solidity: function activeIsTee() view returns(bool) +func (_BatchInbox *BatchInboxCallerSession) ActiveIsTee() (bool, error) { + return _BatchInbox.Contract.ActiveIsTee(&_BatchInbox.CallOpts) +} + +// BatchAuthenticator is a free data retrieval call binding the contract method 0xe7584573. +// +// Solidity: function batchAuthenticator() view returns(address) +func (_BatchInbox *BatchInboxCaller) BatchAuthenticator(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BatchInbox.contract.Call(opts, &out, "batchAuthenticator") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BatchAuthenticator is a free data retrieval call binding the contract method 0xe7584573. +// +// Solidity: function batchAuthenticator() view returns(address) +func (_BatchInbox *BatchInboxSession) BatchAuthenticator() (common.Address, error) { + return _BatchInbox.Contract.BatchAuthenticator(&_BatchInbox.CallOpts) +} + +// BatchAuthenticator is a free data retrieval call binding the contract method 0xe7584573. +// +// Solidity: function batchAuthenticator() view returns(address) +func (_BatchInbox *BatchInboxCallerSession) BatchAuthenticator() (common.Address, error) { + return _BatchInbox.Contract.BatchAuthenticator(&_BatchInbox.CallOpts) +} + +// NonTeeBatcher is a free data retrieval call binding the contract method 0xb1bd4285. +// +// Solidity: function nonTeeBatcher() view returns(address) +func (_BatchInbox *BatchInboxCaller) NonTeeBatcher(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BatchInbox.contract.Call(opts, &out, "nonTeeBatcher") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// NonTeeBatcher is a free data retrieval call binding the contract method 0xb1bd4285. +// +// Solidity: function nonTeeBatcher() view returns(address) +func (_BatchInbox *BatchInboxSession) NonTeeBatcher() (common.Address, error) { + return _BatchInbox.Contract.NonTeeBatcher(&_BatchInbox.CallOpts) +} + +// NonTeeBatcher is a free data retrieval call binding the contract method 0xb1bd4285. +// +// Solidity: function nonTeeBatcher() view returns(address) +func (_BatchInbox *BatchInboxCallerSession) NonTeeBatcher() (common.Address, error) { + return _BatchInbox.Contract.NonTeeBatcher(&_BatchInbox.CallOpts) +} + +// TeeBatcher is a free data retrieval call binding the contract method 0xd909ba7c. +// +// Solidity: function teeBatcher() view returns(address) +func (_BatchInbox *BatchInboxCaller) TeeBatcher(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BatchInbox.contract.Call(opts, &out, "teeBatcher") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TeeBatcher is a free data retrieval call binding the contract method 0xd909ba7c. +// +// Solidity: function teeBatcher() view returns(address) +func (_BatchInbox *BatchInboxSession) TeeBatcher() (common.Address, error) { + return _BatchInbox.Contract.TeeBatcher(&_BatchInbox.CallOpts) +} + +// TeeBatcher is a free data retrieval call binding the contract method 0xd909ba7c. +// +// Solidity: function teeBatcher() view returns(address) +func (_BatchInbox *BatchInboxCallerSession) TeeBatcher() (common.Address, error) { + return _BatchInbox.Contract.TeeBatcher(&_BatchInbox.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_BatchInbox *BatchInboxCaller) Version(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BatchInbox.contract.Call(opts, &out, "version") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_BatchInbox *BatchInboxSession) Version() (string, error) { + return _BatchInbox.Contract.Version(&_BatchInbox.CallOpts) +} + +// Version is a free data retrieval call binding the contract method 0x54fd4d50. +// +// Solidity: function version() view returns(string) +func (_BatchInbox *BatchInboxCallerSession) Version() (string, error) { + return _BatchInbox.Contract.Version(&_BatchInbox.CallOpts) +} + +// PostBlobs is a paid mutator transaction binding the contract method 0x7098ae43. +// +// Solidity: function postBlobs() returns() +func (_BatchInbox *BatchInboxTransactor) PostBlobs(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BatchInbox.contract.Transact(opts, "postBlobs") +} + +// PostBlobs is a paid mutator transaction binding the contract method 0x7098ae43. +// +// Solidity: function postBlobs() returns() +func (_BatchInbox *BatchInboxSession) PostBlobs() (*types.Transaction, error) { + return _BatchInbox.Contract.PostBlobs(&_BatchInbox.TransactOpts) +} + +// PostBlobs is a paid mutator transaction binding the contract method 0x7098ae43. +// +// Solidity: function postBlobs() returns() +func (_BatchInbox *BatchInboxTransactorSession) PostBlobs() (*types.Transaction, error) { + return _BatchInbox.Contract.PostBlobs(&_BatchInbox.TransactOpts) +} + +// PostCalldata is a paid mutator transaction binding the contract method 0x1ad40238. +// +// Solidity: function postCalldata(bytes data) returns() +func (_BatchInbox *BatchInboxTransactor) PostCalldata(opts *bind.TransactOpts, data []byte) (*types.Transaction, error) { + return _BatchInbox.contract.Transact(opts, "postCalldata", data) +} + +// PostCalldata is a paid mutator transaction binding the contract method 0x1ad40238. +// +// Solidity: function postCalldata(bytes data) returns() +func (_BatchInbox *BatchInboxSession) PostCalldata(data []byte) (*types.Transaction, error) { + return _BatchInbox.Contract.PostCalldata(&_BatchInbox.TransactOpts, data) +} + +// PostCalldata is a paid mutator transaction binding the contract method 0x1ad40238. +// +// Solidity: function postCalldata(bytes data) returns() +func (_BatchInbox *BatchInboxTransactorSession) PostCalldata(data []byte) (*types.Transaction, error) { + return _BatchInbox.Contract.PostCalldata(&_BatchInbox.TransactOpts, data) +} + +// SwitchBatcher is a paid mutator transaction binding the contract method 0xbc347f47. +// +// Solidity: function switchBatcher() returns() +func (_BatchInbox *BatchInboxTransactor) SwitchBatcher(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BatchInbox.contract.Transact(opts, "switchBatcher") +} + +// SwitchBatcher is a paid mutator transaction binding the contract method 0xbc347f47. +// +// Solidity: function switchBatcher() returns() +func (_BatchInbox *BatchInboxSession) SwitchBatcher() (*types.Transaction, error) { + return _BatchInbox.Contract.SwitchBatcher(&_BatchInbox.TransactOpts) +} + +// SwitchBatcher is a paid mutator transaction binding the contract method 0xbc347f47. +// +// Solidity: function switchBatcher() returns() +func (_BatchInbox *BatchInboxTransactorSession) SwitchBatcher() (*types.Transaction, error) { + return _BatchInbox.Contract.SwitchBatcher(&_BatchInbox.TransactOpts) +} + // Fallback is a paid mutator transaction binding the contract fallback function. // // Solidity: fallback() returns() diff --git a/op-deployer/pkg/deployer/opcm/espresso.go b/op-deployer/pkg/deployer/opcm/espresso.go index ec8c0afdf804a..64405b34d5dd1 100644 --- a/op-deployer/pkg/deployer/opcm/espresso.go +++ b/op-deployer/pkg/deployer/opcm/espresso.go @@ -19,6 +19,8 @@ type DeployEspressoInput struct { Salt common.Hash PreApprovedBatcherKey common.Address NitroTEEVerifier common.Address + TeeBatcher common.Address + NonTeeBatcher common.Address } type DeployEspressoOutput struct { @@ -27,7 +29,7 @@ type DeployEspressoOutput struct { } type DeployEspressoScript struct { - Run func(input, output common.Address) error + Run func(input, output, deployerAddress common.Address) error } type DeployAWSNitroVerifierScript struct { @@ -72,6 +74,7 @@ func DeployAWSNitroVerifier( func DeployEspresso( host *script.Host, input DeployEspressoInput, + deployerAddress common.Address, ) (DeployEspressoOutput, error) { var output DeployEspressoOutput inputAddr := host.NewScriptAddress() @@ -97,7 +100,7 @@ func DeployEspresso( } defer cleanupDeploy() - if err := deployScript.Run(inputAddr, outputAddr); err != nil { + if err := deployScript.Run(inputAddr, outputAddr, deployerAddress); err != nil { return output, fmt.Errorf("failed to run %s script: %w", implContract, err) } diff --git a/op-deployer/pkg/deployer/pipeline/espresso.go b/op-deployer/pkg/deployer/pipeline/espresso.go index a4334da502cd3..f242c44b08c60 100644 --- a/op-deployer/pkg/deployer/pipeline/espresso.go +++ b/op-deployer/pkg/deployer/pipeline/espresso.go @@ -2,6 +2,7 @@ package pipeline import ( "fmt" + "os" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/opcm" "github.com/ethereum-optimism/optimism/op-deployer/pkg/deployer/state" @@ -36,11 +37,35 @@ func DeployEspresso(env *Env, intent *state.Intent, st *state.State, chainID com } var eo opcm.DeployEspressoOutput + // Read batch authenticator owner address from environment variable, fallback to env.Deployer + var batchAuthenticatorOwnwerAddress common.Address + if batchAuthenticatorOwnerEnv := os.Getenv("BATCH_AUTHENTICATOR_OWNER_ADDRESS"); batchAuthenticatorOwnerEnv != "" { + batchAuthenticatorOwnwerAddress = common.HexToAddress(batchAuthenticatorOwnerEnv) + lgr.Info("Using batch authenticator owner address from BATCH_AUTHENTICATOR_OWNER_ADDRESS env var", "address", batchAuthenticatorOwnwerAddress.Hex()) + } else { + batchAuthenticatorOwnwerAddress = env.Deployer + lgr.Info("Using deployer address from env.Deployer", "address", batchAuthenticatorOwnwerAddress.Hex()) + } + + // Determine batcher addresses for dual-batcher BatchInbox + teeBatcher := chainIntent.PreApprovedBatcherKey + nonTeeBatcher := chainIntent.Roles.Batcher + // Fallback: if PreApprovedBatcherKey is not set, use Roles.Batcher for both + if teeBatcher == (common.Address{}) { + teeBatcher = chainIntent.Roles.Batcher + } + // Fallback: if Roles.Batcher is not set, use PreApprovedBatcherKey for both + if nonTeeBatcher == (common.Address{}) { + nonTeeBatcher = chainIntent.PreApprovedBatcherKey + } + eo, err = opcm.DeployEspresso(env.L1ScriptHost, opcm.DeployEspressoInput{ Salt: st.Create2Salt, PreApprovedBatcherKey: chainIntent.PreApprovedBatcherKey, NitroTEEVerifier: nvo.NitroTEEVerifierAddress, - }) + TeeBatcher: teeBatcher, + NonTeeBatcher: nonTeeBatcher, + }, batchAuthenticatorOwnwerAddress) if err != nil { return fmt.Errorf("failed to deploy espresso contracts: %w", err) } diff --git a/packages/contracts-bedrock/interfaces/L1/IBatchAuthenticator.sol b/packages/contracts-bedrock/interfaces/L1/IBatchAuthenticator.sol index 16ac0b2b78b5a..9d76da2c58d10 100644 --- a/packages/contracts-bedrock/interfaces/L1/IBatchAuthenticator.sol +++ b/packages/contracts-bedrock/interfaces/L1/IBatchAuthenticator.sol @@ -38,6 +38,7 @@ interface IBatchAuthenticator { function __constructor__( address _espressoTEEVerifier, - address _preApprovedBatcher + address _preApprovedBatcher, + address _owner ) external; } diff --git a/packages/contracts-bedrock/interfaces/L1/IBatchInbox.sol b/packages/contracts-bedrock/interfaces/L1/IBatchInbox.sol index afddfcc3c1e8b..687a2c81967dc 100644 --- a/packages/contracts-bedrock/interfaces/L1/IBatchInbox.sol +++ b/packages/contracts-bedrock/interfaces/L1/IBatchInbox.sol @@ -2,9 +2,15 @@ pragma solidity ^0.8.0; interface IBatchInbox { - fallback() external; - function version() external view returns (string memory); - function __constructor__(address _batchAuthenticator) external; + function __constructor__(address _teeBatcher, address _nonTeeBatcher, address _batchAuthenticator) external; + + function switchBatcher() external; + + function postCalldata(bytes calldata data) external; + + function postBlobs() external; + + fallback() external; } diff --git a/packages/contracts-bedrock/scripts/deploy/DeployEspresso.s.sol b/packages/contracts-bedrock/scripts/deploy/DeployEspresso.s.sol index f5238df099eca..9e08712c5ff97 100644 --- a/packages/contracts-bedrock/scripts/deploy/DeployEspresso.s.sol +++ b/packages/contracts-bedrock/scripts/deploy/DeployEspresso.s.sol @@ -16,10 +16,15 @@ contract DeployEspressoInput is BaseDeployIO { bytes32 internal _salt; address internal _preApprovedBatcherKey; address internal _nitroTEEVerifier; + address internal _teeBatcher; + address internal _nonTeeBatcher; function set(bytes4 _sel, bytes32 _val) public { - if (_sel == this.salt.selector) _salt = _val; - else revert("DeployEspressoInput: unknown selector"); + if (_sel == this.salt.selector) { + _salt = _val; + } else { + // tolerate unknown selectors, some pipelines may pass extra fields we don't need + } } function set(bytes4 _sel, address _val) public { @@ -27,8 +32,13 @@ contract DeployEspressoInput is BaseDeployIO { _preApprovedBatcherKey = _val; } else if (_sel == this.nitroTEEVerifier.selector) { _nitroTEEVerifier = _val; + } else if (_sel == bytes4(keccak256("teeBatcher()")) || _sel == bytes4(keccak256("teeBatcher(address)"))) { + _teeBatcher = _val; + } else if (_sel == bytes4(keccak256("nonTeeBatcher()")) || _sel == bytes4(keccak256("nonTeeBatcher(address)"))) + { + _nonTeeBatcher = _val; } else { - revert("DeployEspressoInput: unknown selector"); + // tolerate unknown selectors, ignore } } @@ -44,6 +54,16 @@ contract DeployEspressoInput is BaseDeployIO { function preApprovedBatcherKey() public view returns (address) { return _preApprovedBatcherKey; } + + function teeBatcher() public view returns (address) { + require(_teeBatcher != address(0), "DeployEspressoInput: tee batcher not set"); + return _teeBatcher; + } + + function nonTeeBatcher() public view returns (address) { + require(_nonTeeBatcher != address(0), "DeployEspressoInput: non-tee batcher not set"); + return _nonTeeBatcher; + } } contract DeployEspressoOutput is BaseDeployIO { @@ -73,9 +93,9 @@ contract DeployEspressoOutput is BaseDeployIO { } contract DeployEspresso is Script { - function run(DeployEspressoInput input, DeployEspressoOutput output) public { + function run(DeployEspressoInput input, DeployEspressoOutput output, address deployerAddress) public { IEspressoTEEVerifier teeVerifier = deployTEEVerifier(input); - IBatchAuthenticator batchAuthenticator = deployBatchAuthenticator(input, output, teeVerifier); + IBatchAuthenticator batchAuthenticator = deployBatchAuthenticator(input, output, teeVerifier, deployerAddress); deployBatchInbox(input, output, batchAuthenticator); checkOutput(output); } @@ -83,7 +103,8 @@ contract DeployEspresso is Script { function deployBatchAuthenticator( DeployEspressoInput input, DeployEspressoOutput output, - IEspressoTEEVerifier teeVerifier + IEspressoTEEVerifier teeVerifier, + address owner ) public returns (IBatchAuthenticator) @@ -96,11 +117,14 @@ contract DeployEspresso is Script { _name: "BatchAuthenticator", _salt: salt, _args: DeployUtils.encodeConstructor( - abi.encodeCall(IBatchAuthenticator.__constructor__, (address(teeVerifier), preApprovedBatcherKey)) + abi.encodeCall( + IBatchAuthenticator.__constructor__, (address(teeVerifier), preApprovedBatcherKey, owner) + ) ) }) ); vm.label(address(impl), "BatchAuthenticatorImpl"); + output.set(output.batchAuthenticatorAddress.selector, address(impl)); return impl; } @@ -125,13 +149,15 @@ contract DeployEspresso is Script { public { bytes32 salt = input.salt(); + address tee = input.teeBatcher(); + address nonTee = input.nonTeeBatcher(); vm.broadcast(msg.sender); IBatchInbox impl = IBatchInbox( DeployUtils.create2({ _name: "BatchInbox", _salt: salt, _args: DeployUtils.encodeConstructor( - abi.encodeCall(IBatchInbox.__constructor__, (address(batchAuthenticator))) + abi.encodeCall(IBatchInbox.__constructor__, (tee, nonTee, address(batchAuthenticator))) ) }) ); diff --git a/packages/contracts-bedrock/src/L1/BatchAuthenticator.sol b/packages/contracts-bedrock/src/L1/BatchAuthenticator.sol index eda08d64b5b72..afc5ca5886252 100644 --- a/packages/contracts-bedrock/src/L1/BatchAuthenticator.sol +++ b/packages/contracts-bedrock/src/L1/BatchAuthenticator.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.0; import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; +import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import { ISemver } from "interfaces/universal/ISemver.sol"; import { EspressoTEEVerifier } from "@espresso-tee-contracts/EspressoTEEVerifier.sol"; import { IEspressoTEEVerifier } from "@espresso-tee-contracts/interface/IEspressoTEEVerifier.sol"; @@ -14,7 +14,7 @@ interface INitroValidator { returns (bytes memory attestationTbs, bytes memory signature); } -contract BatchAuthenticator is ISemver, OwnableUpgradeable { +contract BatchAuthenticator is ISemver, Ownable { /// @notice Semantic version. /// @custom:semver 1.0.0 string public constant version = "1.0.0"; @@ -27,10 +27,11 @@ contract BatchAuthenticator is ISemver, OwnableUpgradeable { EspressoTEEVerifier public immutable espressoTEEVerifier; INitroValidator public immutable nitroValidator; - constructor(EspressoTEEVerifier _espressoTEEVerifier, address _preApprovedBatcher) OwnableUpgradeable() { + constructor(EspressoTEEVerifier _espressoTEEVerifier, address _preApprovedBatcher, address _owner) Ownable() { espressoTEEVerifier = _espressoTEEVerifier; preApprovedBatcher = _preApprovedBatcher; nitroValidator = INitroValidator(address(espressoTEEVerifier.espressoNitroTEEVerifier())); + _transferOwnership(_owner); } function decodeAttestationTbs(bytes memory attestation) external view returns (bytes memory, bytes memory) { diff --git a/packages/contracts-bedrock/src/L1/BatchInbox.sol b/packages/contracts-bedrock/src/L1/BatchInbox.sol index d9650326cdca4..265c21b7076a2 100644 --- a/packages/contracts-bedrock/src/L1/BatchInbox.sol +++ b/packages/contracts-bedrock/src/L1/BatchInbox.sol @@ -4,29 +4,65 @@ pragma solidity 0.8.28; import { IBatchAuthenticator } from "interfaces/L1/IBatchAuthenticator.sol"; contract BatchInbox { - IBatchAuthenticator immutable batchAuthenticator; + string public constant version = "1.1.0"; - constructor(IBatchAuthenticator _batchAuthenticator) { + address public immutable teeBatcher; + address public immutable nonTeeBatcher; + IBatchAuthenticator public immutable batchAuthenticator; + + // true if teeBatcher is active, false if nonTeeBatcher is active + bool public activeIsTee; + + constructor(address _teeBatcher, address _nonTeeBatcher, IBatchAuthenticator _batchAuthenticator) { + require(_teeBatcher != address(0) && _nonTeeBatcher != address(0), "BatchInbox: zero batcher"); + teeBatcher = _teeBatcher; + nonTeeBatcher = _nonTeeBatcher; batchAuthenticator = _batchAuthenticator; + // By default, start with the TEE batcher active + activeIsTee = true; + } + + function switchBatcher() external { + activeIsTee = !activeIsTee; + } + + function postCalldata(bytes calldata data) external { + _requireAuthorized(keccak256(data)); + } + + function postBlobs() external { + _requireAuthorized(_commitmentFromBlobs()); } fallback() external { - if (blobhash(0) != 0) { - bytes memory concatenatedHashes = new bytes(0); - uint256 currentBlob = 0; - while (blobhash(currentBlob) != 0) { - concatenatedHashes = bytes.concat(concatenatedHashes, blobhash(currentBlob)); - currentBlob++; - } - bytes32 hash = keccak256(concatenatedHashes); - if (!batchAuthenticator.validBatchInfo(hash)) { - revert("Invalid blob batch"); - } + _requireAuthorized(keccak256(msg.data)); + } + + function _activeBatcher() internal view returns (address active, bool isTee) { + if (activeIsTee) { + return (teeBatcher, true); } else { - bytes32 hash = keccak256(msg.data); - if (!batchAuthenticator.validBatchInfo(hash)) { - revert("Invalid calldata batch"); + return (nonTeeBatcher, false); + } + } + + function _requireAuthorized(bytes32 commitment) internal view { + (address active, bool isTee) = _activeBatcher(); + require(msg.sender == active, "BatchInbox: inactive batcher"); + if (isTee) { + require(batchAuthenticator.validBatchInfo(commitment), "BatchInbox: invalid batch"); + } + } + + function _commitmentFromBlobs() internal view returns (bytes32) { + bytes memory concatenatedHashes; + uint256 i; + while (blobhash(i) != 0) { + concatenatedHashes = bytes.concat(concatenatedHashes, blobhash(i)); + unchecked { + i++; } } + return keccak256(concatenatedHashes); } }