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

Add support interface #21

Merged
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
6 changes: 3 additions & 3 deletions crosschain-resolver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const l2resolverAddress = await l2Factory.predictAddress(ETH_ADDRESS)
- DelegatableResolverRegistrar = [DelegatableResolverRegistrar](https://goerli-optimism.etherscan.io/address/0x2b07cf3ef421a5ff1cb6f437036bdef132eea37b#writeContract) = Demo contract that allow anyone to register subname under `op.evmgateway.eth` on [L2 resolver on `op.evmgateway.eth`](https://goerli-optimism.etherscan.io/address/0x96753bd0D9bdd98d3a84837B5933078AF49aF12d#writeContract)

#### L1
- L1Resolver = [0x65a0963A2941A13a96FcDCfE36c94c6a341f26E5](https://goerli.etherscan.io/address/0x65a0963A2941A13a96FcDCfE36c94c6a341f26E5) = Currently `op.evmgateway.eth` is set to the resolver
- L1Resolver = [0x7Bf57B0a683CC964B0fEe30633A72F5c05464a0f](https://goerli.etherscan.io/address/0x7Bf57B0a683CC964B0fEe30633A72F5c05464a0f) = Currently `op.evmgateway.eth` is set to the resolver

### Base

Expand All @@ -121,7 +121,7 @@ const l2resolverAddress = await l2Factory.predictAddress(ETH_ADDRESS)
- DelegatableResolverRegistrar = [DelegatableResolverRegistrar](https://goerli.basescan.org/address/0xe0356133c3c43cbb623543488e607e4e349eaa10#code) = Demo contract that allow anyone to register subname under `base.evmgateway.eth` on [L2 resolver on `base.evmgateway.eth`](https://goerli.basescan.org/address/0xE4B18eFbF71d516046514598FD7FcFbad4beC742)

#### L1
- L1Resolver = [0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D](https://goerli.etherscan.io/address/0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D) = Currently `base.evmgateway.eth` is set to the resolver
- L1Resolver = [0x3Ac25843A1F696fe2166C5dE127FD4f2832F4d42](https://goerli.etherscan.io/address/0x3Ac25843A1F696fe2166C5dE127FD4f2832F4d42) = Currently `base.evmgateway.eth` is set to the resolver


## Usage
Expand Down Expand Up @@ -214,7 +214,7 @@ Once done, set addrss of the subname from the operator, wait 10~20 min, then que
Go to [Base L1 resolver](https://goerli.etherscan.io/address/0x052D7E10D55Ae12b4F62cdE18dBb7E938efa230D#readContract)

```
[node, target] = l1resolver.getTarget(encodedname, 0)
[node, target] = l1resolver.getTarget(encodedname)
```

#### Step 2: Deploy the registrar contract
Expand Down
8 changes: 8 additions & 0 deletions crosschain-resolver/contracts/ITargetResolver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

interface ITargetResolver{
function getTarget(
makoto marked this conversation as resolved.
Show resolved Hide resolved
bytes memory name
) external view returns (bytes32 node, address target);
}
34 changes: 25 additions & 9 deletions crosschain-resolver/contracts/L1Resolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import {IAddrResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profi
import {IAddressResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IAddressResolver.sol";
import {ITextResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol";
import {IContentHashResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/IContentHashResolver.sol";
import "@ensdomains/ens-contracts/contracts/resolvers/profiles/IExtendedResolver.sol";
import {ITargetResolver} from './ITargetResolver.sol';
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";


contract L1Resolver is EVMFetchTarget {
contract L1Resolver is EVMFetchTarget, ITargetResolver, IExtendedResolver, ERC165 {
using EVMFetcher for EVMFetcher.EVMFetchRequest;
using BytesUtils for bytes;
IEVMVerifier immutable verifier;
ENS immutable ens;
INameWrapper immutable nameWrapper;
IEVMVerifier public immutable verifier;
ENS public immutable ens;
INameWrapper public immutable nameWrapper;
mapping(bytes32 => address) targets;
uint256 constant COIN_TYPE_ETH = 60;
uint256 constant RECORD_VERSIONS_SLOT = 0;
Expand Down Expand Up @@ -72,19 +74,24 @@ contract L1Resolver is EVMFetchTarget {
/**
* @dev Returns the L2 target address that can answer queries for `name`.
* @param name DNS encoded ENS name to query
* @param offset The offset of the label to query recursively.
* @return node The node of the name
* @return target The L2 resolver address to verify against.
*/
function getTarget(
bytes memory name
) public view returns (bytes32 node, address target) {
return _getTarget(name, 0);
}

function _getTarget(
bytes memory name,
uint256 offset
) public view returns (bytes32 node, address target) {
) private view returns (bytes32 node, address target) {
uint256 len = name.readUint8(offset);
node = bytes32(0);
if (len > 0) {
bytes32 label = name.keccak(offset + 1, len);
(node, target) = getTarget(
(node, target) = _getTarget(
name,
offset + len + 1
);
Expand All @@ -111,7 +118,7 @@ contract L1Resolver is EVMFetchTarget {
* @return result result of the call
*/
function resolve(bytes calldata name, bytes calldata data) external view returns (bytes memory result) {
(, address target) = getTarget(name, 0);
(, address target) = _getTarget(name, 0);
bytes4 selector = bytes4(data);

if (selector == IAddrResolver.addr.selector) {
Expand Down Expand Up @@ -210,4 +217,13 @@ contract L1Resolver is EVMFetchTarget {
) public pure returns (bytes memory) {
return abi.encode(values[1]);
}

function supportsInterface(
bytes4 interfaceId
) public override view returns (bool) {
return
makoto marked this conversation as resolved.
Show resolved Hide resolved
interfaceId == type(IExtendedResolver).interfaceId ||
interfaceId == type(ITargetResolver).interfaceId ||
super.supportsInterface(interfaceId);
}
}
4 changes: 2 additions & 2 deletions crosschain-resolver/scripts/getaddr.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import packet from 'dns-packet';
const encodeName = (name) => '0x' + packet.name.encode(name).toString('hex')
const l1abi = [
"function getTarget(bytes,uint256) view returns (bytes32, address)",
"function getTarget(bytes) view returns (bytes32, address)",
"function addr(bytes32) view returns (address)",
"function resolve(bytes,bytes) view returns (bytes)",
]
Expand Down Expand Up @@ -32,7 +32,7 @@ export const main = async () => {
}
console.log({ENS_NAME, resolver, encodedname, node})
const l1resolver = new ethers.Contract(resolver.address, l1abi, l1provider);
const target = await l1resolver.getTarget(encodedname, 0)
const target = await l1resolver.getTarget(encodedname)
const l2resolverAddress = target[1]
console.log('Target is set to ' + l2resolverAddress);
const l2resolver = new ethers.Contract(l2resolverAddress, l2abi, l2provider);
Expand Down
14 changes: 10 additions & 4 deletions crosschain-resolver/test/testResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ describe('Crosschain Resolver', () => {
}catch(e){
}

const result = await target.getTarget(incorrectname, 0)
const result = await target.getTarget(incorrectname)
expect(result[1]).to.equal(EMPTY_ADDRESS);
})

it("should allow owner to set target", async() => {
await target.setTarget(node, signerAddress)
const result = await target.getTarget(encodeName(name), 0)
const result = await target.getTarget(encodeName(name))
expect(result[1]).to.equal(signerAddress);
})

Expand All @@ -174,7 +174,7 @@ describe('Crosschain Resolver', () => {
const encodedsubname = encodeName(subname)
const subnode = ethers.namehash(subname)
await target.setTarget(node, signerAddress)
const result = await target.getTarget(encodedsubname, 0)
const result = await target.getTarget(encodedsubname)
expect(result[0]).to.equal(subnode);
expect(result[1]).to.equal(signerAddress);
})
Expand All @@ -193,7 +193,7 @@ describe('Crosschain Resolver', () => {
const wrappedtnode = ethers.namehash(`${label}.eth`)
await target.setTarget(wrappedtnode, resolverAddress)
const encodedname = encodeName(`${label}.eth`)
const result = await target.getTarget(encodedname, 0)
const result = await target.getTarget(encodedname)
expect(result[1]).to.equal(resolverAddress);
})

Expand Down Expand Up @@ -290,4 +290,10 @@ describe('Crosschain Resolver', () => {
const decoded = i.decodeFunctionResult("contenthash", result2)
expect(decoded[0]).to.equal(contenthash);
})

it("should support interface", async() => {
expect(await target.supportsInterface('0x15f64386')).to.equal(true) // ITargetResolver
expect(await target.supportsInterface('0x9061b923')).to.equal(true) // IExtendedResolver
expect(await target.supportsInterface('0x01ffc9a7')).to.equal(true) // ERC-165 support
})
});
14 changes: 13 additions & 1 deletion crosschain-reverse-resolver/contracts/L1ReverseResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ pragma solidity ^0.8.17;
import {EVMFetcher} from '@ensdomains/evm-verifier/contracts/EVMFetcher.sol';
import {EVMFetchTarget} from '@ensdomains/evm-verifier/contracts/EVMFetchTarget.sol';
import {IEVMVerifier} from '@ensdomains/evm-verifier/contracts/IEVMVerifier.sol';
import "@ensdomains/ens-contracts/contracts/resolvers/profiles/INameResolver.sol";
import "@ensdomains/ens-contracts/contracts/resolvers/profiles/ITextResolver.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

contract L1ReverseResolver is EVMFetchTarget {
contract L1ReverseResolver is EVMFetchTarget, INameResolver, ITextResolver, ERC165 {
using EVMFetcher for EVMFetcher.EVMFetchRequest;
IEVMVerifier immutable verifier;
address immutable target;
Expand Down Expand Up @@ -67,4 +70,13 @@ contract L1ReverseResolver is EVMFetchTarget {
) public pure returns (string memory) {
return string(values[1]);
}

function supportsInterface(
bytes4 interfaceId
) public override view returns (bool) {
return
interfaceId == type(ITextResolver).interfaceId ||
interfaceId == type(INameResolver).interfaceId ||
super.supportsInterface(interfaceId);
}
}
5 changes: 5 additions & 0 deletions crosschain-reverse-resolver/test/testReverseResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,9 @@ describe('Crosschain Reverse Resolver', () => {
expect(result2).to.equal(value);
})

it("should support interface", async() => {
expect(await target.supportsInterface('0x59d1d43c')).to.equal(true) // ITextResolver
expect(await target.supportsInterface('0x691f3431')).to.equal(true) // INameResolver
expect(await target.supportsInterface('0x01ffc9a7')).to.equal(true) // ERC-165 support
})
});
Loading