Skip to content

Commit

Permalink
feat: now works with the ERC721 L2 resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
Julink-eth committed Apr 11, 2023
1 parent 01fdc66 commit 6aacbb8
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 2,718 deletions.
13 changes: 2 additions & 11 deletions packages/client/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "zkevm-resolver-client",
"name": "linea-resolver-client",
"version": "1.0.0",
"main": "index.ts",
"license": "MIT",
Expand All @@ -9,18 +9,9 @@
"dependencies": {
"@types/node": "^18.11.17",
"commander": "^9.4.1",
"cross-fetch": "^3.1.5",
"dotenv": "^16.0.3",
"eth-ens-namehash": "^2.0.8",
"ethers": "^5.7.2",
"isomorphic-fetch": "^3.0.0",
"keccak256": "^1.0.6",
"merkle-patricia-tree": "^4.2.4",
"merkletreejs": "^0.3.9",
"random-bytes-seed": "^1.0.3",
"rlp": "^3.0.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.4",
"web3": "^1.8.1"
"typescript": "^4.9.4"
}
}
3 changes: 1 addition & 2 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Command } from "commander";
import { ethers } from "ethers";
import { REGISTRY_ADDRESS } from "./constants";

const namehash = require("eth-ens-namehash");
const program = new Command();
program
.requiredOption(
Expand Down Expand Up @@ -44,7 +43,7 @@ const provider = new ethers.providers.JsonRpcProvider(l1_provider_url, {
console.log("name", name);
const resolverFound = await provider.getResolver(name);
console.log("resolverFound address", resolverFound?.address);
const node = namehash.hash(name);
const node = ethers.utils.namehash(name);
console.log("node", node);

if (resolverFound) {
Expand Down
2,495 changes: 10 additions & 2,485 deletions packages/client/yarn.lock

Large diffs are not rendered by default.

44 changes: 21 additions & 23 deletions packages/contracts/contracts/l1/LineaResolverStub.sol
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
pragma solidity 0.8.9;

import { Lib_OVMCodec } from "@eth-optimism/contracts/libraries/codec/Lib_OVMCodec.sol";
import { Lib_SecureMerkleTrie } from "@eth-optimism/contracts/libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_RLPReader } from "@eth-optimism/contracts/libraries/rlp/Lib_RLPReader.sol";
import { Lib_BytesUtils } from "@eth-optimism/contracts/libraries/utils/Lib_BytesUtils.sol";

import "hardhat/console.sol";

struct L2StateProof {
bytes32 blockHash;
bytes encodedBlockArray;
bytes stateTrieWitness;
bytes accountProof;
bytes32 stateRoot;
bytes storageTrieWitness;
bytes tokenIdStorageProof;
bytes ownerStorageProof;
}

interface IResolverService {
Expand Down Expand Up @@ -104,26 +103,32 @@ contract LineaResolverStub is IExtendedResolver, SupportsInterface {

L2StateProof memory proof = abi.decode(response, (L2StateProof));
// bytes32 node = abi.decode(extraData, (bytes32));
// step 2: check blockHash against encoded block array
// step 1: check blockHash against encoded block array
require(
proof.blockHash == keccak256(proof.encodedBlockArray),
"blockHash encodedBlockArray mismatch"
);

// step 3: check storage value from derived value
// Here the node used should be in extra data but we need to find a way
// to convert extra data to an ens hashname in solidity, in the meantime we use
// the node sent by the gateway
bytes32 slot = keccak256(abi.encodePacked(node, uint256(1)));
bytes32 value = getStorageValue(
// step 2: check storage values, get itemId first and then get the address result
bytes32 tokenIdSlot = keccak256(abi.encodePacked(node, uint256(6)));
bytes32 tokenId = getStorageValue(
l2resolver,
tokenIdSlot,
proof.stateRoot,
proof.accountProof,
proof.tokenIdStorageProof
);

bytes32 ownerSlot = keccak256(abi.encodePacked(tokenId, uint256(2)));
bytes32 owner = getStorageValue(
l2resolver,
slot,
ownerSlot,
proof.stateRoot,
proof.stateTrieWitness,
proof.storageTrieWitness
proof.accountProof,
proof.ownerStorageProof
);

return abi.encode(value);
return abi.encode(owner);
}

function getl2Resolver() external view returns (address) {
Expand Down Expand Up @@ -161,13 +166,6 @@ contract LineaResolverStub is IExtendedResolver, SupportsInterface {
return ret;
}

function addressToBytes(address a) internal pure returns (bytes memory b) {
b = new bytes(20);
assembly {
mstore(add(b, 32), mul(a, exp(256, 12)))
}
}

function supportsInterface(
bytes4 interfaceID
) public pure override returns (bool) {
Expand Down
35 changes: 4 additions & 31 deletions packages/contracts/contracts/l2/LineaResolver.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
pragma solidity 0.8.9;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { IERC721Receiver } from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";

contract LineaResolver is Ownable, ERC721 {
contract LineaResolver is ERC721 {
mapping(bytes32 => uint256) public addresses;
uint256 public tokenId;

Expand All @@ -20,14 +18,7 @@ contract LineaResolver is Ownable, ERC721 {
bytes32 node,
address _addr
) external returns (uint256) {
string memory nodeStr = bytes32ToString(node);

require(addresses[node] == 0, "Sub-domain has already been registered");
require(bytes(nodeStr).length != 0, "Sub-domain cannot be null");
require(
testAlphaNumeric(nodeStr) == true,
"Sub-domain contains unsupported characters"
);

addresses[node] = tokenId;
emit AddrChanged(node, _addr);
Expand All @@ -37,26 +28,8 @@ contract LineaResolver is Ownable, ERC721 {
return tokenId;
}

function testAlphaNumeric(string memory str) public pure returns (bool) {
bytes memory b = bytes(str);
for (uint i; i < b.length; i++) {
bytes1 char = b[i];
if (!(char > 0x2F && char < 0x3A) && !(char > 0x60 && char < 0x7B))
return false;
}
return true;
}

function bytes32ToString(bytes32 x) private pure returns (string memory) {
bytes memory b = new bytes(32);
for (uint i = 0; i < 32; i++) {
b[i] = x[i];
}
return string(b);
}

function resolve(bytes32 node) external view returns (address) {
uint256 tokenId = addresses[node];
return ownerOf(tokenId);
uint256 _tokenId = addresses[node];
return ownerOf(_tokenId);
}
}
7 changes: 2 additions & 5 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Linea-resolver",
"name": "linea-resolver",
"version": "0.0.1",
"description": "Linea Resolver for ENS",
"main": "index.js",
Expand Down Expand Up @@ -28,11 +28,8 @@
"typescript": ">=4.5.0"
},
"dependencies": {
"@ensdomains/ens-contracts": "^0.0.20",
"@eth-optimism/contracts": "^0.5.40",
"@openzeppelin/contracts": "^4.8.1",
"dotenv": "^16.0.3",
"ens-namehash": "JonahGroendal/ens-namehash",
"eth-ens-namehash": "^2.0.8"
"dotenv": "^16.0.3"
}
}
3 changes: 1 addition & 2 deletions packages/contracts/scripts/deployL1.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ethers, network, run } from "hardhat";
import { REGISTRY_ADDRESS, ROLLUP_ADDRESSES } from "./constants";
const ensRegistryAbi = require("../abi/ENSRegistry.json");
const namehash = require("eth-ens-namehash");

const HARDHAT_NETWORK_CHAIN_ID = 31337;

Expand Down Expand Up @@ -31,7 +30,7 @@ async function main() {
const registryAddr = REGISTRY_ADDRESS[network.name as keyof typeof REGISTRY_ADDRESS];
const registry = await new ethers.Contract(registryAddr, ensRegistryAbi, owner);
const name = process.env.L1_ENS_NAME ? process.env.L1_ENS_NAME : "lineatest.eth";
const node = namehash.hash(name);
const node = ethers.utils.namehash(name);
let tx = await registry.setResolver(node, lineaResolverStub.address);
await tx.wait();
console.log("L1 ENS name:", name, ", set to LineaResolverStub: ", lineaResolverStub.address);
Expand Down
12 changes: 7 additions & 5 deletions packages/contracts/scripts/deployL2.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
import { ethers, run } from "hardhat";
const namehash = require("eth-ens-namehash");

async function main() {
const [owner] = await ethers.getSigners();
const chainId = await owner.getChainId();

// Deploy Linea Resolver to L2
const LineaResolver = await ethers.getContractFactory("LineaResolver");
const lineaResolver = await LineaResolver.deploy();
const nftName = "Lineatest";
const symbol = "LTST";
const lineaResolver = await LineaResolver.deploy(nftName, symbol);
await lineaResolver.deployed();

// Test with subdomain with default "julink.lineatest.eth", assuming we still control lineatest.eth on L1
const name = process.env.L2_ENS_NAME ? process.env.L2_ENS_NAME : "julink.lineatest.eth";
const node = namehash.hash(name);
const tx = await lineaResolver.setAddr(node, owner.address);
const node = ethers.utils.namehash(name);
const tx = await lineaResolver.mintSubdomain(node, owner.address);
await tx.wait();
console.log(`LineaResolver deployed to, L2_RESOLVER_ADDRESS: ${lineaResolver.address}`);

if (chainId !== 31337) {
setTimeout(async () => {
await run("verify", {
await run("verify:verify", {
address: lineaResolver.address,
constructorArguments: [nftName, symbol],
});
}, 10000);
}
Expand Down
70 changes: 1 addition & 69 deletions packages/contracts/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,6 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"

"@ensdomains/buffer@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@ensdomains/buffer/-/buffer-0.1.1.tgz#6c275ba7e457e935405b67876f1f0d980c8baa63"
integrity sha512-92SfSiNS8XorgU7OUBHo/i1ZU7JV7iz/6bKuLPNVsMxV79/eI7fJR6jfJJc40zAHjs3ha+Xo965Idomlq3rqnw==

"@ensdomains/ens-contracts@^0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@ensdomains/ens-contracts/-/ens-contracts-0.0.20.tgz#346eac70d666a7864142287ce1759b0f44bd8a5e"
integrity sha512-lAHQBVj2WtgbchcrE8ZuFI6DFq+O33wkLAGqsO2gcnn0EUJb65OJIdTqUfvfULKGJjkB2pyHfS/RgMSIW6h1Pw==
dependencies:
"@ensdomains/buffer" "^0.1.1"
"@ensdomains/solsha1" "0.0.3"
"@openzeppelin/contracts" "^4.1.0"
dns-packet "^5.3.0"

"@ensdomains/[email protected]":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@ensdomains/solsha1/-/solsha1-0.0.3.tgz#fd479da9d40aadb59ff4fb4ec50632e7d2275a83"
integrity sha512-uhuG5LzRt/UJC0Ux83cE2rCKwSleRePoYdQVcqPN1wyf3/ekMzT/KZUF9+v7/AG5w9jlMLCQkUM50vfjr0Yu9Q==
dependencies:
hash-test-vectors "^1.3.2"

"@eth-optimism/contracts@^0.5.40":
version "0.5.40"
resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.40.tgz#d13a04a15ea947a69055e6fc74d87e215d4c936a"
Expand Down Expand Up @@ -422,11 +400,6 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"

"@leichtgewicht/ip-codec@^2.0.1":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==

"@metamask/eth-sig-util@^4.0.0":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088"
Expand Down Expand Up @@ -719,11 +692,6 @@
table "^6.8.0"
undici "^5.14.0"

"@openzeppelin/contracts@^4.1.0":
version "4.8.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.2.tgz#d815ade0027b50beb9bcca67143c6bcc3e3923d6"
integrity sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g==

"@openzeppelin/contracts@^4.8.1":
version "4.8.1"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4"
Expand Down Expand Up @@ -1828,13 +1796,6 @@ dir-glob@^3.0.1:
dependencies:
path-type "^4.0.0"

dns-packet@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.5.0.tgz#f59cbf3396c130957c56a6ad5fd3959ccdc30065"
integrity sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==
dependencies:
"@leichtgewicht/ip-codec" "^2.0.1"

dotenv@^16.0.3:
version "16.0.3"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07"
Expand Down Expand Up @@ -1878,10 +1839,6 @@ enquirer@^2.3.0:
dependencies:
ansi-colors "^4.1.1"

ens-namehash@JonahGroendal/ens-namehash:
version "1.0.0"
resolved "https://codeload.github.com/JonahGroendal/ens-namehash/tar.gz/d956b0be0ae5d14191067ed398c4454e35f4558d"

env-paths@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
Expand Down Expand Up @@ -1996,14 +1953,6 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==

eth-ens-namehash@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf"
integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==
dependencies:
idna-uts46-hx "^2.3.1"
js-sha3 "^0.5.7"

eth-gas-reporter@^0.2.25:
version "0.2.25"
resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566"
Expand Down Expand Up @@ -2717,11 +2666,6 @@ hash-base@^3.0.0:
readable-stream "^3.6.0"
safe-buffer "^5.2.0"

hash-test-vectors@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/hash-test-vectors/-/hash-test-vectors-1.3.2.tgz#f050fde1aff46ec28dcf4f70e4e3238cd5000f4c"
integrity sha512-PKd/fitmsrlWGh3OpKbgNLE04ZQZsvs1ZkuLoQpeIKuwx+6CYVNdW6LaPIS1QAdZvV40+skk0w4YomKnViUnvQ==

[email protected]:
version "1.1.3"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846"
Expand Down Expand Up @@ -2809,13 +2753,6 @@ [email protected]:
dependencies:
safer-buffer ">= 2.1.2 < 3"

idna-uts46-hx@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9"
integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==
dependencies:
punycode "2.1.0"

ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
Expand Down Expand Up @@ -3051,7 +2988,7 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==

[email protected], js-sha3@^0.5.7:
[email protected]:
version "0.5.7"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7"
integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==
Expand Down Expand Up @@ -3804,11 +3741,6 @@ psl@^1.1.28:
resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==

[email protected]:
version "2.1.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d"
integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==

punycode@^2.1.0, punycode@^2.1.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
Expand Down
Loading

0 comments on commit 6aacbb8

Please sign in to comment.