Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
8abf757
Copy contracts from l2 example
makoto Aug 23, 2021
e841998
copy contracts from l2 demo
makoto Aug 23, 2021
edf07db
Add 0.8.4
makoto Sep 7, 2021
f6a4b74
Add OptimismResolverStubI and upgrade solidity to 0.8.7
makoto Sep 13, 2021
8e930a5
Added deployment script
makoto Sep 14, 2021
2fa8be4
WIP
makoto Sep 14, 2021
48620bc
WIP using custom error type
makoto Sep 15, 2021
047947d
Add OptimismVerifier
makoto Sep 15, 2021
4d367e9
Add IS_OPTIMISM flag
makoto Sep 20, 2021
19934ac
Make test script work
makoto Sep 21, 2021
c9f9bbb
Add server and client code
makoto Sep 21, 2021
25d3055
Add README
makoto Sep 21, 2021
fc53f81
Set non zero address
makoto Sep 21, 2021
3eb4d66
Test getting record for multiple nodes
makoto Sep 21, 2021
760409b
Update README
makoto Sep 21, 2021
3c2fd2d
Add testnet info
makoto Sep 27, 2021
cbc80e0
WIP
makoto Sep 27, 2021
77b272a
Add etherscan verifier and save contract addresses
makoto Sep 27, 2021
0db643a
WIP
makoto Sep 27, 2021
f6f9f58
Test ethers.js is correctly catching error and decoding
makoto Sep 27, 2021
9cfa22c
Downgrade contract version to 0.7.6
makoto Sep 28, 2021
c143ce3
Downgrade contract version to 0.7.6
makoto Sep 29, 2021
5927da7
Downgrade contract version to 0.7.6
makoto Sep 29, 2021
ae77548
Add msg.data
makoto Sep 29, 2021
1dd1e2e
Add msg.data
makoto Sep 29, 2021
6d4deb9
Make end to end test work
makoto Sep 29, 2021
0bd1e0f
Initial work on middleware
Arachnid Sep 30, 2021
c4378f2
Merge branch 'middleware' of https://github.com/ensdomains/durin into…
makoto Sep 30, 2021
9dd5c4a
Optimism middleware (#14)
makoto Oct 15, 2021
641e4ae
Merge branch 'optimism' of https://github.com/ensdomains/durin into o…
makoto Oct 15, 2021
0ab438f
Add context to actions
makoto Oct 15, 2021
ef32d70
Remove test script command from middleware
makoto Oct 15, 2021
284a07e
Add working directory
makoto Oct 15, 2021
a89c40a
Update build name
makoto Oct 15, 2021
a0de50a
Add working directory when installing npm
makoto Oct 15, 2021
b7c322d
Remove with
makoto Oct 15, 2021
ac2c517
Hardcode working directory
makoto Oct 15, 2021
8738e45
Put back with
makoto Oct 15, 2021
4e6fe23
Change step order
makoto Oct 15, 2021
5c2fef2
remove ./
makoto Oct 15, 2021
90425f8
Use npm install
makoto Oct 15, 2021
5d59a85
use yarn instead
makoto Oct 15, 2021
8ff3c62
Add .
makoto Oct 15, 2021
04d7ef6
Hardcode server
makoto Oct 15, 2021
9458ffc
Add middleware
makoto Oct 15, 2021
1ee658c
Remove test from middleware
makoto Oct 15, 2021
1b71352
Add README
makoto Oct 15, 2021
fd81962
Add README of Middleware
makoto Oct 15, 2021
d01a949
Add readme on server
makoto Oct 15, 2021
d6db9bd
Simplify demo code
makoto Oct 15, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,32 @@ jobs:
with:
node-version: ${{ matrix.node }}

- name: Install deps and build (with cache)
- name: Install deps and build (with cache) server
uses: bahmutov/npm-install@v1
with:
working-directory: ./server

- name: Lint
- name: Lint server
run: yarn lint
working-directory: ./server

- name: Build server
run: yarn build
working-directory: ./server

- name: Test
- name: Test server
run: yarn test --ci --coverage --maxWorkers=2
working-directory: ./server

- name: Install deps and build (with cache) middleware
uses: bahmutov/npm-install@v1
with:
working-directory: ./middleware

- name: Lint middleware
run: yarn lint
working-directory: ./middleware

- name: Build
- name: Build middleware
run: yarn build
working-directory: ./middleware
13 changes: 8 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
.DS_Store
node_modules
dist
**/node_modules
**/dist
docs
.env
artifacts
cache
**/.env
**/artifacts
**/artifacts-ovm
**/cache
**/cache-ovm
**/.github/**
4 changes: 2 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
#. "$(dirname "$0")/_/husky.sh"

yarn format && yarn lint
#yarn format && yarn lint
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v14.17.0
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
Durin is a protocol and framework for secure retrieval of offchain data as part of EVM smart contract communication. This repository contains a Typescript framework for writing Durin gateway services.

The Durin specification is [EIP 3668](https://eips.ethereum.org/EIPS/eip-3668).

133 changes: 133 additions & 0 deletions examples/optimism-gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@

## Optimism gateway ENS resolver example

## Summary

This example is a port of https://github.com/ensdomains/l2gateway-demo

## The flow

### When A user updates smart contract on l2

- l1 state root gets updated
- `OVM_StateCommitmentChain` on l1 emits events

### When A user query l2 data via Durin

- The client library first calls `resolver.addr()` which throws an error with Durin gateway url
- Durin extracts the latest state batch header from `OVM_StateCommitmentChain.StateBatchAppended`event.
- Durin constructs MerkleTree based on the state roots
- Durin calls l2 `eth_getProof` to fetch the first storage slot of the `OptimismResolver` contract where `mapping(bytes32=>address) addresses` is stored
- Durin returns the `stateBatchHeader` in the follwoing format

```js
{
stateBatchHeader: {
batch: {
batchIndex: [BigNumber],
batchRoot: '0x2fe1dc132260ee7b45a468d9f84e1d1cecf02dba8e16e0646b59c2b11b5f4fa9',
batchSize: [BigNumber],
prevTotalElements: [BigNumber],
extraData: '0x00000000000000000000000000000000000000000000000000000000614a3b3200000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8'
},
stateRoots: [
'0x2fe1dc132260ee7b45a468d9f84e1d1cecf02dba8e16e0646b59c2b11b5f4fa9'
]
}
}
```

- Once the client library receives the response, calls l1 `resolver.addrWithProof` with the response
- `addrWithProof` calls `verifier.getVerifiedValue(l2resolver, slot, proof)` and returns the resolver address

## How to set up

### 1. Setup optimism environment

Follow [the Optimism guide to create a node locally](https://community.optimism.io/docs/developers/l2/dev-node.html#creating-a-node)

This will start up l2 on port 8545 and l1 on port 9545.
All the subsequent accounts are generated from the following seed

```
test test test test test test test test test test test junk
```

### 2. clone the repo

```
git clone https://github.com/ensdomains/durin
cd examples/optimism-gateway
```

### 3. Deploy Resolver contracts

```
cd contracts
cd yarn
yarn local:deploy
```

This will deploy `OptimismResolver` into l2 and `OptimismResolverStub` to l1

```
~/.../optimism-gateway/contracts (optimism)$yarn deploy
yarn run v1.22.10
$ yarn deploy:l2 && yarn deploy:l1
$ IS_OPTIMISM=true npx hardhat --network optimistic run scripts/l2deploy.js
OptimismResolver deployed to 0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6
Address set
$ npx hardhat --network integration run scripts/deploy.js
{ RESOLVER_ADDRESS: '0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6' }
ENS registry deployed at 0xb7278A61aa25c888815aFC32Ad3cC52fF24fE575
OptimismResolverStub deployed at 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0
```

### 4. Start gateway server


```
cd ../server
yarn
yarn start
```

### 4. Run client script

The demo demonstrates the followings

- 1. get the address of `test.test` via Durin
- 2. get the address of `test2.test` via Durin
- 3. Update the record of `test.test` to `0x...1` on l2
- 4. get the updated address of `test.test` via Durin

```
cd ../client
yarn
yarn start
```

```
$yarn start
yarn run v1.22.15
$ yarn build && node dist/index.js
$ tsdx build
✓ Creating entry file 1.2 secs
✓ Building modules 1.8 secs
{ RESOLVER_STUB_ADDRESS: '0xCD8a1C3ba11CF5ECfa6267617243239504a98d90' }
Ask durin for test.test
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Ask durin for test2.test
0x70997970C51812dc3A010C7d01b50e0d17dc79C8
Update test.test on l2
Set new value to l2 0x0000000000000000000000000000000000000001
Wait 10 sec
Ask durin again
0x0000000000000000000000000000000000000001
✨ Done in 15.32s.
```


## Open questions

- What happens
64 changes: 64 additions & 0 deletions examples/optimism-gateway/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"version": "0.1.0",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "yarn build && node dist/index.js",
"build": "tsdx build",
"test": "tsdx test",
"lint": "tsdx lint",
"prepare": "tsdx build",
"size": "size-limit",
"analyze": "size-limit --why"
},
"peerDependencies": {},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
},
"name": "client",
"author": "Makoto Inoue",
"module": "dist/client.esm.js",
"size-limit": [
{
"path": "dist/client.cjs.production.min.js",
"limit": "10 KB"
},
{
"path": "dist/client.esm.js",
"limit": "10 KB"
}
],
"devDependencies": {
"@size-limit/preset-small-lib": "^5.0.2",
"husky": "^7.0.1",
"size-limit": "^5.0.2",
"tsdx": "^0.14.1",
"tslib": "^2.3.0",
"typescript": "^4.3.5"
},
"dependencies": {
"@ensdomains/durin-middleware": "^0.0.1",
"@types/node-fetch": "^2.5.12",
"dotenv": "^10.0.0",
"eth-ens-namehash": "^2.0.8",
"ethers": "^5.4.4",
"jayson": "^3.6.4",
"node-fetch": "^2.6.1"
}
}
48 changes: 48 additions & 0 deletions examples/optimism-gateway/client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const ethers = require('ethers');
const namehash = require('eth-ens-namehash');
const TEST_NODE = namehash.hash('test.test');
const TEST2_NODE = namehash.hash('test2.test');
const nodeFetch = require('node-fetch');
const TEST_ADDRESS = "0x0000000000000000000000000000000000000001";

require('dotenv').config({ path: '../contracts/.env' });
const fs = require('fs');
const abi = [...JSON.parse(
fs.readFileSync(
'../server/abis/OptimismResolverStub.json',
'utf8'
)
), 'error OffchainLookup(bytes,bytes,string)'
]
const abi2 = JSON.parse(
fs.readFileSync(
'../server/abis/OptimismResolver.json',
'utf8'
)
);
const {
MNEMONIC,
RESOLVER_ADDRESS,
RESOLVER_STUB_ADDRESS,
NETWORK,
INFURA_API_KEY
} = process.env;
let PROVIDER_URL, L2_PROVIDER_URL
if(NETWORK === 'kovan'){
PROVIDER_URL = `https://kovan.infura.io/v3/${INFURA_API_KEY}`
L2_PROVIDER_URL = 'https://kovan.optimism.io'
}else{
PROVIDER_URL = 'http://localhost:9545'
L2_PROVIDER_URL = 'http://localhost:8545'
}

const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL);
const middleware = require('@ensdomains/durin-middleware')
const durinProvider = new middleware.DurinMiddleware(provider)
const wrappedProvider = new ethers.providers.Web3Provider(durinProvider)
const resolver = new ethers.Contract(RESOLVER_STUB_ADDRESS, abi, wrappedProvider);
// const resolver = new ethers.Contract(RESOLVER_STUB_ADDRESS, abi, provider);

resolver.addr(namehash.hash('test.test'))
.then(console.log)
.catch(console.log)
35 changes: 35 additions & 0 deletions examples/optimism-gateway/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
// see https://www.typescriptlang.org/tsconfig to better understand tsconfigs
"include": ["src", "types"],
"compilerOptions": {
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
// output .d.ts declaration files for consumers
"declaration": true,
// output .js.map sourcemap files for consumers
"sourceMap": true,
// match output dir to input dir. e.g. dist/index instead of dist/src/index
"rootDir": "./src",
// stricter type-checking for stronger correctness. Recommended by TS
"strict": true,
// linter checks for common issues
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
// noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
"noUnusedLocals": true,
"noUnusedParameters": true,
// use Node's module resolution algorithm, instead of the legacy TS one
"moduleResolution": "node",
// transpile JSX to React.createElement
"jsx": "react",
// interop between ESM and CJS modules. Recommended by TS
"esModuleInterop": true,
// significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS
"skipLibCheck": true,
// error out if import and file system have a casing mismatch. Recommended by TS
"forceConsistentCasingInFileNames": true,
// `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc`
"noEmit": true,
}
}
Loading