Can't decode Contenthash
Closed this issue · 7 comments
Go version 1.16.5 linux/amd64
Version v3.4.6
I ran into an issue earlier where an ipns-ns encoded content hash isn't properly displayed:
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/ethclient"
ens "github.com/wealdtech/go-ens"
)
func main() {
client, err := ethclient.Dial("http://127.0.0.1:8545")
if err != nil {
panic(err)
}
// Resolve a name to an address
domain := "esteroids.eth"
address, err := ens.Resolve(client, domain)
if err != nil {
panic(err)
}
fmt.Printf("Address of %s is %s\n", domain, address.Hex())
resolver, err := ens.NewResolver(client, domain)
if err != nil {
panic(err)
}
// Get content hash
content, err := resolver.Contenthash()
if err != nil {
panic(err)
}
readable, err := ens.ContenthashToString(content)
if err != nil {
panic(err)
}
fmt.Printf(readable)
}
Which results in the following:
Address of esteroids.eth is 0x7448467f85FfA36Ca763C9E301e270F8ece0C2B8
/ipns �
�b�%!�(MISSING)�G̍KC�T��R�M����}
ݸ
I've noticed similar behavior with the ENS plugin for coredns (possibly unrelated):
ipfs resolve -r /ipns/esteroids.eth/
Error: could not resolve name: "\\008\\001\\018 \\149\\011\\143b\\185%\\236\\197\\002G\\204\\141\\225\\008KC\\248T\\251\\196R\\137M\\154\\026\\151\\215\\242}\\010\\221\\184" is missing a DNSLink record (https://docs.ipfs.io/concepts/dnslink/)
Am I using this package incorrectly? Thanks for the great project, I've enjoyed working with your tools.
Chances are it is a different encoding to that which the library supports so far. Any idea which encoding was used for the contenthash?
I think it's ipns-ns
. When I use web3.js
The contenthash is successfully decoded:
const { resolve } = require('path');
const contentHash = require('content-hash')
var Web3 = require('web3');
var add = 'ws://127.0.0.1:8546'
var web3 = new Web3(new Web3.providers.WebsocketProvider(add));
web3.eth.ens.getAddress('esteroids.eth').then(function (address) {
console.log(address)
});
web3.eth.ens.getContenthash('esteroids.eth').then(function (result) {
content_hash = result['decoded']
content = decodeContenthash(content_hash);
console.log(content)
});
function decodeContenthash(contenthash) {
const codec = contentHash.getCodec(contenthash)
if (codec === 'ipns-ns') {
try {
const content = contentHash.decode(contenthash)
return(`/ipns/${content}`);
}
catch (err) {
console.error(err);
}
}
}
Result:
/ipns/12D3KooWKrB93pwXDdeyz2WRMwcSBny5ECjA1JasB4GTo4ijUUtf
0x7448467f85FfA36Ca763C9E301e270F8ece0C2B8
It might be CID v1?
There have been a few changes made to content hashes (multiformats is somewhat of a moving target).
I have created a branch contenthash-update
that should handle the newer style. It has to be a little opinionated in how it generates the text strings due to lack of encoding information in the contenthash, so defaults to the more modern output and base36. Please could you try it and see it now behaves?
(Note you will need to change your import to be go-ens/v3,)
@mcdee thank you for the fix, I can confirm that this works:
Address of esteroids.eth is 0x7448467f85FfA36Ca763C9E301e270F8ece0C2B8
ipns://k51qzi5uqu5djwbl0zcd4g9onue26a8nq97c0m9wp6kir1gibuyjxpkqpoxwag
On an unrelated note, do you know why there seem to be 2 different CIDs for that ipns namespace? Completely different results between the 2 decode methods; they both point to the same location.
The first character defines the encoding used. In this case 'k' means 'base 36'. There are other encodings available, such as base 58, however base 36 is the currently default so the library will use that.
I will merge the fix and tag a new release. Thank you for testing.
Release tagged as v3.5.0