Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ens infra #1830

Draft
wants to merge 6 commits into
base: origin-dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@
"build"
],
"dependencies": {
"@ensdomains/ens": "0.4.4",
"@ensdomains/resolver": "0.2.4",
"@ensdomains/ens-contracts": "0.0.22",
"content-hash": "2.5.2",
"eth-ens-namehash": "2.0.8",
"ethers": "5.6.6"
},
"devDependencies": {
"@types/node": "18.15.3",
"rimraf": "3.0.2",
"ts-node": "10.9.1",
"typescript": "4.9.5"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,130 @@
import { loadContract, deploy, utf8ToKeccak256 } from "./utils";
import { loadContract, deploy, utf8ToKeccak256, computeInterfaceId } from "./utils";

import { ethers } from "ethers";

const ensJSON = loadContract("ens", "ENSRegistry");
const fifsRegistrarJSON = loadContract("ens", "FIFSRegistrar");
const reverseRegistrarJSON = loadContract("ens", "ReverseRegistrar");
const publicResolverJSON = loadContract("resolver", "PublicResolver");
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";

const ensJSON = loadContract( "registry", "ENSRegistry");
const dummyOracleJSON = loadContract( "ethregistrar", "DummyOracle");
const stablePriceOracleJSON = loadContract( "ethregistrar", "StablePriceOracle");
const baseRegistrarJSON = loadContract( "ethregistrar", "BaseRegistrarImplementation");
const ethControllerJSON = loadContract( "deployments", "ETHRegistrarController");
const reverseRegistrarJSON = loadContract("deployments", "ReverseRegistrar");
const nameWrapperJSON = loadContract( "deployments", "NameWrapper");
const publicResolverJSON = loadContract( "deployments", "PublicResolver");

const iNameWrapperJSON = loadContract( "wrapper", "INameWrapper");
const iEthControllerJSON = loadContract( "ethregistrar", "IETHRegistrarController");

const tld = "eth";

export async function deployENS(provider: ethers.providers.JsonRpcProvider) {
const signer = provider.getSigner();
const signerAddress = await signer.getAddress();
// Registry
console.log("deploying registry");
const ens = await deploy(provider, ensJSON);

// Resolver
const resolver = await deploy(provider, publicResolverJSON, ens.address);
await setupResolver(ens, resolver, signerAddress);
// Reverse Registrar
console.log("deploying reverse registrar");
const reverse = await deploy(
provider,
reverseRegistrarJSON,
ens.address
);
console.log("setting up reverse registrar");
await setupReverseRegistrar(ens, reverse, signerAddress);

// Registrar
const registrar = await deploy(
// Base Registrar
console.log("deploying base registrar");
const baseRegistrar = await deploy(
provider,
fifsRegistrarJSON,
baseRegistrarJSON,
ens.address,
ethers.utils.namehash(tld)
);
await setupRegistrar(ens, registrar, signerAddress);
console.log("setting up eth registrar");
await setupBaseRegistrar(ens, baseRegistrar);

// Reverse Registrar
const reverse = await deploy(
// Name Wrapper
console.log("deploying name wrapper");
const nameWrapper = await deploy(
provider,
reverseRegistrarJSON,
nameWrapperJSON,
ens.address,
resolver.address
baseRegistrar.address,
ZERO_ADDRESS,
);
await setupReverseRegistrar(ens, reverse, signerAddress);
console.log("setting up name wrapper");
await setupNameWrapper(baseRegistrar, nameWrapper);

// Eth Registrar Controller
console.log("deploying dummy oracle")
const dummyOracle = await deploy(
provider,
dummyOracleJSON,
0
);
console.log("deploying stable price oracle")
const stablePriceOracle = await deploy(
provider,
stablePriceOracleJSON,
dummyOracle.address,
[0, 0, 0, 0, 0],
);
console.log("deploying eth registrar controller");
const ethController: ethers.Contract = await deploy(
provider,
ethControllerJSON,
baseRegistrar.address,
stablePriceOracle.address,
1,
3655,
reverse.address,
nameWrapper.address,
ens.address,
);
await setupEthRegistrar(ethController, nameWrapper, reverse);

// Resolver
console.log("deploying resolver")
const resolver = await deploy(
provider,
publicResolverJSON,
ens.address,
nameWrapper.address,
ethController.address,
reverse.address,
);
console.log("setting up resolver")
await setupResolver(ens, resolver, reverse, nameWrapper, ethController);

return {
ensAddress: ens.address,
resolverAddress: resolver.address,
registrarAddress: registrar.address,
registrarAddress: ethController.address,
reverseAddress: reverse.address,
};
}

async function setupResolver(
async function setupBaseRegistrar(
ens: ethers.Contract,
resolver: ethers.Contract,
accountAddress: string
registrar: ethers.Contract
) {
const resolverNode = ethers.utils.namehash("resolver");
const resolverLabel = utf8ToKeccak256("resolver");

await ens.setSubnodeOwner(
ethers.utils.hexZeroPad(ethers.constants.AddressZero, 32),
resolverLabel,
accountAddress
utf8ToKeccak256(tld),
registrar.address
);
await ens.setResolver(resolverNode, resolver.address);
await resolver["setAddr(bytes32,address)"](resolverNode, resolver.address);
}

async function setupRegistrar(
ens: ethers.Contract,
registrar: ethers.Contract,
accountAddress: string
async function setupEthRegistrar(
ethController: ethers.Contract,
nameWrapper: ethers.Contract,
reverseRegistrar: ethers.Contract,
) {
await ens.setSubnodeOwner(
ethers.utils.hexZeroPad(ethers.constants.AddressZero, 32),
utf8ToKeccak256(tld),
registrar.address
);
await nameWrapper.setController(ethController.address, true);
await reverseRegistrar.setController(ethController.address, true);
}

async function setupReverseRegistrar(
Expand All @@ -90,3 +143,38 @@ async function setupReverseRegistrar(
reverseRegistrar.address
);
}

async function setupResolver(
ens: ethers.Contract,
resolver: ethers.Contract,
reverseRegistrar: ethers.Contract,
nameWrapper: ethers.Contract,
ethController: ethers.Contract,
) {
const tldNode = ethers.utils.namehash("eth");

const iNameWrapper = new ethers.utils.Interface(iNameWrapperJSON.abi)
const iNameWrapperId = computeInterfaceId(iNameWrapper);
console.log(`setting resolver iNameWrapper interface with id ${iNameWrapperId}`)
await resolver.setInterface(tldNode, iNameWrapperId, nameWrapper.address);

const iEthController = new ethers.utils.Interface(iEthControllerJSON.abi)
const iEthControllerId = computeInterfaceId(iEthController);
console.log(`setting resolver iEthController interface with id ${iEthControllerId}`)
await resolver.setInterface(tldNode, iEthControllerId, ethController.address);

const resolverNode = ethers.utils.namehash("resolver.eth");
console.log("calling ens.setResolver")
await ens.setResolver(resolverNode, resolver.address);
console.log("calling resolver.setAddr")
await resolver.setAddr(resolverNode, resolver.address);
console.log("calling reverseRegistrar.setDefaultResolver")
await reverseRegistrar.setDefaultResolver(resolver.address);
}

async function setupNameWrapper(
registrar: ethers.Contract,
nameWrapper: ethers.Contract,
) {
await registrar.addController(nameWrapper.address)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { loadContract, utf8ToKeccak256 } from "./utils";
import { ethers } from "ethers";

const contentHash = require("content-hash");
const ensJSON = loadContract("ens", "ENSRegistry");
const fifsRegistrarJSON = loadContract("ens", "FIFSRegistrar");
const publicResolverJSON = loadContract("resolver", "PublicResolver");

const ensJSON = loadContract( "registry", "ENSRegistry");
const fifsRegistrarJSON = loadContract( "registry", "FIFSRegistrar");
const publicResolverJSON = loadContract( "deployments", "PublicResolver");

interface RegisterArgs {
provider: ethers.providers.JsonRpcProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@ interface ContractJson {
bytecode: string;
}

export function loadContract(
modName: string,
contractName: string
): ContractJson {
if (modName === "ens") {
const ens = require(`@ensdomains/ens`);
return ens[contractName];
export function loadContract(modName: string, contractName: string): ContractJson {
if (modName === "deployments") {
return require(`@ensdomains/ens-contracts/deployments/mainnet/${contractName}`);
}
return require(`@ensdomains/${modName}/build/contracts/${contractName}`);
return require(`@ensdomains/ens-contracts/artifacts/contracts/${modName}/${contractName}.sol/${contractName}`);
}

export async function deploy(
Expand All @@ -32,6 +28,33 @@ export async function deploy(
return contract;
}

export async function utf8ToKeccak256(value: string) {
export function utf8ToKeccak256(value: string) {
return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(value));
}

export function computeInterfaceId(iface: ethers.utils.Interface) {
const functions = Object.values(iface.functions);
const sigHashes = functions.map((frag) => frag.format('sighash'));
return makeInterfaceIdERC165(sigHashes);
}

// see https://github.com/OpenZeppelin/openzeppelin-test-helpers/blob/master/src/makeInterfaceId.js
function makeInterfaceIdERC165 (functionSignatures: string[] = []) {
const INTERFACE_ID_LENGTH = 4;

const interfaceIdBuffer = functionSignatures
.map(signature => utf8ToKeccak256(signature)) // keccak256
.map(h =>
Buffer
.from(h.substring(2), 'hex')
.slice(0, 4) // bytes4()
)
.reduce((memo, bytes) => {
for (let i = 0; i < INTERFACE_ID_LENGTH; i++) {
memo[i] = memo[i] ^ bytes[i]; // xor
}
return memo;
}, Buffer.alloc(INTERFACE_ID_LENGTH));

return `0x${interfaceIdBuffer.toString('hex')}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ export const ETH_ENS_IPFS_MODULE_CONSTANTS = {
ethereumProvider: "http://localhost:8545",
ensAddresses: {
ensAddress: "0xe78A0F7E598Cc8b0Bb87894B0F60dD2a88d6a8Ab",
resolverAddress: "0x5b1869D9A4C187F2EAa108f3062412ecf0526b24",
registrarAddress: "0xD833215cBcc3f914bD1C9ece3EE7BF8B14f841bb",
reverseAddress: "0xe982E462b094850F12AF94d21D470e21bE9D0E9C",
resolverAddress: "0x9561C133DD8580860B6b7E504bC5Aa500f0f06a7",
registrarAddress: "0x5b1869D9A4C187F2EAa108f3062412ecf0526b24",
reverseAddress: "0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B",
}
} as const;
// $end
Loading