From 496af8cba4545a5d128ea03baa0095d8f7825c6f Mon Sep 17 00:00:00 2001 From: MF416 <93141290+MF416@users.noreply.github.com> Date: Wed, 1 Dec 2021 21:37:17 -0500 Subject: [PATCH] doc: extract runnable examples from README + update dependencies (#135) --- examples/block-interface.js | 31 +++++++++++++++ examples/cid-interface.js | 66 ++++++++++++++++++++++++++++++++ examples/multicodec-interface.js | 13 +++++++ examples/multihash-interface.js | 54 ++++++++++++++++++++++++++ 4 files changed, 164 insertions(+) create mode 100644 examples/block-interface.js create mode 100644 examples/cid-interface.js create mode 100644 examples/multicodec-interface.js create mode 100644 examples/multihash-interface.js diff --git a/examples/block-interface.js b/examples/block-interface.js new file mode 100644 index 00000000..262a9976 --- /dev/null +++ b/examples/block-interface.js @@ -0,0 +1,31 @@ +import * as Block from 'multiformats/block' +import * as codec from '@ipld/dag-cbor' +import { sha256 as hasher } from 'multiformats/hashes/sha2' + +async function run () { + const value = { hello: 'world' } + + // encode a block + const block = await Block.encode({ value, codec, hasher }) + + // block.value --> { hello: 'world' } + // block.bytes --> Uint8Array + // block.cid --> CID() w/ sha2-256 hash address and dag-cbor codec + + console.log('Example block CID: ' + block.cid.toString()) + + // you can also decode blocks from their binary state + const block2 = await Block.decode({ bytes: block.bytes, codec, hasher }) + + // check for equivalency using cid interface + console.log('Example block CID equal to decoded binary block: ' + block.cid.equals(block2.cid)) + + // if you have the cid you can also verify the hash on decode + const block3 = await Block.create({ bytes: block.bytes, cid: block.cid, codec, hasher }) + console.log('Example block CID equal to block created from CID + bytes: ' + block.cid.equals(block3.cid)) +} + +run().catch((err) => { + console.error(err) + process.exit(1) +}) diff --git a/examples/cid-interface.js b/examples/cid-interface.js new file mode 100644 index 00000000..add5b5b6 --- /dev/null +++ b/examples/cid-interface.js @@ -0,0 +1,66 @@ +import assert from 'assert' +import { CID } from 'multiformats/cid' +import * as json from 'multiformats/codecs/json' +import { sha256 } from 'multiformats/hashes/sha2' +import { base64 } from 'multiformats/bases/base64' + +async function run () { + // ** PART 1: CREATING A NEW CID ** + + // Arbitrary input value + const value = { hello: 'world' } + + // Encoded Uint8array representation of `value` using the plain JSON IPLD codec + const bytes = json.encode(value) + + // Hash Uint8array representation + const hash = await sha256.digest(bytes) + + // Create CID (default base32) + const cid = CID.create(1, json.code, hash) + + // cid.code --> 512 (0x0200) JSON IPLD codec) + // cid.version --> 1 + // cid.multihash --> digest, including code (18 for sha2-256), digest size (32 bytes) + // cid.bytes --> byte representation` + + console.log('Example CID: ' + cid.toString()) + // 'bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea' + + // ** PART 2: MULTIBASE ENCODERS / DECODERS / CODECS ** + + // Encode CID from part 1 to base64, decode back to base32 + const cidBase64 = cid.toString(base64.encoder) + console.log('base64 encoded CID: ' + cidBase64) + // 'mAYAEEiCTojlxqRTl6svwqNJRVM2jCcPBxy+7mRTUfGDzy2gViA' + + const cidBase32 = CID.parse(cidBase64, base64.decoder) + // 'bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea' + + // test decoded CID against original + assert.strictEqual(cidBase32.toString(), cid.toString(), 'Warning: decoded base32 CID does not match original') + console.log('Decoded CID equal to original base32: ' + cidBase32.equals(cid)) // alternatively, use more robust built-in function to test equivalence + + // Multibase codec exposes both encoder and decoder properties + cid.toString(base64) + CID.parse(cid.toString(base64), base64) + + // ** PART 3: CID BASE CONFIGURATIONS ** + + // CID v1 default encoding is base32 + const v1 = CID.parse('bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea') + v1.toString() + // 'bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea' + + // CID v0 default encoding is base58btc + const v0 = CID.parse('QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n') + v0.toString() + // 'QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n' + v0.toV1().toString() + // 'bafybeihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku' +} + +run().catch((err) => { + console.error(err) + process.exit(1) +}) diff --git a/examples/multicodec-interface.js b/examples/multicodec-interface.js new file mode 100644 index 00000000..dae59b3c --- /dev/null +++ b/examples/multicodec-interface.js @@ -0,0 +1,13 @@ +// Example of multicodec implementation for JSON (UTF-8-encoded) +// Codec implementations should conform to the BlockCodec interface which implements both BlockEncoder and BlockDecoder + +/** + * @template T + * @type {BlockCodec<0x0200, T>} + */ +export const { name, code, encode, decode } = { + name: 'json', + code: 0x0200, + encode: json => new TextEncoder().encode(JSON.stringify(json)), + decode: bytes => JSON.parse(new TextDecoder().decode(bytes)) +} diff --git a/examples/multihash-interface.js b/examples/multihash-interface.js new file mode 100644 index 00000000..979a1c8d --- /dev/null +++ b/examples/multihash-interface.js @@ -0,0 +1,54 @@ +import { CID } from 'multiformats/cid' +import crypto from 'crypto' +import * as json from 'multiformats/codecs/json' +import * as hasher from 'multiformats/hashes/hasher' + +// ** Example 1: sha2-256 hasher ** + +const sha256 = hasher.from({ + // As per multiformats table + // https://github.com/multiformats/multicodec/blob/master/table.csv#L9 + name: 'sha2-256', + code: 0x12, + + encode: (input) => new Uint8Array(crypto.createHash('sha256').update(input).digest()) +}) + +async function run1 () { + const hash = await sha256.digest(json.encode({ hello: 'world' })) + const cid = CID.create(1, json.code, hash) + + console.log(cid.multihash.size) // should equal 32 bytes for sha256 + console.log(cid) + // CID(bagaaierasords4njcts6vs7qvdjfcvgnume4hqohf65zsfguprqphs3icwea) +} + +run1().catch((err) => { + console.error(err) + process.exit(1) +}) + +// ** Example 2: sha3-512 hasher ** + +const sha512 = hasher.from({ + // As per multiformats table + // https://github.com/multiformats/multicodec/blob/master/table.csv#L9 + name: 'sha3-512', + code: 0x14, + + encode: (input) => new Uint8Array(crypto.createHash('sha512').update(input).digest()) +}) + +async function run2 () { + const hash2 = await sha512.digest(json.encode({ hello: 'world' })) + const cid2 = CID.create(1, json.code, hash2) + + console.log(cid2.multihash.size) // should equal 64 bytes for sha512 + console.log(cid2) + // CID(bagaaifca7d5wrebdi6rmqkgtrqyodq3bo6gitrqtemxtliymakwswbazbu7ai763747ljp7ycqfv7aqx4xlgiugcx62quo2te45pcgjbg4qjsvq) +} + +run2().catch((err) => { + console.error(err) + process.exit(1) +})