You are welcome to present at ecosystem. I’ll be putting out the agenda tomorrow and make sure to include namesys.
Hi. thank you for your detailed update. Decentralised file system based offchain resolver has been presented a couple of times but all of them lacked a way to prove that the given record is the latest. Does this method resolve the timestamp issue?
Also does this approach works for issuing subnames on l2?
Very cool effort indeed!
Makoto highlights one concern that users should be made aware of: although you can prove the domain owner approved the records, you can’t prove they’re the latest version, so replay attacks are possible.
I note that you’re using a separate dedicated gateway; you may be intrigued to note that it’s actually possible for an IPFS gateway to serve as a CCIP-Read gateway. If you use substitution parameters to put the recipient and data into the URL, you can store pregenerated CCIP-read responses in an IPFS hierarchy and they can be served up directly. Combined with a custom resolver this can eliminate the need to run any dedicated gateway at all.
@broke.eth we finally released a * beta * basic working version of non-custodial off-chain+gasless records manager/ pls take a look around for feedback…
Hello, @NameSys Will you please explain why users need to share their private key?
I know you’re referring to the IPFS node private key, but non-tech users might not grasp its meaning, and some of them are even jokingly asking if you intend to ‘rug’ my wallet . Can you please rephrase the explanation for better clarity?
This is correct. IPFS/IPNS stack by itself provides no way to definitively determine the latest version. But there are solutions to this beyond IPFS and they all (ideally) require some sort of (decentralised) indexer/archiver which can store the pointer to the latest version. We jammed on some ideas and there are two main ones:
Use Nostr Relays as the decentralised indexer. One can imagine Nostr bots republishing IPNS updates on the Nostr network and the CCIP2 contract can be interfaced with Nostr network to pick the latest version number of the IPNS node. This method is sort of alien to the Ethereum ecosystem with a lot of caveats but it is free.
Use L2 events as the decentralised indexer. One can imagine a simple contract on a cheap L2 logging events containing the latest version number upon each IPNS update. CCIP2 contract can then be interfaced directly with the L2’s RPC provider to pick the latest IPNS version. This is our preferred solution and it is part of our v2 roadmap. This is a more native method, very cheap even if not free (fraction of a cent) but requires users to maintain an L2 wallet with small funds. With AA, this will become rather straightforward though and not as much a hassle.
Replay attacks are never possible since records require signature check for each version. The worst-case scenario here is a “stale resolution” where an older version is resolved by the IPNS lookup. In >99% of cases, it takes less than 1 hour for the IPFS network to resolve the latest version.
This was our initial prototype but we ran into problems such as extremely slow speed and high error rate of public gateways. This forced us into creating our own web3 gateway with great help from @ethlimo.eth and we are able to resolve the records with 1s latency using ETH.LIMO infra.
This is a potential ‘man in the middle’ vulnerability. Our dedicated gateway is in fact a contract that uses ETH.LIMO as the primary gateway provider but additionally has the usual public gateways coded as fallbacks. So we do exactly what you describe under the hood, plus some extra decentralisation and transparency.
Yes, I must explicitly mention that I am talking about the IPNS private key and not your Ethereum wallet key. Having said that, we are happy to help 1W3.io implement keyless IPNS if they want. The underlying implementation code is here: IPNS Keygen and the deep docs for it are here: README. This method is a bit of an overkill for IPNS though and it is possible to shorten it. You can ping us in our discussions and we’ll be happy to help you.
You may be able to fetch the latest information through events but would it be possible to verify that that’s the latest version on L1 verifier contract?
Also, how do you guarantee that the event information is written in the sequence without trusting the entity that send a transaction to L2 to emit the event?
There is no need to verify on L1. It is up to the user to make sure that they complete the event logging transaction on L2 or they will risk resolving a stale version. One can additionally code a condition in the CCIP2
callback() to compare the version number resolved by IPFS and the last version number logged on L2. If the IPFS version is later, we will warn the users that they are missing event logs and resolve the IPFS version instead of the L2 version.
This entity is the user and we expect them to send the transaction to L2 via our client. It will be an optional part of the record update codeflow. If user chooses against this, then they are risking stale resolution. This may matter to some users and/or some records but not so much for others.
As requested in the earlier comment, please include the IPNS key part in your original article. We don’t want the community to get the wrong information.
Could you please explain why a user would share his IPFS node private keys? Here 1W3 or dWebservices are the ones generating the IPNS keys, not the other way around.
Thanks for offering help
The post seems locked for edits. There is no
Edit button on the main post for me (screenshot below). Maybe a mod can help us?
That is bad since the third party is updating the content on user’s behalf. If 1W3.io server gets compromised/hacked, hacker can post malicious content to user’s .eth profile. If user has payment/sensitive links on their profile, visitors can get phished. A third party holding user’s private key is as bad as it gets.
Yes, If 1W3.io server gets hacked! This is the same with all the IPNS service providers like pinata, fleek, web3.storage, etc., because of its centralized nature. That is the reason we have been given the option to choose between IPFS and IPNS for content hash.
Will you please explain who’s IPFS nodes the IPNS records are getting created for users by namesys.xyz? are you using any third-party services?
I’m trying to use namesys.xyz this one is always 504
Not all IPNS service providers are an attack vector, only those who store the private keys at the node.
w3name is an example of such an API. It doesn’t store or require your key to host your content. We are using their stack. It is open-source and very lightweight!
We use our own IPFS node for pinning IPFS content initially. This is not a limitation though since both IPNS private key and IPFS hash can be exported in our client and re-pinned by the user (and they should be!) at their own choice of service provider. For example, if a user wants to be extra sure that their records resolve if
w3name API dies, they can export their IPNS key and host it additionally on their server. Users can of course pin their IPFS hash at multiple services like Pinata, Fleek, web3storage etc if they want to host their records at other nodes besides NameSys. More the merrier!
We strongly believe in the ‘not your keys, not your content’ philosophy. NameSys stack is uncompromisable at its core. If
w3name API dies and NameSys node crashes, NameSys stack will keep on working. It only needs new coordinates of the new storages and it will keep running (users will have to reset their records though of course).
This is correct and expected. You have set the
recordhash in the client so it is trying to read what records you have set (
address in this case) in the IPNS key. When you make an update, it will be stop throwing the log. Thanks for notifying nonetheless, I’ll pass this info to the devs so that this try-catch is caught instead of logged.
We also strongly believe in the ‘not your keys, not your content’ philosophy. We made numerous attempts to implement a user-owned IPNS KEY; however, at the time we were building our solution, w3name was not stable. We hope it is now functioning properly.
I would like to understand more about how the user can own the IPNS private key. I hope you will demonstrate this in the ECOSYSTEM call this Thursday. See you at the call.
sorry for this mix up…
Our ed25519 keygen PR was merged in GitHub - paulmillr/ed25519-keygen: Generate ed25519 keys for SSH, PGP (GPG), TOR, IPNS and SLIP-0010 hdkey recently, it’s 100% compatible with w3name keys format… still requires other half using secp256k1 deterministic signature and ?HKDF, all inspired by Umbra cash keygen.
It’s possible to inject IPNS/DHT for hourly/daily republishing services, it’s more confusing with old libp2p key specs used as node key which is also IPNS key. IPNS directly supports (at least on docs) to use secp256k1 but it’s not widely supported yet, that’d allow reusing same ETH keys directly for IPNS.
We’re recently talking with @ethlimo.eth devs for possible full ENS+IPFS cluster to store “pin” and manage IPFS data with some basic size limits per domain… That’ll require its own forum topics and funding process from ENS DAO. We’re all in this together, always happy to help around.
That’s what a replay attack is.
Wouldn’t it be simpler to just operate your own IPFS gateway instead, then? You could apply access controls to only allow access to relevant content via it.
I don’t follow; can you describe the vulnerability in more detail?
In that case, we are on the same page I understood ‘replay attack’ to mean something else
That is correct. But the devs made this project with $239 in expenses. $173 in contract deployment and $66 for 3 months of cloud service for a basic IPFS node. We have so far received $110 from the Gitcoin round. A dedicated gateway needs more . Lack of funds forced us into bootstrapping on ETH.LIMO infra. Plus, ETH.LIMO is a highly trusted service/gateway and we are not.
Having thought more on this, you are right. It is not necessarily MITM-vulnerable as long as the users make informed choice for a gateway. Devs were initially worried about compromised/slow choice of gateways. When the user sets the records on our client, we can offer them the option to specify the gateway and encode it in the payload. So this can indeed be a choice for users in v2 and some users may well want to use a personal access-controlled fast gateway. We have made a note of this for v2
P.S. I forgot to add that devs are looking into abandoning IPNS in favour of L2 altogether. If one can read IPNS version numbers from L2, then why not read an IPFS hash directly? Then resolution will be instant and just like L1, avoiding the IPNS mess. The issue standing in the way of this is the rigid CCIP-Read interface that cannot read directly from RESTful Ethereum endpoints (as far as we know; please correct us otherwise). We don’t want to inject another web2 point-of-failure by using a middleware proxy server for interfacing. A better option would be a Chainlink Oracle that can translate the HTTP GET from common Ethereum providers (Infura, Alchemy etc) to CCIP-Read-compatible format. This would be a better and more general solution!
Update on NameSys
We are glad to announce that NameSys is now LIVE on MAINNET!
We have made several improvements to the Beta version and included some features that came up in the comments. We have also brought forward couple of features such as
- Global Storage for all names in a wallet, and
- Possibility to specify an HTTP Gateway instead of using the IPFS network as default.
We have also drafted a Comprehensive Guide with step-by-step instructions to using the NameSys Client. If you have any questions, feel free to ask! If you find any bugs, place report them on our Github page linked at the bottom of our Clients.
We are already aware of two issues in our Client:
- Emoji domains not yet supported (other non-ASCII domains are fine)
- NFT Avatars in format
eip155:1/erc721:0xnot yet supported
We will be fixing these shortly and updating the Client!