ENS on Swarm decentralized storage

ENS on Swarm

Authors: Viktor Toth, Viktor Tron

Introduction

ENS enables name resolution based on the DNS address structure in a decentralized way. Its main logic and functionalities are defined in smart contracts, thus the system is meant to be deployed on EVM-compatible blockchains, additionally it is extended by centralized use-cases such as EIP-3668. Various workflows exist which define how to interact with these smart contracts functions initiating the requests from dApps.

In this document, we would like to offer an off-chain architecture to the same use-case, on the P2P storage network Swarm. The proposal can be used in three ways:

  1. an alternative feature for off-chain ENS resolvers,
  2. for regular user record updates,
  3. putting the whole application logic off-chain.

Solutions for Current Architecture

This proposal suggests solutions for the biggest pain points of the current architecture:

  • how to significantly decrease the fee for write operations
  • how to improve the availability of the service.

We argue that a solution based on a decentralized off-chain resolver is called for. Below we elaborate this objective and present a full-blown name resolution service handled completely off-chain yet in a cryptographically provable way allowing for trustless provision in a decentralized environment.

Identity Addressing

In this new architecture the data is identity addressed, meaning that only the uploader’s Ethereum address and an arbitrary, consensual topic are required to calculate the address of the data. Technically, it leverages the Single Owner Chunk (SOC) based Feed concept of Swarm Network. SOCs have the following structure:

The Single Owner Chunk can wrap any chunk (span + payload) that can determine any length of data. This data can be labeled by the uploader (usually defined by some consensus laid out by dApps) which is expressed in the Identifier (I). The signature consists of an Ethereum signed message of these two: the hash of the identifier and the content address of the wrapped chunk.

Since the signature is signed by the uploader, the SOC address can be attested by recovering the Ethereum address of the uploader and hash that together with the Identifier. If one gets the same result as the SOC address prequested, then the SOC is valid. All this forms an address space that can be only written by possessing the corresponding private key to that address.

Feeds can be implemented by SOCs using a convention that the Identifier results from two parts: a topic (that has the same purpose as the Identifier) and an index, in order to differentiate different versions of the same topic. This allows mutable addressing where knowing the Source of the Information, the data identifier and the indexing schema any possible data address can be calculated on client-side, before lookup. The most straightforward way is to have sequential indexing that is supported on API and on JS side as well. The index can be anchored to the time that leverages the fact that the present time is known, thereby the maximum value of the index set is also known. Epoch-Based Feeds and the Fault Tolerant Feed Streams are indexing schemas and lookup methods and act as a blueprint to handle Swarm Feeds. The latest can be used to have O(1) lookup time of Feed data.

User Record Handling

In the first step, let’s check how all user records/metadata can be handled and found using the concepts above.

The 1st operation remains the same where the user acquires a node in the ENS Registry. But instead of setting up a new Resolver contract, the records can be uploaded and versioned off-chain (2nd). It is cheaper than managing the metadata on-chain (see #Uses section on Get BZZ Token - Swarm) and faster because it does not need block finalizations.

The last operation shows how this uploaded data can be downloaded by another user: retrieve the owner’s Ethereum address from the ENS registry and use the calculated node as topic of the feed, in which the latest version can be looked up based on the feed type.

Moving ENS Registry Data Off-Chain

It is possible to move the ENS Registry data off-chain as well. In that scenario, the owner of the registry maintains a service feed where the topics equal to the nodes again, but it stores Registry related information (owner/TTL properties) instead of resolver records. This service feed can be extended with other information too for the off-chain resolver use-case that also adds resolver related metadata in the same payload.

DApps are interacting with ENS by hard-coding its contract address in the source code and performing actions by its outlined logic. The trusted point, in this case, is the contract address itself which, for the above architecture, would be the ethereum addresses of the TLD service feeds. These addresses can be registered also under a smart contract that lists all trusted actors. One aspect of the model is not required, namely to register nodes in the TLD service feed because this responsibility can be delegated to the corresponding subdomains (e.g. host.alice.eth can be listed only under the service feed of alice.eth). Nevertheless, TLDs can aggregate nodes from feeds of descendant domains. This also implies that one must not look after any resolver, just obtain ownership of the domain chain that can start from the TLD. Based on this, if one wants to obtain “resolver” a node (its owner address), they can do virtually the opposite of ENSIP-10 Wildcard resolution. First let’s define a function canonicalDomains(domain) that returns domains of the passed parameter starting from its TLD or a domain of which address is known and supports off-chain operations (e.g. canonicalDomains(“host.alice.eth”) → [“eth”, “alice.eth”, “host.alice.eth”] ). Then one applies the following procedure:

  1. Initiate variable ownerAddress to the default TLD owner address.
  2. Iterate on elements in the canonicalDomains array (namehash(element) = node) trying to find feed records for all subsequent domain nodes concurrently. The process results in at least the one child domain having an owner record that can be used to continue the iteration. Otherwise it must throw an error.
  3. If the resolver record was retrieved by a service feed, attest it back on the owner’s feed.

Because every Feed has an out-of-the-box signature on the data that it carries, users can wrap the commitment from the parent domain’s service feed about their ownership above the node that they manage. This information can be optionally placed in the same payload (since the smallest data unit is 4kb on Swarm) or by introducing a new topic construction that holds this data such as topic = keccak256(node + ‘witness’). Nevertheless, for full attestation one must check the latest versions of the corresponding ESFs up to the TLD if one wants to be sure the domain is owned by the user at the moment.

Extras

To list all handled subdomains of a domain, one can use data-structures meant to represent indexes, such as Mantaray or POT. Both have native implementations on Swarm, offer logarithmic retrieval in the size of the index, allow prefix searches, iterations, preserve history.

POT is optimized for cheap insertions and updates and amortized retrieval and update performance over recently updated records (which virtually auto scales for frequently updated content).

As a bonus, communication with the services live on Swarm can be done in a decentralized way (e.g. initial request for name registration) without the need for additional components using Graffiti Feeds or PSS messaging. This would allow serverless registries…

Swarm ensures permissionless publishing and access to the data and automatic scaling of popular content.

Implementation

The development of this architecture can happen by JS developers that are familiar with the concepts of ENS and can interact with Swarm (feeds/SOC).

My personal experience is that it is the fastest to start with the libraries first. There are two main components: (1) user/revolver handler and (2) registry handler. For initiative, the interfaces of these should be designed by the applicants and after choosing the best alternative, the logic, documentation and testing could be done. The components can be placed in a single library (e.g. ens-swarm-js) where the functionalities are implemented in different phases as it is numbered.

In order to try out the concept, a website like ENS App that utilizes the library mentioned is also necessary. In the alpha phase, this could be implemented only in one domain (e.g. swarmens.eth) and after that it could be extended to other domains as well.

13 Likes

really cool concept

2 Likes

Can all the security invariants be verified in a smart contract? If so, this would fit well within the EIP-3668 architecture, and so could be implemented transparently to clients.

How are replay attacks prevented? Can a gateway/node return a stale chunk for a given identifier?

3 Likes

The identity-based addressing uses digital signatures that can be attested on-chain. Thereby, if one signs two different chunk payloads under one SOC address, that can be handled on-chain.

Outside of the double signing, each version/record has unique SOC address because versions are different in their identifiers. (Identifier is made of a consensual topic as written above and a sequential index). Based on this, gateways/nodes won’t return different payloads for a specific SOC address. On the other hand, if the latest chunk must be discovered (by sequential feed lookup) then all historical versions must be kept alive on the network or time-to-time truncate that by letting their attached postage stamps expire at once. Both are the responsibility area of the ENS data uploader. If the owner had uploaded the versions with different postage batches and a postage stamp expired on an earlier version, then the sequential feed lookup returns the version before the expired update (which is not the case at Fault Tolerant Feed Streams).

4 Likes

Bounty and implementation proposal

As discussed in the community call, I’m drafting below a proposal for implementation.

Hours of work estimated: 350

Skills necessary: JS development, ENS, familiarity with Swarm feeds/SOC.

To develop the proposal, one way to proceed would be a joint bounty between the Swarm Foundation and ENS DAO:

  • Matching contributions in the range of 10-20k DAI from both the ENS DAO and the Swarm Foundation, for a total of 20-40k DAI for the bounty
  • Panel of judges from both the ENS DAO and the Swarm community
  • Community efforts to involve both ENS DAO community and Swarm community and foster collaboration between the two communities
  • Joint marketing activities
  • Coordination of the bounty, resources and activity done by the Swarm Foundation (Costanza Gallo, the poster of the proposal can take lead)
  • Bounty proposal - being prepared and uploaded shortly

Hi @nick.eth, just following up to see if you have other questions after @nugaon 's reply :slight_smile: happy to discuss or to jump on a community call to elaborate :slight_smile:

Bounty proposal can be found here

Am I correct to understand that this approach requires all ENS name users to acquire your $BZZ token to be able to update record?

Hi. We had calls a couple of times on this point. Is your proposal compatible with EIP-3668 or are you suggesting something else?
If I understand correctly, your proposal requires each client (ethers.js, web3.j, etc) requires to speak to swarm endpoint directly instead of fetching the data via gateway service which EIP-3668 defines. Is it still the case? If correct, I don’t think the approach is feasible.

This approach of recovering ethereum address via signing address of swarm seems resembles to the approach of the namesys . Could you compare the approach and describe what parts are similar and what parts are different (also it would be great if @NameSys team can examine and compare the approach)

Lastly, do you have any proof of concept solidity code that shows how to verify swarm data (or signing key) on Ethereum L1 without relying on client js library nor gateway middleware? To make your solution entirely trustless, you have to be able to verify your record (or the signing key) entirely verifiable on L1.

1 Like

Hi Victor & Victor,

NameSys has built pretty much exactly the same thing with IPFS & IPNS (see 1 and 2).

We use IPFS content wrapped inside IPNS for infinite upgradeability. Since IPFS is inherently a nearly cost-free solution, we favour it over Arweave or Swarm. We use a similar Signing and Verification algorithm as Makoto pointed out. This prohibits any unauthorised updates to the records (even if the IPNS key is compromised) leaving (D)DOS as the only vulnerability.

Internal content addressing differences between Swarm and IPFS will have their impact during the lookup stage but I don’t know enough to comment on this. On the plus side, it seems like fetching and validating the latest version in Swarm is somewhat easier than in IPNS by construction. With IPNS, we have to rely on an external indexer to track the latest version which is not ideal.

Couple of pain points in Swarm’s implementation are perhaps:

  • Incompatibility with CCIP-Read which requires HTTP interfacing. Is Swarm content fully queryable over HTTP, say for example through BEE API? CCIP-Read in its current form cannot handle JSON-RPC, native ipfs://, ipns://, bzz://, onion:// etc content addressing, due to which we must handle all interfacing across a middleware. Swarm will need its own middleware (probably bootstrapped to BEE API) answering CCIP-Read queries over HTTP. This could be dynamic or static.

  • Native payments in $BZZ? It’s not hard to inject multiple wallets in clients as long as there is some sort of interoperability

Cheers
NameSys

yes as well as xDAI in order to send the transaction for buying the Postage Batch on the Gnosis chain.

This logic can be delegated to a gateway service as well as the before mentioned Postage Batch handling. The SOC can also be attested, thereby, this can be integrated with EIP-3668. Nevertheless, the proposal details how it is possible to query/manage ENS data off-chain without relying a gateway service since it provides better data availability.
So to answer shortly, this mainly suggests something else but the same logic should be used in EIP-3668 Swarm-backed gateways.

Content Addressed Chunk (CAC) can be verified like this and Single Owner Chunks (SOC) can be verified like this. You can find the test here and here correspondingly.

Outside that @NameSys mentioned about the differences, it has “upload and disappear” functionality meaning that you do not need to host your own content since you pay the storage network out to store your data for a specific amount of time.

NameSys’ first concern is also right, for CCIP-Read there should be a middleware implemented over Bee API.

3 Likes

@matoken.eth @nick.eth

Reply:

Following this discussion, @nugaon and I run a simulation:

Swarm] 32 bytes write (up to 4KB) | 1 GB = 2^18 chunks ~ 0.000001244 (BZZ/chunk) / month.

On the current market 0.000211 ETH = BZZ thereby performing a 32 bytes update on EThereum equals to 0.5 BZZ: for this price 400 000 chunks ~ 1.5 GB write can happen on Swarm with one month lifespan.

On the contrary, a single 32 bytes write on Swarm with a 33 000 years lifespan would be the same price on Ethereum as well.`

Hence: one write for one month is 0.000001244 BZZ

Analysing the past it’s clear how unexpensive implementing the proposal would be:

Assumption tx Month Unit in BZZ
More than 7,299,472 transactions found 1 1 0.000001244
7299472 1 9.080543168
7299472 12 108.966518

Data of 24th October at 12.31 CET

Assumption tx Month Unit in BZZ
transactions found: 369,543 1 1 0.000001244
369,543 1 0.459711492
369,543 12 5.516537904

Data of 24th October at 12.32 CET

For this reason, the Swarm Foundation will guarantee funds for 2 years, with a limit of 100k BZZ. Those are part of a large donation from the Ethereum Foundation which the goal of supporting the Ethereum Ecosystem.

Viktor Tron, author of the proposal, suggested the following way to proceed:

The Swarm foundation will deploy a smart contract with a twofold goal:

First, it will check if the batch ID making the request owns the ENS record for a specific name or if they own the feed associated with that ENS record.

Then, if the conditions are met, the smart contract will use funds allocated to add more resources to a batch, ensuring it has enough resources to cover 2 years based on the current price.

This mechanism aims to provide automatic support while also preventing misuse, especially when limited to ENS entries.

Moreover, at the end of the 2 years, the remaining funds of the stipulated 100k BZZ will be given to the ENS community via an airdrop.

1 Like

Hi @matoken.eth I’m in Istanbul until Sunday if you want to discuss it IRL :slight_smile: