Skip to content

Commit

Permalink
Restructure repo (#35)
Browse files Browse the repository at this point in the history
* Move submodules

* Move submodules

* Move submodules

* Move contracts to contracts subdir

* Move Dockerfile to op-enclave subdirectory

* Fix deployment file

* Fix Makefile and tests

* Move example

* Add README for register-signer

* Comment about public key

* Add README
  • Loading branch information
mdehoog authored Dec 12, 2024
1 parent a1fdac8 commit e6c849c
Show file tree
Hide file tree
Showing 47 changed files with 115 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
- name: Build and push the Docker image
uses: docker/build-push-action@v4
with:
context: .
context: op-enclave
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ jobs:
- name: Run Forge fmt
run: |
cd contracts
forge fmt --check
id: fmt

- name: Run Forge build
run: |
cd contracts
forge build --sizes
id: build

- name: Run Forge tests
run: |
cd contracts
forge test -vvv
id: test
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
/.idea/
.DS_Store
/out/
/cache/
/testnet/data/
/testnet/.env
/deployments/*-*-*.json
/bin/
6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[submodule "lib/forge-std"]
path = lib/forge-std
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/optimism"]
path = lib/optimism
path = contracts/lib/optimism
url = https://github.com/ethereum-optimism/optimism
[submodule "lib/nitro-validator"]
path = lib/nitro-validator
path = contracts/lib/nitro-validator
url = https://github.com/base-org/nitro-validator
30 changes: 16 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ guard-%:

define abigen
echo "Generating bindings for $(1)"
cp out/$(1).sol/$(1).$(3).json out/$(1).sol/$(1).json 2>/dev/null || true
jq -r '.bytecode.object' out/$(1).sol/$(1).json > out/$(1).sol/$(1).bin
jq -r '.abi' out/$(1).sol/$(1).json > out/$(1).sol/$(1).abi
abigen --abi out/$(1).sol/$(1).abi --bin out/$(1).sol/$(1).bin --pkg bindings --type $(1) --out bindings/$(2).go
cp contracts/out/$(1).sol/$(1).$(3).json contracts/out/$(1).sol/$(1).json 2>/dev/null || true
jq -r '.bytecode.object' contracts/out/$(1).sol/$(1).json > contracts/out/$(1).sol/$(1).bin
jq -r '.abi' contracts/out/$(1).sol/$(1).json > contracts/out/$(1).sol/$(1).abi
abigen --abi contracts/out/$(1).sol/$(1).abi --bin contracts/out/$(1).sol/$(1).bin --pkg bindings --type $(1) --out bindings/$(2).go
endef

define verify
Expand All @@ -17,18 +17,20 @@ define verify
name=$$(jq -r --arg address "$$address" '.transactions[] | select((.transactionType=="CREATE" or .transactionType=="CREATE2") and .contractAddress==$$address) | .contractName' $$deploy); \
arguments=$$(jq -r --arg address "$$address" '.transactions[] | select((.transactionType=="CREATE" or .transactionType=="CREATE2") and .contractAddress==$$address) | .arguments // [] | join(" ")' $$deploy); \
namewithoutversion=$${name%.*.*.*}; \
constructor=$$(jq '.abi[] | select(.type=="constructor")' out/$$namewithoutversion.sol/$$name.json | jq -r '.inputs | map(.type) | join(",")'); \
constructor=$$(jq '.abi[] | select(.type=="constructor")' contracts/out/$$namewithoutversion.sol/$$name.json | jq -r '.inputs | map(.type) | join(",")'); \
echo; \
echo "Verifying $$namewithoutversion @ $$address using constructor($$constructor) $$arguments"; \
constructor_args=$$(cast abi-encode "constructor($$constructor)" $$arguments); \
forge verify-contract --compiler-version $$version --watch --verifier-url https://api-sepolia.basescan.org/api --constructor-args $$constructor_args $$address $$namewithoutversion ; \
cd contracts; \
forge verify-contract --compiler-version $$version --watch --verifier-url https://api-sepolia.basescan.org/api --constructor-args $$constructor_args $$address $$namewithoutversion; \
cd ..; \
done
endef

.PHONY: bindings
bindings:
go install github.com/ethereum/go-ethereum/cmd/[email protected]
forge build
cd contracts && forge build
mkdir -p bindings
@$(call abigen,"OutputOracle","output_oracle","0.8.15")
@$(call abigen,"Portal","portal","0.8.15")
Expand All @@ -39,26 +41,26 @@ bindings:

.PHONY: deploy-cert-manager
deploy-cert-manager: guard-IMPL_SALT guard-DEPLOY_PRIVATE_KEY guard-RPC_URL
@forge script DeployCertManager --rpc-url $(RPC_URL) \
@cd contracts && forge script DeployCertManager --rpc-url $(RPC_URL) \
--private-key $(DEPLOY_PRIVATE_KEY) --broadcast

.PHONY: deploy
deploy: guard-IMPL_SALT guard-DEPLOY_CONFIG_PATH guard-DEPLOY_PRIVATE_KEY guard-RPC_URL
@forge script DeploySystem --sig deploy --rpc-url $(RPC_URL) \
@cd contracts && forge script DeploySystem --sig deploy --rpc-url $(RPC_URL) \
--private-key $(DEPLOY_PRIVATE_KEY) --broadcast

.PHONY: deploy-deploy-chain
deploy-deploy-chain: guard-IMPL_SALT guard-DEPLOY_PRIVATE_KEY guard-RPC_URL
@forge script DeployDeployChain --rpc-url $(RPC_URL) \
@cd contracts && forge script DeployDeployChain --rpc-url $(RPC_URL) \
--private-key $(DEPLOY_PRIVATE_KEY) --broadcast

.PHONY: testnet
testnet: guard-L1_URL guard-DEPLOY_PRIVATE_KEY
DEPLOY_CHAIN_ADDRESS=$${DEPLOY_CHAIN_ADDRESS:-$$(jq -r ".DeployChain" deployments/84532-deploy.json)} \
DEPLOY_CHAIN_ADDRESS=$${DEPLOY_CHAIN_ADDRESS:-$$(jq -r ".DeployChain" contracts/deployments/84532-deploy.json)} \
go run ./testnet

.PHONY: verify
verify:
@$(call verify,"broadcast/DeployCertManager.s.sol/84532/run-1733890597.json","0.8.24")
@$(call verify,"broadcast/DeploySystem.s.sol/84532/run-1733867021.json","0.8.15")
@$(call verify,"broadcast/DeployDeployChain.s.sol/84532/run-1733884066.json","0.8.15")
@$(call verify,"contracts/broadcast/DeployCertManager.s.sol/84532/run-1733890597.json","0.8.24")
@$(call verify,"contracts/broadcast/DeploySystem.s.sol/84532/run-1733867021.json","0.8.15")
@$(call verify,"contracts/broadcast/DeployDeployChain.s.sol/84532/run-1733884066.json","0.8.15")
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# op-enclave

`op-enclave` is a relatively small modification to the [op-stack](https://github.com/ethereum-optimism/optimism/)
that proofs state transitions in a AWS Nitro Enclave, and submits the resulting state roots to the L1 chain.
This removes the need for the 7-day challenge period, and allows for immediate withdrawals.

## Directory Structure

<pre>
├── <a href="./bindings">bindings</a>: Go bindings for various contracts, generated by `make bindings`
├── <a href="./contracts">contracts</a>: Solidity contracts
├── <a href="./op-batcher">op-batcher</a>: Batcher modification that submits batches immediately after withdrawals are detected
├── <a href="./op-da">op-da</a>: Data availability service for writing to S3 / file system
├── <a href="./op-enclave">op-enclave</a>: Stateless transition function, for running in a AWS Nitro TEE
├── <a href="./op-proposer">op-proposer</a>: L2-Output Submitter, communicates with op-enclave and submits proposals to L1
├── <a href="./op-withdrawer">op-withdrawer</a>: Withdrawal utility for submitting withdrawals to L1
├── <a href="./register-signer">register-signer</a>: Registers a enclave signer key from a Nitro attestation with the SystemConfigGlobal contract
├── <a href="./testnet">testnet</a>: Dockerized testnet for running the op-enclave stack
</pre>

## Running a testnet

1. Deploy the Nitro certificate manager using `make deploy-cert-manager`:
```bash
IMPL_SALT=0 DEPLOY_PRIVATE_KEY=<privatekey> RPC_URL=https://sepolia.base.org make deploy-cert-manager
```

2. Deploy the system contracts using `make deploy`:
```bash
IMPL_SALT=0 DEPLOY_PRIVATE_KEY=<privatekey> DEPLOY_CONFIG_PATH=deploy-config/example.json RPC_URL=https://sepolia.base.org make deploy
```

3. Generate a testnet genesis block and deploy the proxy contracts for a new chain using `make testnet`:
```bash
DEPLOY_PRIVATE_KEY=<privatekey> L1_URL=https://sepolia.base.org make testnet
```

4. Copy `testnet/.env.example` to `testnet/.env` and fill in the environment variables,
in particular the `# per deploy` section at the top.

5. Run the testnet:
```bash
docker-compose -f testnet/Dockerfile up
```
3 changes: 3 additions & 0 deletions contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/out/
/cache/
/deployments/*-*-*.json
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ contract SystemConfigGlobal is OwnableUpgradeable, ISemver, NitroValidator {

require(ptrs.timestamp + MAX_AGE > block.timestamp, "attestation too old");

// The publicKey is encoded in the form specified in section 4.3.6 of ANSI X9.62, which is a
// 0x04 byte followed by the x and y coordinates of the public key. We ignore the first byte.
bytes32 publicKeyHash = attestationTbs.keccak(ptrs.publicKey.start() + 1, ptrs.publicKey.length() - 1);
address enclaveAddress = address(uint160(uint256(publicKeyHash)));
validSigners[enclaveAddress] = true;
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
10 changes: 5 additions & 5 deletions Dockerfile → op-enclave/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ RUN go install github.com/linuxkit/linuxkit/src/cmd/linuxkit@270fd1c5aa1986977b3
WORKDIR /build
RUN mkdir -p /build

COPY op-enclave/go.mod op-enclave/go.sum op-enclave/
RUN cd op-enclave && go mod download
COPY go.mod go.sum ./
RUN go mod download

COPY op-enclave/ op-enclave/
COPY . .

RUN cd op-enclave && CGO_ENABLED=0 go build -o ../bin/enclave ./cmd/enclave
RUN CGO_ENABLED=0 go build -o bin/enclave ./cmd/enclave

COPY eif/ eif/
COPY eif eif/
COPY --from=bootstrap /build/out bootstrap
RUN linuxkit build --format kernel+initrd --no-sbom --name init-ramdisk ./eif/init-ramdisk.yaml
RUN linuxkit build --format kernel+initrd --no-sbom --name user-ramdisk ./eif/user-ramdisk.yaml
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions op-withdrawer/example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Deposit + Withdraw example

This directory contains an example Golang script that demonstrates how to deposit and withdraw funds from a deployed chain.
File renamed without changes.
29 changes: 29 additions & 0 deletions register-signer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Signer registration utility

This utility can be used to register an op-enclave signer key with the
[SystemConfigGlobal](../contracts/src/SystemConfigGlobal.sol) contract.

## Installation

```
go install github.com/base-org/op-enclave/register-signer
```

## Usage

Query an AWS Nitro attestation from op-enclave server:
```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"enclave_signerAttestation"}' -H "Content-Type: application/json" http://op-enclave:7333
```

```
Usage of register-signer:
-attestation string
attestation hex
-deployment string
deployment file (default "deployments/84532-deploy.json")
-private-key string
private key
-rpc string
rpc url (default "https://sepolia.base.org")
```
31 changes: 6 additions & 25 deletions register-signer/main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package main

import (
"bytes"
"context"
"encoding/json"
"flag"
"fmt"
"os"
Expand All @@ -20,22 +18,18 @@ import (
"github.com/hf/nitrite"
)

type deployment struct {
SystemConfigGlobalProxy common.Address `json:"SystemConfigGlobalProxy"`
}

func main() {
var attestationHex string
var rpcUrl string
var privateKeyHex string
var deploymentFile string
var configAddress string
flag.StringVar(&attestationHex, "attestation", "", "attestation hex")
flag.StringVar(&rpcUrl, "rpc", "https://sepolia.base.org", "rpc url")
flag.StringVar(&privateKeyHex, "private-key", "", "private key")
flag.StringVar(&deploymentFile, "deployment", "deployments/84532-deploy.json", "deployment file")
flag.StringVar(&configAddress, "address", "", "address of the SystemConfigGlobal proxy contract")
flag.Parse()

if attestationHex == "" || privateKeyHex == "" {
if attestationHex == "" || privateKeyHex == "" || configAddress == "" {
flag.Usage()
os.Exit(1)
}
Expand All @@ -60,20 +54,6 @@ func main() {
panic(err)
}

deploy, err := os.ReadFile(deploymentFile)
if err != nil {
panic(err)
}
var d deployment
err = json.Unmarshal(deploy, &d)
if err != nil {
panic(err)
}

if bytes.Equal(common.Address{}.Bytes(), d.SystemConfigGlobalProxy.Bytes()) {
panic("SystemConfigGlobalProxy address not found in deployment file")
}

key, err := crypto.ToECDSA(privateKey)
if err != nil {
panic(err)
Expand All @@ -91,7 +71,7 @@ func main() {
},
}

systemConfigGlobal, err := bindings.NewSystemConfigGlobal(d.SystemConfigGlobalProxy, client)
systemConfigGlobal, err := bindings.NewSystemConfigGlobal(common.HexToAddress(configAddress), client)
if err != nil {
panic(err)
}
Expand All @@ -106,10 +86,11 @@ func main() {
panic(err)
}
fmt.Printf("Public key: %s\n", hexutil.Encode(res.Document.PublicKey))
fmt.Printf("Signer: %s\n", signerAddr.String())
if validSigner {
fmt.Printf("Signer already registered: %s\n", signerAddr.String())
return
} else {
fmt.Printf("Registering signer: %s\n", signerAddr.String())
}

certManagerAddr, err := systemConfigGlobal.CertManager(&bind.CallOpts{})
Expand Down

0 comments on commit e6c849c

Please sign in to comment.