Skip to content
This repository has been archived by the owner on Sep 3, 2021. It is now read-only.

refactor: default to base32 encoding for v1 CIDs #89

Merged
merged 3 commits into from
May 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ You can create an instance from a CID string or CID Buffer
```js
const CID = require('cids')

const cid = new CID('zdj7WkRPAX9o9nb9zPbXzwG7JEs78uyhwbUs8JSUayB98DWWY')
const cid = new CID('bafybeig6xv5nwphfmvcnektpnojts33jqcuam7bmye2pb54adnrtccjlsu')

cid.version // 1
cid.codec // 'dag-pb'
cid.multibaseName // 'base58btc'
cid.multibaseName // 'base32'
cid.toString()
// 'zdj7WkRPAX9o9nb9zPbXzwG7JEs78uyhwbUs8JSUayB98DWWY'
// 'bafybeig6xv5nwphfmvcnektpnojts33jqcuam7bmye2pb54adnrtccjlsu'
```

or by specifying the [cid version](https://github.com/multiformats/cid#versions), [multicodec name](https://github.com/multiformats/multicodec/blob/master/table.csv) and [multihash](https://github.com/multiformats/multihash):
Expand All @@ -74,28 +74,28 @@ or by specifying the [cid version](https://github.com/multiformats/cid#versions)
const CID = require('cids')
const multihashing = require('multihashing-async')

multihashing(Buffer.from('OMG!'), 'sha2-256', (err, hash) => {
const cid = new CID(1, 'dag-pb', hash)
console.log(cid.toString())
// zdj7WkRPAX9o9nb9zPbXzwG7JEs78uyhwbUs8JSUayB98DWWY
})
const hash = await multihashing(Buffer.from('OMG!'), 'sha2-256')
const cid = new CID(1, 'dag-pb', hash)
console.log(cid.toString())
// bafybeig6xv5nwphfmvcnektpnojts33jqcuam7bmye2pb54adnrtccjlsu
```

The string form of CIDs currently defaults to `base58btc` flavour. (This is [soon to change to `base32`](https://github.com/ipfs/ipfs/issues/337). When creating a new instance you can optionally specify the default multibase to use when calling `toBaseEncodedString()` or `toString()`
The string form of v1 CIDs defaults to `base32` encoding (v0 CIDs are always `base58btc` encoded). When creating a new instance you can optionally specify the default multibase to use when calling `toBaseEncodedString()` or `toString()`


```js
const cid = new CID(1, 'raw', hash, 'base32')
const cid = new CID(1, 'raw', hash, 'base64')
console.log(cid.toString())
// bafybeig6xv5nwphfmvcnektpnojts33jqcuam7bmye2pb54adnrtccjlsu
// mAXASIN69ets85WVE0ipva5M5b2mAqAZ8LME08PeAG2MxCSuV
```

If you construct an instance from a valid CID string, the base you provided will be preserved as the default.

```js
const cid = new CID('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy')
// e.g. a base64url encoded CID
const cid = new CID('uAXASIHJSUj5lkfuP5VPWf_VahvhARLRqPkF24QxY-lKaSqvV')
cid.toString()
// bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy
// uAXASIHJSUj5lkfuP5VPWf_VahvhARLRqPkF24QxY-lKaSqvV
```


Expand All @@ -121,7 +121,7 @@ instance. Returns true if valid, false if not valid.

`multihash` must be a `Buffer` instance of a valid [multihash](https://github.com/multiformats/multihash).

`multibaseName` optional string. Must be a valid [multibase](https://github.com/multiformats/multibase/blob/master/multibase.csv) name. Default is `base58btc`.
`multibaseName` optional string. Must be a valid [multibase](https://github.com/multiformats/multibase/blob/master/multibase.csv) name. Default is `base58btc` for v0 CIDs or `base32` for v1 CIDs.

### new CID(baseEncodedString)

Expand Down Expand Up @@ -169,7 +169,12 @@ Returns the CID encoded in version 1.

#### cid.toBaseEncodedString(base=this.multibaseName)

Returns a base encodec string of the CID. Defaults to the base encoding in `this.multibaseName`
Returns a base encoded string of the CID. Defaults to the base encoding in `this.multibaseName`.

The value of `this.multibaseName` depends on how the instance was constructed:

1. If the CID was constructed from an object that already had a multibase (a string or an existing CID) then it retains that base.
2. If the CID was constructed from an object that _did not_ have a multibase (a buffer, or by passing only version + codec + multihash to the constructor), then `multibaseName` will be `base58btc` for a v0 CID or `base32` for a v1 CID.

#### cid.toString(base=this.multibaseName)

Expand Down
10 changes: 5 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class CID {
* -> construct CID by parts
* ```
*
* @param {string|Buffer} version
* @param {string|Buffer|CID} version
* @param {string} [codec]
* @param {Buffer} [multihash]
* @param {string} [multibaseName]
Expand All @@ -59,7 +59,7 @@ class CID {
* new CID(<bs58 encoded multihash>)
* new CID(<cid>)
*/
constructor (version, codec, multihash, multibaseName = 'base58btc') {
constructor (version, codec, multihash, multibaseName) {
if (module.exports.isCID(version)) {
// version is an exising CID instance
const cid = version
Expand Down Expand Up @@ -95,13 +95,13 @@ class CID {
if (Buffer.isBuffer(version)) {
const firstByte = version.slice(0, 1)
const v = parseInt(firstByte.toString('hex'), 16)
if (v === 0 || v === 1) {
if (v === 1) {
// version is a CID buffer
const cid = version
this.version = v
this.codec = multicodec.getCodec(cid.slice(1))
this.multihash = multicodec.rmPrefix(cid.slice(1))
this.multibaseName = (v === 0) ? 'base58btc' : multibaseName
this.multibaseName = 'base32'
} else {
// version is a raw multihash buffer, so v0
this.version = 0
Expand Down Expand Up @@ -133,7 +133,7 @@ class CID {
/**
* @type {string}
*/
this.multibaseName = multibaseName
this.multibaseName = multibaseName || (version === 0 ? 'base58btc' : 'base32')
olizilla marked this conversation as resolved.
Show resolved Hide resolved

CID.validateCID(this)
}
Expand Down
15 changes: 12 additions & 3 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('CID', () => {
expect(cid).to.have.property('codec', 'dag-pb')
expect(cid).to.have.property('version', 0)
expect(cid).to.have.property('multihash').that.eql(multihash.fromB58String(mhStr))
expect(cid).to.have.property('multibaseName', 'base58btc')

expect(cid.toBaseEncodedString()).to.be.eql(mhStr)
})
Expand All @@ -46,6 +47,7 @@ describe('CID', () => {
expect(cid).to.have.property('codec', 'dag-pb')
expect(cid).to.have.property('version', 0)
expect(cid).to.have.property('multihash').that.eql(mh)
expect(cid).to.have.property('multibaseName', 'base58btc')

expect(cid.toBaseEncodedString()).to.eql(mhStr)
done()
Expand All @@ -58,6 +60,7 @@ describe('CID', () => {
expect(cid).to.have.property('codec', 'dag-pb')
expect(cid).to.have.property('version', 0)
expect(cid).to.have.property('multihash')
expect(cid).to.have.property('multibaseName', 'base58btc')
})

it('throws on invalid BS58Str multihash ', () => {
Expand Down Expand Up @@ -108,19 +111,21 @@ describe('CID', () => {
expect(cid).to.have.property('codec', 'dag-pb')
expect(cid).to.have.property('version', 1)
expect(cid).to.have.property('multihash')
expect(cid).to.have.property('multibaseName', 'base58btc')

expect(cid.toBaseEncodedString()).to.be.eql(cidStr)
})

it('handles CID (no multibase)', () => {
const cidStr = 'zdj7Wd8AMwqnhJGQCbFxBVodGSBG84TM7Hs1rcJuQMwTyfEDS'
const cidStr = 'bafybeidskjjd4zmr7oh6ku6wp72vvbxyibcli2r6if3ocdcy7jjjusvl2u'
const cidBuf = Buffer.from('017012207252523e6591fb8fe553d67ff55a86f84044b46a3e4176e10c58fa529a4aabd5', 'hex')

const cid = new CID(cidBuf)

expect(cid).to.have.property('codec', 'dag-pb')
expect(cid).to.have.property('version', 1)
expect(cid).to.have.property('multihash')
expect(cid).to.have.property('multibaseName', 'base32')

expect(cid.toBaseEncodedString()).to.be.eql(cidStr)
})
Expand All @@ -131,6 +136,7 @@ describe('CID', () => {
expect(cid).to.have.property('codec', 'dag-cbor')
expect(cid).to.have.property('version', 1)
expect(cid).to.have.property('multihash')
expect(cid).to.have.property('multibaseName', 'base32')
})

it('can roundtrip through cid.toBaseEncodedString()', () => {
Expand All @@ -140,6 +146,7 @@ describe('CID', () => {
expect(cid1).to.have.property('codec').that.eql(cid2.codec)
expect(cid1).to.have.property('version').that.eql(cid2.version)
expect(cid1).to.have.property('multihash').that.eql(cid2.multihash)
expect(cid1).to.have.property('multibaseName').that.eql(cid2.multibaseName)
})

it('handles multibyte varint encoded codec codes', () => {
Expand All @@ -151,9 +158,11 @@ describe('CID', () => {
expect(cid1).to.have.property('codec', 'eth-block')
expect(cid1).to.have.property('version', 1)
expect(cid1).to.have.property('multihash').that.eql(mh)
expect(cid1).to.have.property('multibaseName', 'base32')
expect(cid2).to.have.property('codec', 'eth-block')
expect(cid2).to.have.property('version', 1)
expect(cid2).to.have.property('multihash').that.eql(mh)
expect(cid2).to.have.property('multibaseName', 'base32')
})

it('.prefix', () => {
Expand Down Expand Up @@ -199,9 +208,9 @@ describe('CID', () => {

it('returns a string in the base provided', () => {
const b58v1Str = 'zdj7Wd8AMwqnhJGQCbFxBVodGSBG84TM7Hs1rcJuQMwTyfEDS'
const b32v1Str = 'bafybeidskjjd4zmr7oh6ku6wp72vvbxyibcli2r6if3ocdcy7jjjusvl2u'
const b64urlv1Str = 'uAXASIHJSUj5lkfuP5VPWf_VahvhARLRqPkF24QxY-lKaSqvV'
const cid = new CID(b58v1Str)
expect(cid.toString('base32')).to.equal(b32v1Str)
expect(cid.toString('base64url')).to.equal(b64urlv1Str)
})
})

Expand Down