From be84bec5285f507fcb769629e1afc4aabb35ef42 Mon Sep 17 00:00:00 2001 From: douglasacost Date: Mon, 12 May 2025 11:05:17 +0200 Subject: [PATCH 1/2] Refactor the service contract deployment and name resolution logic. * Removed the `SHOULD_DEPLOY` variable and improved the verification of environment variables required for deployment. * Rename ClickResolver to `UniversalResolver` contract to handle subdomain resolution based on names registered in L2 * Updated resolver addresses in the deployment script to use `NS_RESOLVER_ADDR` instead of `CLICK_RESOLVER_ADDR`. * Improved deployment logic to check if `CONTRACT_ADDRESS` is defined before proceeding with contract deployment. --- deploy/deploy_nodl_name_service.dp.ts | 37 ++++++++++--------- script/DeployL1Ens.s.sol | 24 ++++++------ ...lickResolver.sol => UniversalResolver.sol} | 6 +-- 3 files changed, 35 insertions(+), 32 deletions(-) rename src/nameservice/{ClickResolver.sol => UniversalResolver.sol} (96%) diff --git a/deploy/deploy_nodl_name_service.dp.ts b/deploy/deploy_nodl_name_service.dp.ts index 6650d7c..8554e54 100644 --- a/deploy/deploy_nodl_name_service.dp.ts +++ b/deploy/deploy_nodl_name_service.dp.ts @@ -7,8 +7,11 @@ import "@matterlabs/hardhat-zksync-verify/dist/src/type-extensions"; import * as dotenv from "dotenv"; dotenv.config(); -const SHOULD_DEPLOY = false; -let CONTRACT_ADDRESS = ""; +let CONTRACT_ADDRESS; + +if (!process.env.DEPLOYER_PRIVATE_KEY || !process.env.GOV_ADDR || !process.env.REGISTRAR_ADDR) { + throw new Error("DEPLOYER_PRIVATE_KEY, GOV_ADDR, and REGISTRAR_ADDR must be set"); +} module.exports = async function (hre: HardhatRuntimeEnvironment) { const rpcUrl = hre.network.config.url; @@ -27,22 +30,22 @@ module.exports = async function (hre: HardhatRuntimeEnvironment) { ]; const artifact = await deployer.loadArtifact("NameService"); - if (SHOULD_DEPLOY) { - const deploymentFee = await deployer.estimateDeployFee( - artifact, - constructorArgs - ); - console.log( - "NameService deployment fee (ETH): ", - ethers.formatEther(deploymentFee) - ); - const contract = await deployer.deploy(artifact, constructorArgs); - await contract.waitForDeployment(); - CONTRACT_ADDRESS = await contract.getAddress(); - console.log("Deployed NameService at", CONTRACT_ADDRESS); + if (!CONTRACT_ADDRESS) { + const deploymentFee = await deployer.estimateDeployFee( + artifact, + constructorArgs + ); + console.log( + "NameService deployment fee (ETH): ", + ethers.formatEther(deploymentFee) + ); + const contract = await deployer.deploy(artifact, constructorArgs); + await contract.waitForDeployment(); + CONTRACT_ADDRESS = await contract.getAddress(); + console.log("Deployed NameService at", CONTRACT_ADDRESS); - // Verify contract - console.log("Waiting for 5 confirmations..."); + // Verify contract + console.log("Waiting for 5 confirmations..."); await contract.deploymentTransaction()?.wait(5); } diff --git a/script/DeployL1Ens.s.sol b/script/DeployL1Ens.s.sol index b21fbf5..e7f020a 100644 --- a/script/DeployL1Ens.s.sol +++ b/script/DeployL1Ens.s.sol @@ -7,7 +7,7 @@ import { StorageProofVerifier, IZkSyncDiamond } from "lib/zksync-storage-proofs/packages/zksync-storage-contracts/src/StorageProofVerifier.sol"; -import {ClickResolver} from "../src/nameservice/ClickResolver.sol"; +import {UniversalResolver} from "../src/nameservice/UniversalResolver.sol"; interface IResolverSetter { function setResolver(bytes32 node, address resolver) external; @@ -42,28 +42,28 @@ contract DeployL1Ens is Script { console.log("Using StorageProofVerifier at", spvAddress); } - address clickResolverAddress = vm.envOr("CLICK_RESOLVER_ADDR", address(0)); + address resolverAddress = vm.envOr("NS_RESOLVER_ADDR", address(0)); - if (clickResolverAddress == address(0)) { - console.log("Deploying ClickResolver..."); - ClickResolver l1Resolver = new ClickResolver( - vm.envString("CNS_OFFCHAIN_RESOLVER_URL"), - vm.envAddress("CLK_OWNER_ADDR"), - vm.envAddress("CNS_ADDR"), + if (resolverAddress == address(0)) { + console.log("Deploying UniversalResolver..."); + UniversalResolver l1Resolver = new UniversalResolver( + vm.envString("NS_OFFCHAIN_RESOLVER_URL"), + vm.envAddress("NS_OWNER_ADDR"), + vm.envAddress("NS_ADDR"), StorageProofVerifier(spvAddress) ); - clickResolverAddress = address(l1Resolver); - console.log("Deployed ClickResolver at", clickResolverAddress); + resolverAddress = address(l1Resolver); + console.log("Deployed UniversalResolver at", resolverAddress); } - string memory label = vm.envString("CNS_DOMAIN"); + string memory label = vm.envString("NS_DOMAIN"); bytes32 labelHash = keccak256(abi.encodePacked(label)); bytes32 ETH_NODE = 0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae; bytes32 node = keccak256(abi.encodePacked(ETH_NODE, labelHash)); IResolverSetter resolverSetter = IResolverSetter(vm.envAddress("NAME_WRAPPER_ADDR")); - resolverSetter.setResolver(node, clickResolverAddress); + resolverSetter.setResolver(node, resolverAddress); vm.stopBroadcast(); } diff --git a/src/nameservice/ClickResolver.sol b/src/nameservice/UniversalResolver.sol similarity index 96% rename from src/nameservice/ClickResolver.sol rename to src/nameservice/UniversalResolver.sol index 7cae306..91a3c75 100644 --- a/src/nameservice/ClickResolver.sol +++ b/src/nameservice/UniversalResolver.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BSD-3-Clause-Clear /** - * @title ClickResolver for resolving ens subdomains based on names registered on L2 + * @title UniversalResolver for resolving ens subdomains based on names registered on L2 * @dev This contract is based on ClaveResolver that can be found in this repository: * https://github.com/getclave/zksync-storage-proofs */ @@ -20,7 +20,7 @@ interface IExtendedResolver { function resolve(bytes calldata name, bytes calldata data) external view returns (bytes memory); } -contract ClickResolver is IExtendedResolver, IERC165, Ownable { +contract UniversalResolver is IExtendedResolver, IERC165, Ownable { bytes4 private constant _EXTENDED_INTERFACE_ID = 0x9061b923; // ENSIP-10 bytes4 private constant _ADDR_SELECTOR = 0x3b3b57de; // addr(bytes32) @@ -158,7 +158,7 @@ contract ClickResolver is IExtendedResolver, IERC165, Ownable { string[] memory urls = new string[](1); urls[0] = url; - revert OffchainLookup(address(this), urls, callData, ClickResolver.resolveWithProof.selector, extraData); + revert OffchainLookup(address(this), urls, callData, UniversalResolver.resolveWithProof.selector, extraData); } /// @notice Callback used by CCIP read compatible clients to verify and parse the response. From debb3e643517423e41cdaca27e6213cce9c22c4b Mon Sep 17 00:00:00 2001 From: douglasacost Date: Wed, 14 May 2025 20:22:26 +0200 Subject: [PATCH 2/2] indexer post deployment updates --- .gitignore | 1 + subquery/mainnet-click.ts | 42 ++++++++++++++++++++++++++++++++++++ subquery/mainnet-complete.ts | 42 ++++++++++++++++++++++++++++++++++++ subquery/src/mappings/ens.ts | 4 ++-- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index fd48e63..6ac6220 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ docs/ # Dotenv file .env +.env* sa.json # Subquery files diff --git a/subquery/mainnet-click.ts b/subquery/mainnet-click.ts index 1a77cb1..c091daa 100644 --- a/subquery/mainnet-click.ts +++ b/subquery/mainnet-click.ts @@ -189,6 +189,48 @@ const project: EthereumProject = { ], }, }, + { + kind: EthereumDatasourceKind.Runtime, + startBlock: 51533910, // This is the block that the contract was deployed on + options: { + abi: "ENS", + address: "0x9741565272C7B29574c88ed2eBDF15BFE9C04612", + }, + assets: new Map([ + [ + "ENS", + { + file: "./abis/ENS.abi.json", + }, + ], + ]), + mapping: { + file: "./dist/index.js", + handlers: [ + { + kind: EthereumHandlerKind.Call, + handler: "handleCallRegistry", + filter: { + function: "register(address,string)", + }, + }, + { + kind: EthereumHandlerKind.Event, + handler: "handleENSTransfer", + filter: { + topics: ["Transfer(address,address,uint256)"], + }, + }, + { + kind: EthereumHandlerKind.Event, + handler: "handleENSTextRecord", + filter: { + topics: ["TextRecordSet(uint256,string,string)"], + }, + }, + ], + }, + }, ], }; diff --git a/subquery/mainnet-complete.ts b/subquery/mainnet-complete.ts index a114e6b..f68ba66 100644 --- a/subquery/mainnet-complete.ts +++ b/subquery/mainnet-complete.ts @@ -425,6 +425,48 @@ const project: EthereumProject = { ], }, }, + { + kind: EthereumDatasourceKind.Runtime, + startBlock: 51533910, // This is the block that the contract was deployed on + options: { + abi: "ENS", + address: "0x9741565272C7B29574c88ed2eBDF15BFE9C04612", + }, + assets: new Map([ + [ + "ENS", + { + file: "./abis/ENS.abi.json", + }, + ], + ]), + mapping: { + file: "./dist/index.js", + handlers: [ + { + kind: EthereumHandlerKind.Call, + handler: "handleCallRegistry", + filter: { + function: "register(address,string)", + }, + }, + { + kind: EthereumHandlerKind.Event, + handler: "handleENSTransfer", + filter: { + topics: ["Transfer(address,address,uint256)"], + }, + }, + { + kind: EthereumHandlerKind.Event, + handler: "handleENSTextRecord", + filter: { + topics: ["TextRecordSet(uint256,string,string)"], + }, + }, + ], + }, + }, ], }; diff --git a/subquery/src/mappings/ens.ts b/subquery/src/mappings/ens.ts index d8a922f..653c07d 100644 --- a/subquery/src/mappings/ens.ts +++ b/subquery/src/mappings/ens.ts @@ -10,9 +10,9 @@ import { ethers } from "ethers"; import { keccak256, toUtf8Bytes } from "ethers/lib/utils"; const CLICK_NS_ADDR = - process.env.CLICK_NS_ADDR || "0xC84A95a3A012F25CdAa9922066427768Ef2186e5"; + process.env.CLICK_NS_ADDR || "0xF3271B61291C128F9dA5aB208311d8CF8E2Ba5A9"; const NODLE_NS_ADDR = - process.env.NODLE_NS_ADDR || "0x4a430a543Ab201307a5D33f5bab4056B5844DcA0"; + process.env.NODLE_NS_ADDR || "0x9741565272C7B29574c88ed2eBDF15BFE9C04612"; const whitelistKeys = { [keccak256(toUtf8Bytes("avatar"))]: "avatar", [keccak256(toUtf8Bytes("description"))]: "description",