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 EIP: Contract Discovery and eTLD+1 Association #7815

Closed
wants to merge 29 commits into from
Closed
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4b498c0
first commit
TtheBC01 Oct 2, 2023
bfe4897
VALUE formatting
TtheBC01 Oct 2, 2023
d1e1488
VALUE formatting
TtheBC01 Oct 2, 2023
3f7408c
capitalization
TtheBC01 Oct 2, 2023
87b9151
capitalization
TtheBC01 Oct 2, 2023
3502677
Update eip-draft-contract-ownership-via-DoH.md
SnickerChar Oct 4, 2023
a5c417e
update
TtheBC01 Oct 4, 2023
9b90fd6
Merge branch 'master' of https://github.com/SnickerdoodleLabs/EIPs
TtheBC01 Oct 4, 2023
50985fe
formatting
TtheBC01 Oct 4, 2023
f8a504a
formatting
TtheBC01 Oct 4, 2023
5373dad
restructuring
TtheBC01 Oct 4, 2023
80dd5a2
new example
TtheBC01 Oct 4, 2023
2ed56de
removed weak example
TtheBC01 Oct 4, 2023
78e1d79
removed TTL specification
TtheBC01 Oct 4, 2023
32b54b0
update
TtheBC01 Oct 4, 2023
2377048
update
TtheBC01 Oct 4, 2023
2b17a93
update
TtheBC01 Oct 4, 2023
8fa8cc0
spelling
TtheBC01 Oct 4, 2023
8345741
Merge branch 'ethereum:master' into master
TtheBC01 Oct 4, 2023
d1e43c0
Update with changes from EIP Walidator
SnickerChar Oct 4, 2023
e04c4cc
Second time through with the EIP Walidator
SnickerChar Oct 4, 2023
5369269
Third update for Walidator
SnickerChar Oct 4, 2023
182a325
Update all EIPXXXX to EIP7528
SnickerChar Oct 4, 2023
ca327b6
Change host header from EIP7528 to EIP-7528
SnickerChar Oct 4, 2023
f7a1f8a
Link first instance of ERC-7528, change EIP-7528 to ERC-7528.
SnickerChar Oct 4, 2023
06eae3d
changed eip number
TtheBC01 Oct 4, 2023
42ba7d1
Update eip-7529.md
TtheBC01 Oct 19, 2023
9c2e529
Update eip-7529.md
TtheBC01 Oct 19, 2023
98c034e
EIP-7529: simplification to HOST naming scheme
TtheBC01 Oct 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
157 changes: 157 additions & 0 deletions EIPS/eip-7529.md
@@ -0,0 +1,157 @@
---
eip: 7529
title: Contract Discovery and eTLD+1 Association
description: A simple method for leveraging TXT Records to discover, verify and associate a smart contract with the owner of a DNS domain.
author: Todd Chapman (@tthebc01), Charlie Sibbach <charlie@cwsoftware.com>, Sean Sing (@seansing)
discussions-to: https://ethereum-magicians.org/t/add-eip-dns-over-https-for-contract-discovery-and-etld-1-association/15996
status: Draft
type: Standards Track
category: ERC
created: 2023-09-30
requires: 1191
---

## Abstract

The introduction of DNS over HTTPS (DoH) in [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) has enabled tamper-resistant client-side queries of DNS records directly from the browser context. [ERC-7529](./eip-7529.md) describes a simple standard leveraging DoH to fetch TXT records which are used for discovering and verifying the association of a smart contract with a common DNS domain.

## Motivation

As mainstream businesses begin to adopt public blockchain and digital asset technologies more rapidly, there is a growing need for a discovery/search mechanism (compatible with conventional browser resources) of smart contracts associated with a known business domain as well as reasonable assurance that the smart contract does indeed belong to the business owner of the DNS domain. The relatively recent introduction and widespread support of DoH means it is possible to make direct queries of DNS records straight from the browser context and thus leverage a simple TXT record as a pointer to an on-chain smart contract.

A TXT pointer coupled with an appropriate smart contract interface (described in this ERC) yields a simple, yet flexible and robust mechanism for the client-side detection and reasonably secure verification of on-chain logic and digital assets associated with a the owner of a domain name. For example, a stablecoin issuer might leverage this standard to provide a method for an end user or web-based end user client to ensure that the asset their wallet is interacting with is indeed the contract issued or controlled by the owner or administrator of a well known DNS domain.

**Example 1**:

A user visits merchant.com who accepts payments via paymentprocessor.com. The business behind paymentprocessor.com has previously released a stable coin for easier cross-border payments which adheres to this ERC. On the checkout page, paymentprocessor.com is mounted as an iframe component. If the user has installed a browser-extension wallet compatible with this standard, then the wallet can detect the domain of the iframe in the context of the checkout page, discover and verify the stable coin's association with paymentprocessor.com, and automatically prompt to complete the purchase in paymentprocessor.com's stable coin.

**Example 2**:

A user visits nftmarketplace.io to buy a limited release NFT from theirfavoritebrand.com. The marketplace app can leverage this ERC to allow the user to search by domain name and also indicate to the user that an NFT of interest is indeed an authentic asset associated with theirfavoritebrand.com.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

### Contract Pointers in TXT Records

The owner of a domain name MUST create a TXT record in their DNS settings that serves as a pointer to all relevant smart contracts they wish to associate with their domain.

[TXT records](https://www.rfc-editor.org/rfc/rfc1035#section-3.3.14) are not intended (nor permitted by most DNS servers) to store large amounts of data. Every DNS provider has their own vendor-specific character limits. However, an EVM-compatible address string is 42 characters, so most DNS providers will allow for dozens of contract addresses to be stored under a single record. Furthermore, a domain is allowed to have multiple TXT records associated with the same host and the content of all duplicate records can be retrived in a single DoH query.

The TXT record MUST adhere to the following schema:

- `HOST`: ERC-7529.`chain_id`._domaincontracts
- `VALUE`: \<address 1\>,\<address 2\>,...

This `HOST` naming scheme is designed to mimic the [DKIM](https://www.rfc-editor.org/rfc/rfc6376) naming convention. Additionally, this naming scheme makes it simple to programmatically ascertain if any smart contracts are associated with the domain on a given blockchain network. Prepending with "ERC-7529" will prevent naming collisions. The value of `chain_id` is simply the integer associated with the target network (i.e. `1` for Ethereum mainnet or `42` for Polygon). So, a typical `HOST` might be: `ERC-7529.1._domainContracts`, `ERC-7529.42._domaincontracts`, etc.

It is RECOMMENDED that EVM address strings adhere to [ERC-1191](./eip-1191.md) so that the browser client can checksum the validity of the address and its target network before making an RPC call.

A user can check the propagation of their TXT record from the browser console with `fetch`:

```
await fetch("https://cloudflare-dns.com/dns-query?name=ERC-7529.1._domaincontracts.example.com&type=TXT", {
headers: {
Accept: "application/dns-json"
}
})
```

### Smart Contract Association with a Domain

Any smart contract MAY implement this ERC to provide a verification mechanism of smart contract addresses listed in a compatible TXT record.

A smart contract need only store one new member variable, `domains`, which is an array of all unique eTLD+1 domains associated with the contract. This member variable can be written to with the external functions `addDomain` and `removeDomain`.

```solidity
{
public string[] domains; // a string list of eTLD+1 domains associated with this contract

function addDomain(string memory domain) external; // an authenticated method to add an eTLD+1

function removeDomain(string memory domain) external; // an authenticated method to remove an eTLD+1
}
```

### Client-side Verification

The user client MUST verify that the eTLD+1 of the TXT record matches an entry in the `domains` list of the smart contract.

When a client detects a compatible TXT record listed on an eTLD+1, it MUST loop through each listed contract address and, via an appropriate RPC provider, collect the `domains` array from each contract in the list. The client should detect an eTLD+1 entry in the contract's `domains` array that exactly matches (DNS domains are not case-sensitive) the eTLD+1 of the TXT record.

Alternatively, if a client is inspecting a contract that implements this ERC, the client SHOULD collect the `domains` array from the contract and then attempt to fetch TXT records from all listed eTLD+1 domains to ascertain its association or authenticity. The client MUST confirm that the contract address is contained in a TXT record's `VALUE` field of the eTLD+1 pointed to by the contract's `domains` array.

## Rationale

According to Cloudflare, the two most common use cases of TXT records today are email spam prevention (via [SPF](https://www.rfc-editor.org/rfc/rfc7208), DKIM, and [DMARC](https://www.rfc-editor.org/rfc/rfc7489) TXT records) and domain ownership verification. The use case considered here for on-chain smart contract discovery and verification is essentially analogous. Now that DoH is supported by most major DNS providers, it is easy to leverage TXT records directly in wallets, dApps, and other web applications without relying on a proprietary vendor API to provide DNS information and thus gain the same benefits afforded to email and domain verification with digital assets and on-chain logic.

The client working with the smart contract is protected by cross-checking that two independent sources of information agree with each other. As long as the `addDomain` and `removeDomain` calls on the smart contract are properly authenticated (as shown in the reference implementation), the values in the domains field must have been set by a controller of the contract. The contract addresses in the TXT records can only be set by the owner of the domain. For these two values to align the same organization must control both resources.

## Backwards Compatibility

No backward compatibility issues found.

## Reference Implementation

The implementation of `addDomain` and `removeDomain` is a trivial exercise, but candidate implementations are given here for completeness (note that these functions are unlikely to be called often, so gas optimizations are possible):

```solidity
function addDomain(
string memory domain
) external onlyRole(DEFAULT_ADMIN_ROLE) {
string[] memory domainsArr = domains;

// check if domain already exists in the array
for (uint256 i; i < domains.length; ) {
if (
keccak256(abi.encodePacked((domainsArr[i]))) ==
keccak256(abi.encodePacked((domain)))
) {
revert("Consent : Domain already added");
}
unchecked {
++i;
}
}
domains.push(domain);
}

function removeDomain(
string memory domain
) external onlyRole(DEFAULT_ADMIN_ROLE) {
string[] memory domainsArr = domains;
// A check that is incremented if a requested domain exists
uint8 flag;
for (uint256 i; i < domains.length; ) {
if (
keccak256(abi.encodePacked((domainsArr[i]))) ==
keccak256(abi.encodePacked((domain)))
) {
// replace the index to delete with the last element
domains[i] = domains[domains.length - 1];
// delete the last element of the array
domains.pop();
// update to flag to indicate a match was found
flag++;
break;
}
unchecked {
++i;
}
}
require(flag > 0, "Consent : Domain is not in the list");
}
```

**NOTE**: It is important that appropriate account authentication be applied to `addDomain` and `removeDomain` so that only authorized users may update the `domains` list. In the given reference implementation the `onlyRole` modifier is used to restrict call privileges to accounts with the `DEFAULT_ADMIN_ROLE` which can be added to any contract with the OpenZeppelin access control library.

## Security Considerations

Due to the reliance on traditional DNS systems, this ERC is susceptible to attacks on this technology, such as domain hijacking. Additionally, it is the responsibility of the smart contract author to ensure that `addDomain` and `removeDomain` are authenticated properly, otherwise an attacker could associate their smart contract with an undesirable domain, which would simply break the ability to verify association with the proper domain.

It is worth noting that for an attacker to falsy verify a contract against a domain would require them to compromise both the DNS settings **and** the smart contract itself. In this scenario, the attacker has likely also compromised the business' email domains as well.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).