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

Formalize IPFS hash into ENS(Ethereum Name Service) resolver #1062

Merged
merged 9 commits into from
May 7, 2018

Conversation

PhyrexTsai
Copy link
Contributor

Initial pull request for the "Formalize IPFS hash into ENS(Ethereum Name Service) resolver" EIP.

The goal is to specify the mapping protocol between resources stored on IPFS and ENS(Ethereum Naming Service).

EIPS/eip-1062.md Outdated
eip: 1062
title: Formalize IPFS hash into ENS(Ethereum Name Service) resolver
author: Phyrex Tsai <phyrex@portal.network>, Portal Network Team
discussions-to: phyrex@portal.network
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please supply a URL where people can discuss, such as a post on the ethereum-magicians forum.

EIPS/eip-1062.md Outdated

export const toHex = function(ipfsHash) {
let buf = multihash.fromB58String(ipfsHash)
let digest = multihash.decode(buf).digest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this hardcodes the use of SHA2-256. Could we just store the binary multihash in a bytes field instead, which would provide forward compatibility?

This would be useful for swarm, too, who want to be able to store hash+key pairs in ENS.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About Base58 hash convert to hex, here's a simple version just using bytes:

To implement the method transfer from IPFS(Base58) to hex encryption format :

import bs58 from 'bs58'

export const toHex = function(ipfsHash) {
  const bytes = bs58.decode(ipfsHash)
  return '0x' + bytes.toString('hex')
}

To implement the method transfer from hex encryption format to IPFS(Base58)

import bs58 from 'bs58'

export const toBase58 = function(contentHash) {
  const hex = contentHash.substring(2)
  const bytes = Buffer.from(hex, 'hex')
  return bs58.encode(bytes)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like it would work, yes. It looks like multihashes has toHexString and fromHexString too, though, which would probably be a better fit.

@Arachnid
Copy link
Contributor

Arachnid commented May 5, 2018

Pinging @homotopycolimit because this is of interest for Swarm, too.

@cobordism
Copy link

also ping: swarm. mutlihash support: @zelig @nolash @gbalint

EIPS/eip-1062.md Outdated
We think that this implementation is not only aim to let more developers and communities to provide more use cases, but also leverage the human-readable features to gain more user adoption accessing decentralized resources. We considered the IPFS ENS resolver mapping standard a cornerstone for building future Web3.0 service.

## Motivation
To build fully decentralized web service, it’s necessary to have a decentralized file sotrage system. Here comes the IPFS, for three following advantages :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: sotrage -> storage

EIPS/eip-1062.md Outdated

## Motivation
To build fully decentralized web service, it’s necessary to have a decentralized file sotrage system. Here comes the IPFS, for three following advantages :
- Address large amounts of data, and has unique cryptographic hash for every records.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: records -> record

EIPS/eip-1062.md Outdated
## Motivation
To build fully decentralized web service, it’s necessary to have a decentralized file sotrage system. Here comes the IPFS, for three following advantages :
- Address large amounts of data, and has unique cryptographic hash for every records.
- Since IPFS is also based on peer to peer network, it can be really helpful to delivers large amounts of data to users, with safer way and lower the millions of cost for the bandwidth.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: delivers -> deliver

EIPS/eip-1062.md Outdated
- Different data type, one is string, the other is integer.
- The way to process the condition requires not only we need to transfer from IPFS to Ethereum, but also need to convert it back.

To solve these requirements, we can use binary buffer briding that gap.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: briding -> bridging

@PhyrexTsai
Copy link
Contributor Author

@ElOpio Thank you for helping fix the typos

EIPS/eip-1062.md Outdated


## Specification
The condition now is that the IPFS file fingerprint using base58 and in the meantime, the Ethereum using hex encryption. These comes the two restrictions :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's "hex encoding", not "hex encryption", and it's not actually the case - Ethereum stores binary data, it just uses hex in API to encode the binary data. Internally it's stored in binary form.

EIPS/eip-1062.md Outdated

## Specification
The condition now is that the IPFS file fingerprint using base58 and in the meantime, the Ethereum using hex encryption. These comes the two restrictions :
- Different data type, one is string, the other is integer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hex strings are encoded binary data, not integers, typically (though they can be either).

EIPS/eip-1062.md Outdated

export const toHex = function(ipfsHash) {
let buf = multihash.fromB58String(ipfsHash)
let digest = multihash.decode(buf).digest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks like it would work, yes. It looks like multihashes has toHexString and fromHexString too, though, which would probably be a better fit.

EIPS/eip-1062.md Outdated
To implement the specification, need two methods from ENS public resolver contract, when we want to store IPFS file fingerprint to contract, convert the Base58 string identifier to the hex format and invoke the `setContent` method below :

```
function setContent(bytes32 node, bytes32 hash) public only_owner(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're happy to change to storing full multihash values in bytes, I'd suggest renaming these to setMultihash and multihash.

Also, to be consistent with existing resolver profiles, setMultihash should be specified as optional; only the getter is strictly part of the public interface.

Copy link
Contributor Author

@PhyrexTsai PhyrexTsai May 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd happy renaming to setMultihash and multihash and use bytes to store

@Arachnid Arachnid merged commit c2bfd23 into ethereum:master May 7, 2018
@cobordism
Copy link

Would we ever expect a name to store both a Swarm hash and an IPFS hash? Or are we expecting a name to store either one or the other and using the multihash format to determine what the content hash refers to?

Or shall we introduce the convention to use bzz.name.eth and ipfs.name.eth ? ;)

@Arachnid
Copy link
Contributor

Arachnid commented May 8, 2018

@homotopycolimit Good question! I'm fine with using different names, personally, but I think it's an issue worth considering. If this is desirable, we could specify that it returns a content-type, or other distinguishing field, maybe?

What do others think?

@Georgi87
Copy link

I would favor to encode this information in a multihash. From a UX perspective users will prefer to type name.eth instead of specifying the protocol using a subdomain.

@PhyrexTsai
Copy link
Contributor Author

If we do need both store IPFS hash and Swarm hash using same name.eth within the same resolver, we may have two functions for each, otherwise the setMultihash function only can store one hash in it.

For this issue, we can consider to implement a map for multihash, and specify IPFS hash or Swarm hash.

struct Record {
    address addr;
    bytes32 content;
    string name;
    PublicKey pubkey;
    mapping(string=>string) text;
    mapping(uint256=>bytes) abis;
    mapping(string=>bytes) multihash; // bytes multihash; to mapping(string=>bytes) multihash;
}

// Set (name.eth, swarm, 0xccef599d1...) and (name.eth, ipfs, 0x49ae177d1db...)
function setMultihash(bytes32 node, string key, bytes hash) public only_owner(node) {
    records[node].multihash[key] = value;
    MultihashChanged(node, key, hash);
}

// Get by (name.eth, swarm) or (name.eth, ipfs)
function multihash(bytes32 node, string key) public view returns (string) {
    return records[node].multihash[key];
}

@nolash
Copy link

nolash commented May 18, 2018

Isn't storing dynamic bytes very expensive? Maybe it should be 3xbytes32 instead?

Also, I'm wondering what exactly does a "IPFS multhash" and "Swarm multihash" mean. Does it mean that there is an actual reserved identifier in the official-ish multihash table that unambiguously specifies this? (currently all of them seem to be actual hash algorithm names).

@Arachnid
Copy link
Contributor

Isn't storing dynamic bytes very expensive? Maybe it should be 3xbytes32 instead?

Storing bytes costs one slot, plus the number of slots required for the data, rounded up.

Also, I'm wondering what exactly does a "IPFS multhash" and "Swarm multihash" mean. Does it mean that there is an actual reserved identifier in the official-ish multihash table that unambiguously specifies this? (currently all of them seem to be actual hash algorithm names).

People are talking about the resource the multihash is specifying - is it on Swarm, or IPFS?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants