During everyday internet use, name services like the Domain Name System (DNS) power our ability to seamlessly navigate the web, however solutions that bring us closer to web3 ideals, particularly for use with fully decentralized applications, have yet to see widespread adoption.
In contrast to the tightly governed DNS, services managed by participants of decentralized blockchain networks aim to bring credible neutrality, permissionless access, and direct ownership and control over domain names.
ℹ️ While DNS is in fact comprised of a distributed system of hierarchical name servers and one we’ll continue to rely upon for IP address translation and content resolution over HTTPS via our selected third party gateway – ICANN, which oversees the Internet Assigned Numbers Authority and in turn manages the DNS root zone, is governed by a 16 member voting body.
As we explored decentralized hosting options and captured relevant takeaways during our decision making process in this post by Lorenzo Sicilia, we were also keen to identify Web3 name services that aligned with the presented acceptance criteria – namely simplified CI/CD integration and the ability to economically pay for any state changes with tokens. Furthermore, the service had to play well with the selected storage solution, Arweave’s Permaweb.
Selecting a name service
To guide our web3 name service selection process, we defined several acceptance criteria as follows:
- EVM compatible: provide full functionality with EVM addresses.
- Human readable domain: provide users with easy to read, recognizable, and memorable domain names.
- Decentralized: be a decentralized protocol and minimise single point of failure risk.
- CI/CD friendly: supports programmatic updates to the domain’s record(s) which in turn enables easy integration into a DevOps pipeline.
- Economic: requires no or nominal transaction fees when updating the domain’s record.
Based on these criteria, we considered several mature as well as some nascent name services.
Name | Ecosystem(s) Support | Decentralized | Maturity | Registration Pricing | Content Record Type(s) | Record Update Cost |
Ethereum Name Service (ENS) | Ethereum Mainnet | Yes | Live | Annual lease, priced by name length | IPFS CIDs and Arweave transaction IDs | High |
Layer 2 ENS | Optimism Mainnet + Goerli Testnet | Yes | Early-stage testing | Assumed similar to ENS | Assumed similar to ENS | Assumed very low |
Unstoppable Domains | Multi-domain (e.g., .eth, .crypto, .com) | No | Live | One-time payment, owned irrevocably (excl. .eth and .com) | IPFS | Very low |
Arweave Name System (ArNS) | Arweave | Yes | Late-stage testing | One-time payment, owned irrevocably | Arweave transaction IDs | Very low |
Ethereum Name Service (ENS)
The .eth suffix offered by ENS is by far the most recognized and adopted EVM name service in web3 – but name registration has largely been driven by users seeking a unique identifier for their personal crypto addresses. Importantly for our purposes, aside from enabling users to set this primary name that supports resolving a wallet address (0x123…aBc) to a human readable ENS name (outlierventures.eth), each ENS name also allows the owner to set distinct ‘records’ that can point to text, other Ethereum addresses, application binary interfaces (ABIs), or content hashes.
View of the Records tab on https://app.ens.domains/
By setting this record to a content hash, we can leverage the easily identifiable ENS name as a human readable domain name that points users to the decentralized front end of our application.
ℹ️ ENS supports setting content hash records to either an IPFS content identifier (CID) or an Arweave transaction hash.
This is a great first step BUT we’re making a couple assumptions:
- That .eth isn’t already an in-use DNS top-level domain that might create resolution conflicts when used in a browser – fortunately for us it’s not currently and a great explainer thread on the topic can be found here; and
- That major browsers have ubiquitously integrated logic that support ENS name resolution – they haven’t!1 In most cases, users would have to add an extension to their browser to enable a seamless resolution and browsing experience.
Without universal browser or DNS support, we needed to pair the ENS name with a gateway designed specifically to resolve the associated ENS record over HTTPS. Two services enable this exact type of resolution for ENS names: eth.link and eth.limo.
Since the eth.link gateway is operated by Cloudflare, which introduces a centralized point of failure, we favor using eth.limo – please continue reading below to find exciting details about this service and the work we did to extend its functionality.
ℹ️ eth.limo is a free public good ENS gateway that uses on a wildcard DNS record *.eth.limo to provide access to ENS domains over HTTPS.2
Our desire to regularly update the website’s content meant that we wanted to retain mutability with respect to the content hash the ENS record is set to. As covered in the aforementioned post each time new content is uploaded to Arweave it generates a unique transaction ID;3 therefore, to support our CI/CD ambitions, we planned to update the ENS record any time we merged new commits into our production branch ensuring users are viewing the most up-to-date website content.
Since the ENS Public Resolver smart contract is on Ethereum mainnet however, we were unfortunately exposed to both the expense and variability of gas prices any time we wanted to push new content to Arweave – this wasn’t economic and thus failed to meet all acceptance criteria.
Layer 2 ENS
In hopes of finding a more economic solution for regularly mutating our records’ content hash while retaining the recognizability of a .eth domain name, we looked for adjacent solutions being built across EVM Layer 2s.
Despite some grant funding, at the present time there isn’t a native ENS solution available – however, a recent post by the ENS team reveals that the team is working on an EVM Gateway service to bring interoperability between the Ethereum service and L2 resolvers. We’ll be keeping a close eye on progress being made on this front, but given its present lack of maturity, we decided to pursue alternative solutions.
Unstoppable Domains
Unstoppable Domains offers a one-stop shop to buy web3 domains: not just .eth records, but also .crypto and .x suffixes. While the products that can be purchased on their website are fully decentralized, it’s worth noting that the company operates a centralized business model, and faced criticism last year after being granted a patent titled “Resolving Blockchain Domains” – ENS’ lead developers claimed the patent “is based entirely on innovations that ENS developed and contains no novel innovations of its own” (thread linked below).
Developers at ENS – which operates on a decentralized governance model – claimed that the patent would lead to further centralization and was based on earlier work done by the whole community. It seems the two entities have now come to an agreement, but you can follow some of the main arguments here.
While we feel Unstoppable Domains offers a valuable service, not least because it offers .crypto and .x domains in perpetuity for a one-time payment, we decided that we wanted our web app to be as decentralized as possible, so we opted not to use this solution.
Arweave Name System (ArNS)
Since Arweave is currently developing and testing their own name service, we studied whether we could leverage it to potentially satisfy our acceptance criteria. The service is relatively new but it brings much of the same functionality and benefits (human readable and decentralized design) that ENS does and we were able to get up to speed in no time thanks to access to the incredible developer relations team via Discord.
ArNS was built using the SmartWeave smart contract protocol for Arweave and uses a registry contract with ID records that point to tokens called Arweave Name Tokens (ANTs). ANTs are the tokenized and transferrable representation of ownership over a specific human readable subdomain. The ANT contract itself holds a record that can be set to an Arweave transaction ID and the content pointed to by this ID is capable of being resolved by a large set of Arweave gateways simply by pre-appending the registered subdomain, e.g. my_domain.ar-io.dev.
Updating an ANT record is very economical and can be executed programmatically which satisfies our goal for seamless integration with a CI/CD workflow and even more specifically with the Arweave bundler utility we developed (please see details in the following section). We were getting very close to meeting our acceptance criteria, albeit without retaining a .eth name.
Enhanced Name Service Gateway Functionality and Applied Learnings
Motivating innovation with eth.limo and ArNS teams
Already working closely with Arweave’s technology but wishing to keep the recognizability of a .eth name, I posed a question to the ArNS and eth.limo teams:
Instead of the eth.limo gateway resolving to Arweave content hashes held within ENS records directly, would it be possible to include resolution logic that would allow us to set an ENS record that points to an ANT and resolve directly on the ANT’s record?
In other words, the record of an ENS name can hold an Arweave content hash, but mutating it is expensive – we should be able to add some logic into the eth.limo gateway that can identify if the ENS record is an ANT (as opposed to a vanilla content hash), and if so key into and render the content hash pointed to by the ANT’s record.
A simplified diagram of the concept
This hybrid approach would let us use eth.limo for ENS resolution, while enabling access to an ANT record that is still mutable but much more economical to regularly update. It would also provide additional domain name redundancy. To our benefit, I was met with intrigue and using our ANT as a guinea pig, the eth.limo team actively began building.
The eth.limo team is currently in the process of testing the new solution and anticipates incorporating the resolution logic into their upcoming release in Q1 or early Q2 of this year.
arweave-bundler: using the ‘set’ command
As mentioned and linked in the introduction, our Head of Engineering covered Outlier Venture’s open source arweave-bundler extensively in a separate blog post – for the unacquainted, the TLDR of the utility is that it allows developers to easily bundle and upload web app files from a target directory to Arweave and can be used either via command line instructions or in an automated CI/CD workflow by integrating as a GitHub Action.
Incorporating our ArNS learnings from above, we wrote a new ‘set’ command and ‘ant-address’ option in the utility enabling automated ANT record updates so a web app can remain current for end users upon domain name resolution shortly after the newest content is uploaded to Arweave. Using the CLI, there are two ways to programmatically update the record an ANT is pointing at:
Calling the ‘set’ command explicitly
If you’ve already uploaded content to Arweave and have an ANT address for which you’d like to update the content’s transaction or manifest ID being pointed at by the record, you can use the ‘set’ command, include the –ant-address option flag and pass the address of the ANT, and lastly the –manifest-id option flag after which you’ll pass the desired transaction ID.
npx arweave-bundler set --ant-address <your-ant-address> --manifest-id your-manifest-id --private-key ${PRIVATE_KEY}
Calling the ‘setRecord’ implicitly when using the ‘upload’ command
If you wish to update the ANT record that points to your newest web app content pushed to the Permaweb at the same time that you upload this content, you can simply include the –ant-address option flag and pass the address of your ANT. This will automatically take the returned manifest-id generated from the upload function and submit an Arweave SmartWeave transaction via the setRecord function. Note that the private key being used to upload new files must match the private key that owns the ANT.
npx arweave-bundler upload build/ --ant-address <your-ant-address> --private-key ${PRIVATE_KEY}
ℹ️ A manifest ID is an Arweave content hash that points to a manifest file, which is a JSON file containing all transaction IDs of the files in a bundle. It contains an index attribute that points to an alias pointing to the transaction ID of the web app entry point.4
Additional documentation can be found in the GitHub repository.
Next in Our Pursuit of Fully Decentralized Applications
As we continue the thread of research focused on building truly decentralized applications, we next turn our attention to the topic of account abstraction in an effort to maintain web2-like UX. Please keep an eye out for the next post in this series.
Acknowledgements
A special thanks to Ben (X: @cerealsabre) from eth.limo (X: @eth_limo) and Vilanerios (X: @Vilenarios) from AR.IO for their accessibility, knowledge sharing, feedback, and steadfast commitment to building decentralized products.
- Brave has implemented ENS ↩︎
- https://github.com/ethlimo/documentation?tab=readme-ov-file ↩︎
- IPFS uses content-based addressing which means that the content identifiers (CIDs) the protocol generates are based on the content itself; therefore, the same file uploaded twice to IPFS (assuming its versioned with the same hashing algorithm) generates the same CID. Since uploading a file to Arweave requires digital signatures and network consensus, the resulting transaction IDs aren’t solely derived from the associated content and are instead always unique, regardless of the data being uploaded. ↩︎
- https://outlierventures.io/article/never-deploy-another-decentralized-app-to-s3/#h-upload-multiple-files ↩︎