bc

package module
v0.1.29 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2024 License: ISC Imports: 16 Imported by: 23

README

go-bc

The go-to Bitcoin Block Chain (BC) GoLang library

Release Build Status Report codecov Go Sponsor Donate


Table of Contents


Installation

go-bc requires a supported release of Go.

go get -u github.com/libsv/go-bc

Documentation

View the generated documentation

GoDoc

For more information around the technical aspects of Bitcoin, please see the updated Bitcoin Wiki


Features
  • Block header building
  • Coinbase transaction building (cb1 + cb2 in stratum protocol)
  • Bitcoin block hash difficulty and hashrate functions
  • Merkle proof/root/branch functions
Library Deployment

goreleaser for easy binary or library deployment to Github and can be installed via: brew install goreleaser.

The .goreleaser.yml file is used to configure goreleaser.

Use make release-snap to create a snapshot version of the release, and finally make release to ship to production.

Makefile Commands

View all makefile commands

make help

List of all current commands:

all                  Runs multiple commands
clean                Remove previous builds and any test cache data
clean-mods           Remove all the Go mod cache
coverage             Shows the test coverage
godocs               Sync the latest tag with GoDocs
help                 Show this help message
install              Install the application
install-go           Install the application (Using Native Go)
lint                 Run the golangci-lint application (install if not found)
release              Full production release (creates release in Github)
release              Runs common.release then runs godocs
release-snap         Test the full release (build binaries)
release-test         Full production test release (everything except deploy)
replace-version      Replaces the version in HTML/JS (pre-deploy)
tag                  Generate a new tag and push (tag version=0.0.0)
tag-remove           Remove a tag if found (tag-remove version=0.0.0)
tag-update           Update an existing tag to current commit (tag-update version=0.0.0)
test                 Runs vet, lint and ALL tests
test-ci              Runs all tests via CI (exports coverage)
test-ci-no-race      Runs all tests via CI (no race) (exports coverage)
test-ci-short        Runs unit tests via CI (exports coverage)
test-short           Runs vet, lint and tests (excludes integration tests)
uninstall            Uninstall the application (and remove files)
update-linter        Update the golangci-lint package (macOS only)
vet                  Run the Go vet application

Examples & Tests

All unit tests and examples run via Github Actions and uses Go version 1.15.x. View the configuration file.

Run all tests (including integration tests)

make test

Run tests (excluding integration tests)

make test-short

Benchmarks

Run the Go benchmarks:

make bench

Code Standards

Read more about this Go project's code standards.


Usage

View the examples


Maintainers

JW
JW

Contributors

JW SO LM
JW SO LM

Contributing

View the contributing guidelines and please follow the code of conduct.

How can I help?

All kinds of contributions are welcome 🙌! The most basic way to show your support is to star 🌟 the project, or to raise issues 💬. You can also support this project by becoming a sponsor on GitHub 👏 or by making a bitcoin donation to ensure this journey continues indefinitely! 🚀


License

License

Documentation

Overview

Package bc is a bitcoin blockchain library bc = block chain.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrHeaderNotFound can be returned if the blockHash isn't found on the network.
	ErrHeaderNotFound = errors.New("header with not found")
	// ErrNotOnLongestChain indicates the blockhash is present but isn't on the longest current chain.
	ErrNotOnLongestChain = errors.New("header exists but is not on the longest chain")
)

Functions

func BuildCoinbase

func BuildCoinbase(c1 []byte, c2 []byte, extraNonce1 string, extraNonce2 string) []byte

BuildCoinbase recombines the different parts of the coinbase transaction. See https://arxiv.org/pdf/1703.06545.pdf section 2.2 for more info.

func BuildMerkleRoot

func BuildMerkleRoot(txids []string) (string, error)

BuildMerkleRoot builds the Merkle Root from a list of transactions.

func BuildMerkleRootFromCoinbase

func BuildMerkleRootFromCoinbase(coinbaseHash []byte, merkleBranches []string) []byte

BuildMerkleRootFromCoinbase builds the merkle root of the block from the coinbase transaction hash (txid) and the merkle branches needed to work up the merkle tree and returns the merkle root byte array.

func BuildMerkleTreeStore

func BuildMerkleTreeStore(txids []string) ([]string, error)

BuildMerkleTreeStore creates a merkle tree from a slice of transaction IDs, stores it using a linear array, and returns a slice of the backing array. A linear array was chosen as opposed to an actual tree structure since it uses about half as much memory. The following describes a merkle tree and how it is stored in a linear array.

A merkle tree is a tree in which every non-leaf node is the hash of its children nodes. A diagram depicting how this works for bitcoin transactions where h(x) is a double sha256 follows:

         root = h1234 = h(h12 + h34)
        /                           \
  h12 = h(h1 + h2)            h34 = h(h3 + h4)
   /            \              /            \
h1 = h(tx1)  h2 = h(tx2)    h3 = h(tx3)  h4 = h(tx4)

The above stored as a linear array is as follows:

[h1 h2 h3 h4 h12 h34 root]

As the above shows, the merkle root is always the last element in the array.

The number of inputs is not always a power of two which results in a balanced tree structure as above. In that case, parent nodes with no children are also zero and parent nodes with only a single left node are calculated by concatenating the left node with itself before hashing. Since this function uses nodes that are pointers to the hashes, empty nodes will be nil.

The additional bool parameter indicates if we are generating the merkle tree using witness transaction id's rather than regular transaction id's. This also presents an additional case wherein the wtxid of the coinbase transaction is the zeroHash.

based off of bsvd: https://github.com/bitcoinsv/bsvd/blob/4c29707f717300d3eb92352081c3b0fec556881b/blockchain/merkle.go#L74

func BuildMerkleTreeStoreChainHash added in v0.1.19

func BuildMerkleTreeStoreChainHash(txids []*chainhash.Hash) []*chainhash.Hash

BuildMerkleTreeStoreChainHash has the same functionality as BuildMerkleTreeStore but uses chainhash as a type to avoid string conversions.

func BytesFromStringReverse added in v0.1.12

func BytesFromStringReverse(s string) []byte

BytesFromStringReverse decodes a hex string into a byte slice and reverses it.

func Decode32Byte

func Decode32Byte(hexStr string) ([32]byte, error)

Decode32Byte decodes a hex string into a 32 byte array.

func DifficultyFromBits

func DifficultyFromBits(bits []byte) (float64, error)

DifficultyFromBits returns the mining difficulty from the nBits field in the block header.

func DifficultyToHashrate

func DifficultyToHashrate(coin string, diff uint64, targetSeconds float64) float64

DifficultyToHashrate takes a specific coin ticker, it's difficulty, and target and computes the estimated hashrate on that specific coin (or chain).

func Equals

func Equals(b1 []byte, b2 []byte) bool

Equals checks if two byte arrays are equal.

func ExpandTargetFrom

func ExpandTargetFrom(bits string) (string, error)

ExpandTargetFrom comment.

func ExpandTargetFromAsInt

func ExpandTargetFromAsInt(bits string) (*big.Int, error)

ExpandTargetFromAsInt comment.

func ExtractMerkleRootFromBlockHeader

func ExtractMerkleRootFromBlockHeader(header string) (string, error)

ExtractMerkleRootFromBlockHeader will take an 80 byte Bitcoin block header hex string and return the Merkle Root from it.

func GetCoinbaseParts

func GetCoinbaseParts(height uint32, coinbaseValue uint64, defaultWitnessCommitment string, coinbaseText string,
	walletAddress string, minerIDBytes []byte) (coinbase1 []byte, coinbase2 []byte, err error)

GetCoinbaseParts returns the two split coinbase parts from coinbase metadata. See https://arxiv.org/pdf/1703.06545.pdf section 2.2 for more info.

func GetMerkleBranches

func GetMerkleBranches(template []string) []string

GetMerkleBranches comment.

func HumanHash

func HumanHash(val float64) string

HumanHash returns a human readable hash/second value from a very large number.

func MerkleRootFromBranches

func MerkleRootFromBranches(txHash string, txIndex int, branches []string) (string, error)

MerkleRootFromBranches returns a Merkle root given a transaction hash (txid), the index in which it is positioned in the Merkle tree, and the branches needed along the way (Merkle path).

func MerkleTreeParent

func MerkleTreeParent(leftNode, rightNode []byte) []byte

MerkleTreeParent returns the Merkle Tree parent of two Merkle Tree children.

func MerkleTreeParentBytes added in v0.1.19

func MerkleTreeParentBytes(l *chainhash.Hash, r *chainhash.Hash) *chainhash.Hash

MerkleTreeParentBytes returns the Merkle Tree parent of two Merkle Tree children. The expectation is that the bytes are not reversed.

func MerkleTreeParentStr

func MerkleTreeParentStr(leftNode, rightNode string) (string, error)

MerkleTreeParentStr returns the Merkle Tree parent of two Merkle Tree children using hex strings instead of just bytes.

func ReverseHexString

func ReverseHexString(hex string) string

ReverseHexString reverses the hex string (little endian/big endian). This is used when computing merkle trees in Bitcoin, for example.

func Sha256Sha256 added in v0.1.12

func Sha256Sha256(digest []byte) []byte

Sha256Sha256 calculates the double sha256 hash of a byte slice.

func SortByteArrays

func SortByteArrays(src [][]byte) [][]byte

SortByteArrays comment.

func StringFromBytesReverse added in v0.1.12

func StringFromBytesReverse(h []byte) string

StringFromBytesReverse reverses a byte slice and encodes it as a hex string.

func TxsToTxIDs

func TxsToTxIDs(txs []string) ([]string, error)

TxsToTxIDs takes an array of transactions and returns instead an array of their corresponding transaction IDs.

func UInt32ToBytes added in v0.1.2

func UInt32ToBytes(num uint32) []byte

UInt32ToBytes converts a uint32 into an array of bytes.

Types

type BUMP added in v0.1.19

type BUMP struct {
	BlockHeight uint64   `json:"blockHeight"`
	Path        [][]leaf `json:"path"`
}

BUMP data model json format according to BRC-74.

func NewBUMPFromBytes added in v0.1.19

func NewBUMPFromBytes(bytes []byte) (*BUMP, error)

NewBUMPFromBytes creates a new BUMP from a byte slice.

func NewBUMPFromJSON added in v0.1.19

func NewBUMPFromJSON(jsonStr string) (*BUMP, error)

NewBUMPFromJSON creates a BUMP from a JSON string.

func NewBUMPFromMerkleTreeAndIndex added in v0.1.19

func NewBUMPFromMerkleTreeAndIndex(blockHeight uint64, merkleTree []*chainhash.Hash, txIndex uint64) (*BUMP, error)

NewBUMPFromMerkleTreeAndIndex with merkle tree we calculate the merkle path for a given transaction.

func NewBUMPFromStr added in v0.1.19

func NewBUMPFromStr(str string) (*BUMP, error)

NewBUMPFromStr creates a BUMP from hex string.

func NewBUMPFromStream added in v0.1.29

func NewBUMPFromStream(bytes []byte) (*BUMP, int, error)

NewBUMPFromStream takes an array of bytes and contructs a BUMP from it, returning the BUMP and the bytes used. Despite the name, this is not actually reading a stream in the true sense: it is a byte slice that contains many BUMPs one after another.

func (*BUMP) Bytes added in v0.1.19

func (bump *BUMP) Bytes() ([]byte, error)

Bytes encodes a BUMP as a slice of bytes. BUMP Binary Format according to BRC-74 https://brc.dev/74

func (*BUMP) CalculateRootGivenTxid added in v0.1.19

func (bump *BUMP) CalculateRootGivenTxid(txid string) (string, error)

CalculateRootGivenTxid calculates the root of the Merkle tree given a txid.

func (*BUMP) String added in v0.1.19

func (bump *BUMP) String() (string, error)

String encodes a BUMP as a hex string.

func (*BUMP) Txids added in v0.1.25

func (bump *BUMP) Txids() []string

Txids returns the txids within the BUMP which the client is expecting. This allows a client to receive one BUMP for a whole block and it will know which txids it should update.

type Block added in v0.1.2

type Block struct {
	BlockHeader *BlockHeader
	Txs         []*bt.Tx
}

A Block in the Bitcoin blockchain.

func NewBlockFromBytes added in v0.1.2

func NewBlockFromBytes(b []byte) (*Block, error)

NewBlockFromBytes will encode a block header byte slice into the bitcoin block header structure.

See https://btcinformation.org/en/developer-reference#serialized-blocks

func NewBlockFromStr added in v0.1.2

func NewBlockFromStr(blockStr string) (*Block, error)

NewBlockFromStr will encode a block header hash into the bitcoin block header structure.

See https://btcinformation.org/en/developer-reference#serialized-blocks

func (*Block) Bytes added in v0.1.2

func (b *Block) Bytes() []byte

Bytes will decode a bitcoin block struct into a byte slice.

See https://btcinformation.org/en/developer-reference#serialized-blocks

func (*Block) String added in v0.1.2

func (b *Block) String() string

String returns the Block Header encoded as hex string.

type BlockHeader

type BlockHeader struct {
	Version        uint32 `json:"version"`
	Time           uint32 `json:"time"`
	Nonce          uint32 `json:"nonce"`
	HashPrevBlock  []byte `json:"hashPrevBlock"`
	HashMerkleRoot []byte `json:"merkleRoot"`
	Bits           []byte `json:"bits"`
}

A BlockHeader in the Bitcoin blockchain.

func NewBlockHeaderFromBytes added in v0.1.2

func NewBlockHeaderFromBytes(headerBytes []byte) (*BlockHeader, error)

NewBlockHeaderFromBytes will encode a block header byte slice into the bitcoin block header structure.

See https://en.bitcoin.it/wiki/Block_hashing_algorithm

func NewBlockHeaderFromStr added in v0.1.2

func NewBlockHeaderFromStr(headerStr string) (*BlockHeader, error)

NewBlockHeaderFromStr will encode a block header hash into the bitcoin block header structure.

See https://en.bitcoin.it/wiki/Block_hashing_algorithm

func (*BlockHeader) BitsStr added in v0.1.2

func (bh *BlockHeader) BitsStr() string

BitsStr returns the Block Header encoded as hex string.

func (*BlockHeader) Bytes added in v0.1.1

func (bh *BlockHeader) Bytes() []byte

Bytes will decode a bitcoin block header struct into a byte slice.

See https://en.bitcoin.it/wiki/Block_hashing_algorithm

func (*BlockHeader) HashMerkleRootStr added in v0.1.2

func (bh *BlockHeader) HashMerkleRootStr() string

HashMerkleRootStr returns the Block Header encoded as hex string.

func (*BlockHeader) HashPrevBlockStr added in v0.1.2

func (bh *BlockHeader) HashPrevBlockStr() string

HashPrevBlockStr returns the Block Header encoded as hex string.

func (*BlockHeader) MarshalJSON added in v0.1.4

func (bh *BlockHeader) MarshalJSON() ([]byte, error)

MarshalJSON marshals the receiving bc.BlockHeader into a JSON []byte.

func (*BlockHeader) String added in v0.1.1

func (bh *BlockHeader) String() string

String returns the Block Header encoded as hex string.

func (*BlockHeader) UnmarshalJSON added in v0.1.4

func (bh *BlockHeader) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals a JSON []byte into the receiving bc.BlockHeader.

func (*BlockHeader) Valid added in v0.1.2

func (bh *BlockHeader) Valid() bool

Valid checks whether a blockheader satisfies the proof-of-work claimed in Bits. Wwe check whether its Hash256 read as a little endian number is less than the Bits written in expanded form.

type BlockHeaderChain

type BlockHeaderChain interface {
	BlockHeader(ctx context.Context, blockHash string) (*BlockHeader, error)
}

A BlockHeaderChain is a generic interface used to map things in the block header chain (chain of block headers). For example, it is used to get a block Header from a bitcoin block hash if it exists in the longest block header chain.

Errors can be returned if the header isn't found or is on a stale chain, you may also use the ErrHeaderNotFound & ErrNotOnLongestChain sentinel errors when implementing the interface.

type MapiCallback added in v0.1.2

type MapiCallback struct {
	CallbackPayload string `json:"callbackPayload"`
	APIVersion      string `json:"apiVersion"`
	Timestamp       string `json:"timestamp"`
	MinerID         string `json:"minerId"`
	BlockHash       string `json:"blockHash"`
	BlockHeight     uint64 `json:"blockHeight"`
	CallbackTxID    string `json:"callbackTxId"`
	CallbackReason  string `json:"callbackReason"`
}

MapiCallback is the body contents posted to the provided callback url from Merchant API.

func NewMapiCallbackFromBytes added in v0.1.8

func NewMapiCallbackFromBytes(b []byte) (*MapiCallback, error)

NewMapiCallbackFromBytes is a glorified json unmarshaller, but might be more sophisticated in future.

func (*MapiCallback) Bytes added in v0.1.8

func (mcb *MapiCallback) Bytes() ([]byte, error)

Bytes converts the MapiCallback struct into a binary format. We are not going to parse anything out but rather take the whole json object as a binary blob. The reason behind this approach is that the whole callback is signed by the mapi server, so if a single byte is out of place the signature will be invalid.

type MerklePath added in v0.1.12

type MerklePath struct {
	Index uint64   `json:"index"`
	Path  []string `json:"path"`
}

MerklePath data model json format according to BRC-58.

func GetTxMerklePath added in v0.1.12

func GetTxMerklePath(txIndex int, merkleTree []string) *MerklePath

GetTxMerklePath with merkle tree we calculate the merkle path for a given transaction.

func NewMerklePathFromBytes added in v0.1.12

func NewMerklePathFromBytes(bytes []byte) (*MerklePath, error)

NewMerklePathFromBytes creates a new MerklePath from a byte slice.

func NewMerklePathFromStr added in v0.1.12

func NewMerklePathFromStr(str string) (*MerklePath, error)

NewMerklePathFromStr creates a MerklePath from hex string.

func (*MerklePath) Bytes added in v0.1.12

func (mp *MerklePath) Bytes() ([]byte, error)

Bytes encodes a MerklePath as a slice of bytes. MerklePath Binary Format according to BRC-71 https://brc.dev/71

func (*MerklePath) CalculateRoot added in v0.1.12

func (mp *MerklePath) CalculateRoot(txid string) (string, error)

CalculateRoot calculates the merkle root from a transaction ID and a MerklePath.

func (*MerklePath) String added in v0.1.12

func (mp *MerklePath) String() (string, error)

String encodes a MerklePath as a hex string.

type MerkleProof

type MerkleProof struct {
	Index      uint64   `json:"index"`
	TxOrID     string   `json:"txOrId"`
	Target     string   `json:"target"`
	Nodes      []string `json:"nodes"`
	TargetType string   `json:"targetType,omitempty"`
	ProofType  string   `json:"proofType,omitempty"`
	Composite  bool     `json:"composite,omitempty"`
}

A MerkleProof is a structure that proves inclusion of a Bitcoin transaction in a block.

func (*MerkleProof) Bytes added in v0.1.8

func (mp *MerkleProof) Bytes() ([]byte, error)

Bytes converts the JSON Merkle Proof into byte encoding.

Check the following encoding:

flags: byte, index: varint, txLength: varint, //omitted if flag bit 0 == 0 as it's a fixed length transaction ID txOrId: byte[32 or variable length], target: byte[32 or 80], //determined by flag bits 1 and 2 nodeCount: varint, nodes: node[]

Directories

Path Synopsis
Package spv is a simple payment verification library for Bitcoin SV.
Package spv is a simple payment verification library for Bitcoin SV.
testing
data
Package data contains test data for the spv package.
Package data contains test data for the spv package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL