Skip to content

JavaScript Bitcoin data multiformats codecs and utilities for IPLD

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

isabella232/js-bitcoin

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IPLD for Bitcoin

JavaScript Bitcoin data multiformats codecs and utilities for IPLD

CI

About

This codec is intended to be used with multiformats and @ipld/block. It provides decode and encode functionality for the Bitcoin native format to and from IPLD.

The primary usage of this library is as a codec added to a multiformats object:

const multiformats = require('multiformats')()
multiformats.add(require('@ipld/bitcoin'))

The following multicodecs are registered:

  • bitcoin-block / 0xb0: The Bitcoin block header, commonly identified by "Bitcoin block identifiers" (hashes with leading zeros).
  • bitcoin-tx / 0xb1: Bitcoin transactions and nodes in a binary merkle tree, the tip of which is referenced by the Bitcoin block header.
  • bitcoin-witness-commitment / 0xb2: The Bitcoin witness commitment that is used to reference transactions with intact witness data (a complication introduced by SegWit).

These multicodecs support encode() and decode() functionality through multiformats.

The following multihash is registered:

  • dbl-sha2-256 / 0x56: A double SHA2-256 hash: SHA2-256(SHA2-256(bytes)), used natively across all Bitcoin blocks, forming block identifiers, transaction identifiers and hashes and binary merkle tree nodes.

In addition to the multiformats codecs and hash, utilities are also provided to convert between Bitcoin hash identifiers and CIDs and to convert to and from full Bitcoin raw block data to a full collection of IPLD blocks. Additional conversion functionality for bitcoin raw data and the bitcoin-cli JSON format is provided by the bitcoin-block library.

See the API section below for details on the additional utility functions.

The previous incarnation of the Bitcoin codec for IPLD can be found at https://github.com/ipld/js-ipld-bitcoin.

Example

const multiformats = require('multiformats/basics')
multiformats.add(require('@ipld/bitcoin'))
const CarDatastore = require('datastore-car')(multiformats)

const carDs = await CarDatastore.readFileComplete('/path/to/bundle/of/blocks.car')
const headerCid = ipldBitcoin.blockHashToCID(multiformats, hash)
const header = multiformats.decode(await carDs.get(headerCid), 'bitcoin-block')

// navigate the transaction binary merkle tree to the first transaction, the coinbase
let txCid = header.tx
let tx
while (true) {
	tx = multiformats.decode(await carDs.get(txCid), 'bitcoin-tx')
	if (!Array.isArray(tx)) { // is not an inner merkle tree node
		break
	}
	txCid = tx[0] // leftmost side of the tx binary merkle
}

// convert the scriptSig to UTF-8 and cross our fingers that there's something
// interesting in there
console.log(Buffer.from(tx.vin[0].coinbase, 'hex').toString('utf8'))

API

Contents

deserializeFullBitcoinBinary(binary)

Instantiate a full object form from a full Bitcoin block graph binary representation. This binary form is typically extracted from a Bitcoin network node, such as with the Bitcoin Core bitcoin-cli getblock <identifier> 0 command (which outputs hexadecimal form and therefore needs to be decoded prior to handing to this function). This full binary form can also be obtained from the utility assemble function which can construct the full graph form of a Bitcoin block from the full IPLD block graph.

The object returned, if passed through JSON.stringify() should be identical to the JSON form provided by the Bitcoin Core bitcoin-cli getblock <identifier> 2 command (minus some chain-context elements that are not possible to derive without the full blockchain).

Parameters:

  • binary (Uint8Array|Buffer): a binary form of a Bitcoin block graph

Return value (object): an object representation of the full Bitcoin block graph

serializeFullBitcoinBinary(obj)

Encode a full object form of a Bitcoin block graph into its binary equivalent. This is the inverse of deserializeFullBitcoinBinary and should produce the exact binary representation of a Bitcoin block graph given the complete input.

The object form must include both the header and full transaction (including witness data) data for it to be properly serialized.

As of writing, the witness merkle nonce is not currently present in the JSON output from Bitcoin Core's bitcoin-cli. See bitcoin/bitcoin#18826 for more information. Without this nonce, the exact binary form cannot be fully generated.

Parameters:

  • obj (object): a full JavaScript object form of a Bitcoin block graph

Return value (Buffer): a binary form of the Bitcoin block graph

async blockToCar(multiformats, carWriter, obj)

Extract all IPLD blocks from a full Bitcoin block graph and write them to a CAR archive.

This operation requires a full deserialized Bitcoin block graph, where the transactions in their full form (with witness data intact post-segwit), as typically presented in JSON form with the Bitcoin Core bitcoin-cli command getblock <identifier> 2 or using one of the utilities here to instantiate a full object form.

The CAR archive should be created using datastore-car and should be capable of write operations.

Parameters:

  • multiformats (object): a multiformats object with dbl-sha2-256 multihash, bitcoin-block, bitcoin-tx and bitcoin-witness-commitment multicodecs as well as the dag-cbor multicodec which is required for writing the CAR header.
  • carWriter (object): an initialized and writable CarDatastore instance.
  • obj (object): a full Bitcoin block graph.

Return value (object): a CID for the root block (the header bitcoin-block).

cidToHash(multiformats, cid)

Convert a CID to a Bitcoin block or transaction identifier. This process is the reverse of blockHashToCID and txHashToCID and involves extracting and decoding the multihash from the CID, reversing the bytes and presenting it as a big-endian hexadecimal string.

Works for both block identifiers and transaction identifiers.

Parameters:

  • multiformats (object): a multiformats object
  • cid (object): a CID (multiformats.CID)

Return value (string): a hexadecimal big-endian representation of the identifier.

async assemble(multiformats, loader, blockCID)

Given a CID for a bitcoin-block Bitcoin block header and an IPLD block loader that can retrieve Bitcoin IPLD blocks by CID, re-assemble a full Bitcoin block graph into both object and binary forms.

The loader should be able to return the binary form for bitcoin-block, bitcoin-tx and bitcoin-witness-commitment CIDs.

Parameters:

  • multiformats (object): a multiformats object with the Bitcoin multicodec and multihash installed
  • loader (function): an IPLD block loader function that takes a CID argument and returns a Buffer or Uint8Array containing the binary block data for that CID
  • blockCID (CID): a CID of type bitcoin-block pointing to the Bitcoin block header for the block to be assembled

Return value (object): an object containing two properties, deserialized and binary where deserialized contains a full JavaScript instantiation of the Bitcoin block graph and binary contains a Buffer with the binary representation of the graph.

blockHashToCID(multiformats)

Convert a Bitcoin block identifier (hash) to a CID. The identifier should be in big-endian form, i.e. with leading zeros.

The process of converting to a CID involves reversing the hash (to little-endian form), encoding as a dbl-sha2-256 multihash and encoding as a bitcoin-block multicodec. This process is reversable, see cidToHash.

Parameters:

  • multiformats (object): a multiformats object with dbl-sha2-256 multihash and bitcoin-block multicodec registered

Return value (object): a CID (multiformats.CID) object representing this block identifier.

txHashToCID(multiformats)

Convert a Bitcoin transaction identifier (hash) to a CID. The identifier should be in big-endian form as typically understood by Bitcoin applications.

The process of converting to a CID involves reversing the hash (to little-endian form), encoding as a dbl-sha2-256 multihash and encoding as a bitcoin-tx multicodec. This process is reversable, see cidToHash.

Parameters:

  • multiformats (object): a multiformats object with dbl-sha2-256 multihash and bitcoin-tx multicodec registered

Return value (object): A CID (multiformats.CID) object representing this transaction identifier.

License

Licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

JavaScript Bitcoin data multiformats codecs and utilities for IPLD

Resources

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE-APACHE
MIT
LICENSE-MIT

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%