Coder Social home page Coder Social logo

mnid's Introduction

Multi Network Identifier (MNID)

Ethereum, and uPort, is entering a multi-chain world. As end users increasingly interact with multiple chains, on Ethereum or elsewhere, the risk of users/servers inadvertently transferring value from an address on network X to an address on network Y is growing. This could result in monetary loss. Since uPort is switching to a new test network, we need to solve this issue urgently.

The Bitcoin protocol uses Base58Check encoding to prevent users from sending value off-network, but the ethereum ecosystem has used a raw hex version of the address instead.

Extendible Encoding

My proposal is inspired by the Base58Check encoding as well as EIP77 but also specifies a network identifier, which allows us to programmatically extract the network used by an address as well as provide a visual indicator of the network used.

The following items are encoded:

  • 1 byte version number currently 1
  • network id or four bytes of genesis block hash (or both)
  • actual address data
  • Four bytes (32 bits) of SHA3-based error checking code (digest of the version, network and payload)

Then base58 encoding is applied to the end result. The end result is fairly complete but still extendible in the future. We could start by simply using the network id and replace it with the genesis block hash and other meta data in the future.

Benefits

This works with ethereum blockchains, but can easily be extended to other blockchains or even non-blockchain identifiers in the future. It would also be straightforward to add further details specifying which fork etc.

Ease of Implementation

This can be implemented very easily with few dependencies. It would be trivial to use this to add multichain support to uport-lite for example. Thus even allowing (if desired) the interchange of JWT's verified on different networks.

Examples

The following Ethereum hex encoded address 0x00521965e7bd230323c423d96c657db5b79d099f could be encoded as follows

  • main-net: 2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX
  • ropsten: 2oDZvNUgn77w2BKTkd9qKpMeUo8EL94QL5V
  • kovan: 34ukSmiK1oA1C5Du8aWpkjFGALoH7nsHeDX
  • infuranet: 9Xy8yQpdeCNSPGQ9jwTha9MRSb2QJ8HYzf1u

Future additions

It would be trivial to add shard ids, fork descriptors (block number and hash) etc to the address. It would also be trivial to encode other kinds of identities that don't correspond directly to an address on a chain.

Javascript reference implementation

> var mnid = require('mnid')
> mnid.encode({
  network: '0x1', // the hex encoded network id or for private chains the hex encoded first 4 bytes of the genesis hash
  address: '0x00521965e7bd230323c423d96c657db5b79d099f'
})
'2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX'

> mnid.decode('2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX')
{ network: '0x1', 
  address: '0x00521965e7bd230323c423d96c657db5b79d099f' }

// Check if string is a valid MNID

> mnid.isMNID('2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX')
true

> mnid.isMNID('0x00521965e7bd230323c423d96c657db5b79d099f')
false

> mnid.isMNID('1GbVUSW5WJmRCpaCJ4hanUny77oDaWW4to')
false

> mnid.isMNID('QmXuNqXmrkxs4WhTDC2GCnXEep4LUD87bu97LQMn1rkxmQ')
false

Inspirations

Base58Check Encoding

Bitcoin's encoding consists of the following 3 items:

  • Version prefix - Used more as a type and network field. See list.
  • Payload (eg. hash of public key)
  • Four bytes (32 bits) of SHA256-based error checking code (digest of the version and payload)

The whole thing is base58 encoded for compactness and URL safety.

The version prefix allows humans to visually recognize the address type from the first few characters in the string. The error checking code ensures that there aren't any obvious errors in the address.

EIP77

A previous attempt at solving this for ethereum is found in EIP 77 which is similar to Base58Check:

  • 1 flag byte - currently undefined. I suppose this could be used to pick a chain. But 1 byte does not seem enough
  • Payload (eg. hash of public key)
  • Four bytes (32 bits) of SHA3-based error error checking code (digest of the version and payload)

mnid's People

Contributors

dependabot[bot] avatar michaelsena avatar mirceanis avatar pelle avatar rmw2 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mnid's Issues

A few questions/thoughts

Hey, This is a great initiative 👍 to self describing opaque strings :)

@kumavis asked @diasdavid and I on IRC to take a look at this and give some feedback, so i figured i'd start an issue for discussion.

It seems what we're really doing here is coming up with a scheme for encoding PKI identities (an ethereum address being roughly the hash of a public key).

Some initial things i want to consider:

  • What would an address on bitcoin look like? How would that be represented?
  • How difficult would it be to represent an ipfs peer ID with this format?
  • Do you think the checksum could be optional? i.e. allow un-checksummed mnids ?
  • The version byte should probably be a varint, this allows future extensibility
  • The network IDs should be in a table somewhere, that way people using this spec don't overlap on their selections
  • Using a segment of the genesis block hash seems like a nice idea, but i would be worried about the possibility of a collision if this spec becomes more adopted. A global table seems the better approach
  • The hash function used for the checksum at the end should be specified by the version (version 1 == sha3, version2 maybe something different if sha3 breaks?). Hardcoding these things always makes me nervous
  • Consider using multibase instead of strictly base58. Some applications might want a case insensitive encoding (like filenames on non-linux OSes)

[BUG] MNID object is undefined using ES6/Webpack import

When the mnid object imported from the dependency I get undefined.

import mnid, {decode} from 'mnid'
console.log(mnid)
console.log(decode)

*console output*

undefined
ƒ decode(encoded) {
  var data = _buffer.Buffer.from(base58.decode(encoded));
  var netLength = data.length - 24;
  var version = data.slice(0, 1);
  var network = data.slice(1, netLength);
  var addre…

I presume this is just a Webpack/ES6 import bug for bundling (personally I don't feel digging in)? To be safe would it make sense to add export default object exporting the functions?

export default {
 checksum,
 encode,
 decode,
 isMNID
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.