core

package
v0.1.21 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package core implements the Bitcoin 09 (09C) consensus rules.

Bitcoin 09 is Bitcoin, same-same but different in exactly one area: proof-of-work is Argon2id (memory-hard) instead of SHA-256d, so ordinary CPUs mine it and ASICs/GPUs gain almost nothing. Everything economic is Bitcoin-classic: 21M cap, 50-coin subsidy, halving every 210,000 blocks, 10-minute blocks, fair launch, no premine, unspendable genesis reward.

Index

Constants

View Source
const (
	TransactionStatusUnknown   = "unknown"
	TransactionStatusMempool   = "mempool"
	TransactionStatusConfirmed = "confirmed"
)

Transaction lookup status values are stable machine-facing identifiers.

View Source
const (
	CoinName               = "Bitcoin 09"
	Ticker                 = "09C"
	MainNetMachineID       = "btc09-mainnet"
	RegTestMachineID       = "btc09-regtest"
	UnitsPerCoin           = 100_000_000 // smallest unit, like satoshis
	MaxMoneyUnits    int64 = 21_000_000 * UnitsPerCoin

	InitialRewardUnits = 50 * UnitsPerCoin
	HalvingInterval    = 210_000 // blocks, Bitcoin-classic
	MaxHalvings        = 64

	MaxBlockBytes = 1_000_000 // 1 MB, Bitcoin-classic
)

Variables

View Source
var ErrMoneyRange = errors.New("money amount out of range")

ErrMoneyRange marks consensus rejection caused by a negative, overflowing, or above-maximum monetary value or aggregate.

View Source
var ErrSnapshotRegression = errors.New("canonical snapshot would regress durable work")
View Source
var MainNet = canonicalMainNetParams()
View Source
var RegTest = canonicalRegTestParams()

Functions

func CanonicalNetworkID added in v0.1.20

func CanonicalNetworkID(p *Params) (string, error)

CanonicalNetworkID returns the stable machine identity for an exact, canonical consensus parameter set. Names alone are intentionally insufficient because machine-facing data must never cross networks whose consensus rules differ.

func CompactToTarget

func CompactToTarget(bits uint32) *big.Int

CompactToTarget expands Bitcoin-style compact difficulty bits.

func DecodeAddress

func DecodeAddress(s string) (pkh [20]byte, err error)

DecodeAddress parses and checksums a 09C address.

func EncodeAddress

func EncodeAddress(pkh [20]byte) string

EncodeAddress renders a pubkey hash as a 09C address.

func HashToBig

func HashToBig(h Hash32) *big.Int

HashToBig interprets a hash as a big-endian integer for target comparison.

func MineGenesis

func MineGenesis(p *Params) uint64

MineGenesis searches nonces in parallel until the genesis header meets its target. Used once at launch to fix Params.GenesisNonce; tests re-verify the committed nonce.

func MoneyRange added in v0.1.20

func MoneyRange(value int64) bool

MoneyRange reports whether value is a valid consensus monetary amount.

func NewKey

func NewKey() (ed25519.PrivateKey, error)

NewKey generates a fresh Ed25519 private key.

func NextBits

func NextBits(p *Params, height int64, bitsAt func(h int64) uint32, timeAt func(h int64) int64) uint32

NextBits returns the required difficulty bits for the block at `height`, given accessors for ancestor headers on the same chain.

Retarget every RetargetInterval blocks by actual/expected timespan, clamped to 4x per adjustment (Bitcoin-classic behaviour, shorter window).

func PubKeyHash20

func PubKeyHash20(pub ed25519.PublicKey) (h [20]byte)

PubKeyHash20 is the address-level hash of an Ed25519 public key: first 20 bytes of SHA256(SHA256(pubkey)).

func SubsidyAt

func SubsidyAt(height int64) int64

SubsidyAt returns the block subsidy in units at a given height. 50 coins, halving every 210,000 blocks, exactly like Bitcoin.

func TargetToCompact

func TargetToCompact(t *big.Int) uint32

TargetToCompact compresses a target into compact bits (canonical form).

func WorkFromTarget

func WorkFromTarget(target *big.Int) *big.Int

WorkFromTarget returns the expected number of hashes to meet the target: 2^256 / (target + 1). Cumulative work decides the best chain.

Types

type AddressOutputSnapshot added in v0.1.20

type AddressOutputSnapshot struct {
	Network  string
	Complete bool
	Tip      ChainTipSnapshot
	Outputs  []ConfirmedAddressOutput
}

AddressOutputSnapshot is the complete canonical output history for one PKH at the exact Tip anchor.

type Block

type Block struct {
	Header Header
	Txs    []*Tx
}

Block is a header plus its transactions (first must be the coinbase).

func BuildBlockTemplate

func BuildBlockTemplate(c *Chain, rewardPKH [20]byte, tag string) *Block

BuildBlockTemplate assembles the next block for the given reward address: coinbase (subsidy + fees) plus mempool transactions that fit.

func DecodeBlock

func DecodeBlock(raw []byte) (*Block, error)

DecodeBlock parses a block from bytes.

func GenesisBlock

func GenesisBlock(p *Params) *Block

GenesisBlock builds the network's block 0 deterministically from Params.

Fair-launch rules, verifiable by anyone reading this file:

  • The 50 09C genesis reward is paid to the all-zero pubkey hash. Spending it requires an Ed25519 pubkey whose hash is 20 zero bytes, nobody can produce one, so the genesis coins are burned forever, exactly like Satoshi's unspendable genesis output.
  • The headline is embedded in the coinbase LockTag and ends up in every copy of the chain.

func (*Block) Bytes

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

Bytes encodes the full block.

type BlockLookupSnapshot added in v0.1.20

type BlockLookupSnapshot struct {
	Network   string
	Tip       ChainTipSnapshot
	Found     bool
	Hash      Hash32
	Height    int64
	Canonical bool
}

BlockLookupSnapshot reports whether a block is known and whether it belongs to the canonical chain anchored by Tip. Height is -1 when Found is false.

type Chain

type Chain struct {

	// OnNewTip is called after the best chain changes, outside the chain
	// lock, so callbacks may safely re-enter the chain (persist, announce).
	OnNewTip func(*Block, int64)
	// contains filtered or unexported fields
}

Chain holds consensus state: every valid block ever seen, the best chain selected by cumulative work, the UTXO set of that chain, and a mempool.

func NewChain

func NewChain(p *Params) (*Chain, error)

NewChain creates a chain initialized with the network's genesis block.

func (*Chain) AcceptBlock

func (c *Chain) AcceptBlock(b *Block) error

AcceptBlock fully validates a block and, if it creates a heavier chain, makes it the new tip (handling reorgs). Non-tip-extending valid blocks are stored for future fork choice.

func (*Chain) AcceptTx

func (c *Chain) AcceptTx(tx *Tx) error

AcceptTx validates a transaction against the current UTXO set + mempool and admits it to the mempool.

func (*Chain) AcceptTxWithResult added in v0.1.20

func (c *Chain) AcceptTxWithResult(tx *Tx) (TxAcceptanceResult, error)

AcceptTxWithResult validates and atomically admits a transaction, while reporting whether this call added it or observed an exact prior admission.

func (*Chain) BlockAt

func (c *Chain) BlockAt(h int64) *Block

BlockAt returns the main-chain block at a height.

func (*Chain) CanonicalTipSnapshot added in v0.1.20

func (c *Chain) CanonicalTipSnapshot() (ChainTipSnapshot, error)

CanonicalTipSnapshot returns the canonical machine-network identity and tip as one detached read snapshot.

func (*Chain) ConfirmedOutputsForPKH added in v0.1.20

func (c *Chain) ConfirmedOutputsForPKH(pkh [20]byte) (AddressOutputSnapshot, error)

ConfirmedOutputsForPKH scans the canonical blocks rather than the UTXO set, retaining spent history and excluding mempool-only outputs. Creation order is block height, transaction index, then vout.

func (*Chain) HasBlock

func (c *Chain) HasBlock(id Hash32) bool

HasBlock reports whether the id is known (any chain).

func (*Chain) Height

func (c *Chain) Height() int64

func (*Chain) LookupBlock added in v0.1.20

func (c *Chain) LookupBlock(id Hash32) (BlockLookupSnapshot, error)

LookupBlock returns canonical membership for a known block, including a side-chain block whose height may exceed the current canonical tip.

func (*Chain) LookupTransaction added in v0.1.20

func (c *Chain) LookupTransaction(id Hash32) (TransactionLookupSnapshot, error)

LookupTransaction applies canonical-confirmed, mempool, then unknown precedence under one chain read snapshot. Side-chain-only transactions are intentionally unknown.

func (*Chain) MempoolTxs

func (c *Chain) MempoolTxs() []*Tx

MempoolTxs returns mempool transactions, deterministic order.

func (*Chain) NextBitsForTip

func (c *Chain) NextBitsForTip() uint32

NextBitsForTip returns required bits for a block extending the main tip.

func (*Chain) Params

func (c *Chain) Params() *Params

func (*Chain) SpendableOutputsForPKHs added in v0.1.20

func (c *Chain) SpendableOutputsForPKHs(pkhs [][20]byte) (SpendableOutputsSnapshot, error)

SpendableOutputsForPKHs derives all mature canonical UTXOs for every owner under one Chain RLock. The canonical sequence is validated exactly once and outputs are sorted by raw transaction ID followed by numeric vout.

func (*Chain) Tip

func (c *Chain) Tip() (Hash32, int64)

func (*Chain) UTXOsForPKH

func (c *Chain) UTXOsForPKH(pkh [20]byte) map[OutPoint]UTXOEntry

UTXOsForPKH returns spendable outputs for an address at current height (coinbase maturity respected).

type ChainTipSnapshot added in v0.1.20

type ChainTipSnapshot struct {
	Network string
	Hash    Hash32
	Height  int64
}

ChainTipSnapshot is a detached, atomic view of the canonical chain tip.

type ConfirmedAddressOutput added in v0.1.20

type ConfirmedAddressOutput struct {
	TxID             Hash32
	TransactionIndex uint32
	Vout             uint32
	AmountUnits      int64
	BlockHash        Hash32
	BlockHeight      int64
	Confirmations    int64
	Coinbase         bool
	Mature           bool
	SpentBy          *ConfirmedSpend
}

ConfirmedAddressOutput is one output created on the canonical chain. Spent outputs remain present and carry their confirmed spender.

type ConfirmedSpend added in v0.1.20

type ConfirmedSpend struct {
	TxID        Hash32
	InputIndex  uint32
	BlockHash   Hash32
	BlockHeight int64
}

ConfirmedSpend identifies the canonical transaction input that spent an address output.

type Hash32

type Hash32 [32]byte

Hash32 is a 32-byte hash.

func MerkleRoot

func MerkleRoot(txs []*Tx) Hash32

MerkleRoot computes the Bitcoin-style merkle root of txids (last node duplicated on odd levels).

func PowHash

func PowHash(header []byte, p *Params) Hash32

PowHash is the mining hash: Argon2id over the 88-byte block header. The 64 MiB memory cost per attempt is what makes mining memory-bound.

func SHA256d

func SHA256d(b []byte) Hash32

SHA256d is Bitcoin's double SHA-256, used for identifiers (block ids, txids, merkle nodes). Cheap and collision resistant.

type Header struct {
	Version    uint32
	PrevBlock  Hash32
	MerkleRoot Hash32
	Time       int64
	Bits       uint32
	Nonce      uint64
}

Header is the 88-byte mined portion of a block.

func (*Header) Bytes

func (h *Header) Bytes() []byte

Bytes returns the canonical 88-byte header encoding (the PoW input).

func (*Header) CheckPow

func (h *Header) CheckPow(p *Params) bool

CheckPow verifies the header's Argon2id hash meets its claimed target.

func (*Header) CheckTimestamp

func (h *Header) CheckTimestamp(p *Params, now time.Time) error

CheckTimestamp enforces the future-drift rule.

func (*Header) ID

func (h *Header) ID() Hash32

ID is the block identifier: cheap SHA256d of the header. (PoW validity uses PowHash separately; ids stay cheap to compute.)

type MineResult

type MineResult struct {
	Block  *Block
	Hashes uint64
}

MineResult carries a found block and mining statistics.

func Mine

func Mine(ctx context.Context, c *Chain, template *Block, workers int) *MineResult

Mine grinds nonces across `workers` goroutines until a block is found or ctx is cancelled or the chain tip changes (stale template).

type OutPoint

type OutPoint struct {
	TxID Hash32
	Idx  uint32
}

OutPoint references a specific output of a prior transaction.

type Params

type Params struct {
	Name             string
	NetMagic         uint32 // wire/network id
	TargetBlockTime  int64  // seconds
	RetargetInterval int64  // blocks between difficulty adjustments
	CoinbaseMaturity int64  // blocks before a coinbase output is spendable
	MaxTargetBits    uint32 // easiest allowed difficulty, compact encoding
	// Argon2id proof-of-work cost parameters (per hash attempt).
	ArgonMemKiB uint32
	ArgonTime   uint32
	// Genesis
	GenesisTime     int64
	GenesisNonce    uint64
	GenesisHeadline string
	FutureDrift     int64 // max seconds a block time may be ahead of local clock
}

Params defines a network (mainnet or regtest for local testing).

func (*Params) MaxTarget

func (p *Params) MaxTarget() *big.Int

MaxTarget returns the easiest-allowed PoW target for the network.

type SpendableOutputSnapshot added in v0.1.20

type SpendableOutputSnapshot struct {
	OutPoint    OutPoint
	AmountUnits int64
	OwnerPKH    [20]byte
	OwnerIndex  uint32
}

SpendableOutputSnapshot is one mature, canonically unspent output owned by an entry in the caller's PKH list. OwnerIndex refers to that input list.

type SpendableOutputsSnapshot added in v0.1.20

type SpendableOutputsSnapshot struct {
	Network  string
	Complete bool
	Tip      ChainTipSnapshot
	Outputs  []SpendableOutputSnapshot
}

SpendableOutputsSnapshot is one immutable multi-owner view derived under a single Chain read lock and anchored to one exact canonical tip.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store persists canonical blocks as repeated [4-byte BE length][block bytes] records for heights 1..N. Genesis is derived from the selected network. Every reader/writer uses both an in-process mutex and a canonical-path OS lock; multiple Store instances and processes therefore share one ordering.

func NewStore

func NewStore(dataDir string, network string) (*Store, error)

func (*Store) LoadInto

func (s *Store) LoadInto(c *Chain) (height int64, err error)

LoadInto strictly validates the complete durable file on a scratch chain while holding the OS lock, then atomically installs that state into c. A corrupt/truncated tail never leaves the caller partially advanced.

func (*Store) SaveSnapshot

func (s *Store) SaveSnapshot(c *Chain) error

SaveSnapshot serializes one detached canonical Chain snapshot. Lock order is Store.mu -> OS file lock -> one Chain RLock snapshot -> disk operations.

type TransactionLookupSnapshot added in v0.1.20

type TransactionLookupSnapshot struct {
	Network       string
	Tip           ChainTipSnapshot
	TxID          Hash32
	Status        string
	BlockHash     Hash32
	BlockHeight   int64
	Confirmations int64
}

TransactionLookupSnapshot reports canonical confirmation state anchored by Tip. BlockHeight is -1 for mempool and unknown transactions.

type Tx

type Tx struct {
	Version uint32
	Ins     []TxIn
	Outs    []TxOut
	LockTag []byte // coinbase-only extra data (headline, miner tag)
}

Tx is a transaction. A coinbase has exactly one input with a zero Prev and height+arbitrary bytes in PubKey (no signature required).

func DecodeTx

func DecodeTx(b []byte) (*Tx, error)

DecodeTx parses a transaction from bytes.

func NewCoinbase

func NewCoinbase(height int64, value int64, to [20]byte, tag string) *Tx

NewCoinbase builds the miner-reward transaction for a block.

func (*Tx) Bytes

func (t *Tx) Bytes() []byte

Bytes returns the full wire encoding.

func (*Tx) ID

func (t *Tx) ID() Hash32

ID returns the txid: SHA256d over the full encoding.

func (*Tx) IsCoinbase

func (t *Tx) IsCoinbase() bool

IsCoinbase reports whether tx is a coinbase transaction.

func (*Tx) SigDigest

func (t *Tx) SigDigest() Hash32

SigDigest returns the digest each input signs.

func (*Tx) Sign

func (t *Tx) Sign(keys []ed25519.PrivateKey) error

Sign signs every input with the corresponding private key.

type TxAcceptanceResult added in v0.1.20

type TxAcceptanceResult string

TxAcceptanceResult distinguishes a newly admitted transaction from an exact idempotent replay. The result is decided under the same chain lock as validation and admission, so concurrent callers cannot both report added.

const (
	TxAcceptanceAdded        TxAcceptanceResult = "added"
	TxAcceptanceAlreadyKnown TxAcceptanceResult = "already_known"
)

type TxIn

type TxIn struct {
	Prev   OutPoint
	PubKey []byte // 32-byte Ed25519 public key
	Sig    []byte // 64-byte Ed25519 signature
}

TxIn spends an outpoint. Sig covers the transaction's signing digest and PubKey must hash to the PubKeyHash of the referenced output.

type TxOut

type TxOut struct {
	Value      int64
	PubKeyHash [20]byte
}

TxOut locks `Value` units to a public key hash.

type UTXOEntry

type UTXOEntry struct {
	Value    int64
	PKH      [20]byte
	Height   int64
	Coinbase bool
}

UTXOEntry is an unspent output plus the metadata needed for validation.

Jump to

Keyboard shortcuts

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