Welcome! started as a list of hyperlinks, notes, and text I found to be useful while learning about Bitcoin.

This project is open-source and contributions are highly encouraged.

If you find any mistakes, open an Issue on Github.


I am hoping these notes serve a useful purpose to the reader in getting started with Bitcoin or refreshing old knowledge. The best way to use this document is to search for topics by heading and sub-heading and follow hyperlinks to the original resources.

The audience of this document is expected to have a technical background, but this soft requirement should not let the reader become reluctant in learning about Bitcoin at a deep level.

The ideal state of this document is to become an authoritative resource and practical guide for software engineers that want to build applications with Bitcoin. Any suggestions to reach that state are highly appreciated. To follow the progress of this document, please refer to the git respository.

The following resources are an excellent starting point:

Bryan Bishop’s Papers

Bryan Bishop’s Transcripts

Learning Bitcoin from the Command Line

Jameson Lopp’s Bitcoin Information & Resources

Jashmenn’s Bitcoin Reading List

A Bitcoin Script Reading List.

The following resources are structured:

Smart Contracts and Blockchain Security

Cryptocurrency Security

MIT DCI online course

Scaling Bitcoin Dev++

Strongly recommend these Chaincode resources:

Chaincode Study Groups

Chaincode Bitcoin Course

Chaincode Lightning Course

Of course, a link to the whitepaper.


An overview of the Bitcoin protocol and the building blocks of Bitcoin.Protocol Documentation

Ultimately, the behavior of Bitcoin is defined by codebase of the reference client. This is not a complete survey of the bitcoin protocol, but a piecemeal overview of different components that make up Bitcoin.

The reference client, Bitcoin Core, was originally written by Satoshi, but has since been an open source project. The C++ client is the most widely used implementation of Bitcoin.1 One of the primary reasons to run the Bitcoin Core client is to stay in consensus with the rest of the network. There is no formal specification of consensus, so consensus is adopted by running the reference client. There are several noteable alternative implementations of Bitcoin, but their usage as consensus daemon are limited. An argument against adopting other implementations is the risk of breaking consensus with the network.



Hashes are one-way functions that accept an input and return a fixed-length value. For the hash function to have integrity, the value returned must be unique. As a result, a strong hash function will make it unlikely that two different inptus have the same output. This is called a hash collision.

In Bitcoin, SHA-256 and RIPEMD-160 are used. It is common to see double hashing where an input is hashed twice.

Merkle Trees

A merkle tree is a binary tree of hashes. It is a container that hashes items and concatenates the hashes in such a way that a final merkle root of the tree is a hash. This merkle root represents the the hashes and concatenation of all the items in the tree.

In Bitcoin, merkle trees are used in a variety of ways. Most notably, a block will have a merkle root of transactions. An excellent utility of merkle trees is proving that a leaf is part of the tree.


Digital signatures are used by a verifier to prove that a signature belongs to a public key. Signatures can only be created using a private key corresponding to the public key.

Bitcoin uses ECDSA, or Ellipitic Curve Digital Signature Algorithm, to sign for transactions and messages. The curve used is secp256k1.


Bitcoin addresses are a human readable format to represent a Bitcoin script. Addresses can be shared to others to receive payment. They should be treated as single-use tokens.




The consensus of Bitcoin is a large topic and part of extensive research.

A quick glimpse into how difficult it is to describe consensus can be found in David Harding’s Bitcoin Paper Errata and Details document. The expectations of the software developer often does not match the reality of the code written. Ultimately, consensus is defined by the software that people choose to run on their machines. This software can have bugs and these bugs are technically part of consensus.

There is also social consensus, the ideas and narratives that people choose to adopt and identify with. Social consensus can drive technical consensus to adopt new rulesets.


Segregated Witness


Notes on BIP340-342. All things concerning Schnorr, Taproot, and Tapscript.


Slides from Sipa's talk at SF Bitcoin Devs

Taproot Workshop

Taproot Review

immediate benefit of taproot: “if you lose this key, your funds are gone” to “if you lose this key, you’ll have to recover 3 of your 5 backup keys that you sent to trusted friends, and pay a little more, but you won’t have lost your funds”" - anthony towns

Notation to be used throughout (from BIP):


Link to BIP340

Why only x-pubkey?

Proposes standard for 64-byte Schnorr signatures.

Why Schnorr?

Encoding: Instead of DER, use fixed 64-byte format. Public Key Encoding: Instead of compressed 33-byte key, use 32 bytes.

Interestingly, the aim of the BIP is to have the Schnorr spec completely specified. In the past, different ECDSA implementations caused issues.

SuredBits’ intro to Schnorr

“tweaking” involves hiding/obfuscation

security of blind discrete log signatures

generalized bday problem

x-only pubkeys

lattice attacks against weak ECDSA

A schnorr signature is defined as the following: S = R + H(x(R)|P|m) * P where R is the Nonce point (k*G)

To save 32 bytes, only the x value of R is provided by the signer. The verifier can computer the y-value.

One of the y-coordinates is even while the other is odd.

Proposal constraints k such that y-value of R is quadratic residue module SECP256K1_FIELD_SIZE. Quadaratic residue is having a square root modulo the field size.

If a randomly generated nonce k does not yield a valid nonce point R, then the signer can negate k to obtain a valid nonce.


Link to BIP341

Proposes new SegWit v1 output type with spending rules based on Taproot, Schnorr, and merkle branches.

BIP claims no new security assumptions are added.

The aims of the output type is to improve privacy, efficiency, and flexibility of Bitcoin script. This is especially useful in minimizing how much information is shown on the blockchain regarding the spendability conditions. Additionally, a few bug fixes are included.

The BIP is very selective in the technologies that are included. Many are swept for later review in order to reduce complexity of review as well as prevent immature technology from weighind down ready technology.

From the BIP document, the following technologies compose the proposal:

Key aggregation allows a public key to be constructed from multiple participant keys. Indistinguishable from single-party.

BIP can be informally summarized in the following way:

a new witness version is added (version 1), whose programs consist of 32-byte encodings of points Q. Q is computed as P + hash(P||m)G for a public key P, and the root m of a Merkle tree whose leaves consist of a version number and a script. These outputs can be spent directly by providing a signature for Q, or indirectly by revealing P, the script and leaf version, inputs that satisfy the script, and a Merkle path that proves Q committed to that leaf. All hashes in this construction (the hash for computing Q from P, the hashes inside the Merkle tree's inner nodes, and the signature hashes used) are tagged to guarantee domain separation.

A taproot output is a native SegWit output with version number 1 and a 32-byte witness program.

Every taproot output corresponds to a combination of a single public key condition (internal key), and zero or more general conditions encoded in scripts in a tree.

General guidelines for construction and spending Taproot outputs:

Q=P+H(P,m)*G where P is public key and m is merkle root of a MAST.

switchable scripting


Link to BIP342

Proposes semantics of the scripting system described in BIP341.

Includes improvements to schnorr signatures, batch validation, and signature hash.

OP_CHECKSIG and OP_CHECKSIGVERIFY are modified to verify schnorr signatures. OP_CODESEPARATOR simplified.

OP_CHECKMULITSIG and OP_CHECKMULTISIGVERIFY are disabled. OP_CHECKSIGADD is introduced to make multisigs batch-verifiable.

A potential malleability vector is eleminated by requiring MINIMALIF. Using a non-standard represetentation of true for OP_IF is now considered invalid as a violation of consensus rules.

OP_SUCCESS opcodes allows introducing new opcodes cleanly than through OP_NOP.

Tapscript can be upgraded through soft forks by defining unknown key types. For example, adding a new hash_types or signature algorithms.


Schnorr multi-signature scheme.

Blockstream announcing MuSig.

actual whitepaper

SuredBits’ blog on musig

Insecure Shortcuts in MuSig

MuSig-DN: Deterministic Nonces

MuSig Interactivity

The Soundness of MuSig

  1. MuSig2

    Exchanging nonce commitments is the subject of the MuSig-DN paper.

    Nonce commitment exchange can be removed by generating the nonce deterministically from the signers’ public keys and message. Providing a non-interactive zk proof that the nonce was generated deterministically along with the nonce.

    The MuSig2 scheme has a two round signing protocol w/o the need for a sk proof. Also, the first round of the nonce exchange is done at key setup time.

    Therefore, there are two variants: interactive setup and non-interactive setup.

    BitcionOps explains MuSig2



proposed bip

a new type of public key for tapscript (bip-tapscript) transactions. It allows signatures for these public keys to not commit to the exact output being spent. This enables dynamic binding of transactions to different UTXOs, provided they have compatible scripts.

Allows dynamic rebinding of a signed transaction to another previous output of the same value


All things Bitcoin mining.


Excellent podcast on mining

cgminer is open source miner for ASIC/FPGA miner. Lots of companies forked off this original miner.

channel payouts in mining


Getblocktemplate: bitcoin core <-> pool server


Stratum: pool server <-> asic controller

Stratum Protocol documentation

The design of the Stratum protocol requires pool operators to build and distribute block templates to their clients.


StratumV2 Migration


link to bip

betterhash overview

Compact Blocks

faq for compact blocks Compact block relay, BIP152, is a method of reducing the amount of bandwidth used to propagate new blocks to full nodes.

Using simple techniques it is possible to reduce the amount of bandwidth necessary to propagate new blocks to full nodes when they already share much of the same mempool contents. Peers send compact block “sketches” to receiving peers.


P2P layer of Bitcoin. For the Bitcoin network to remain in consensus, the network of nodes must not be partitioned. So for an individual node to remain in consensus with the network, it must have at least one connection to that network of peers that share its consensus rules.

partition resistance

Wallet Engineering

Wallet Design concerns all things related to wallet functionality. This mostly is application level logic.

Modern bitcoin wallets are known as HD wallets or hierarchical deterministic. An HD wallet has a seed and can derive many child keys from a single key. In the early development of bitcoin, wallets would generate a new key for each receive address and then save the key to a file. This unfortunately made backups difficult and error prone. Instead, HD wallets can be backed up using a seed. The familiar 12 or 24 word mnemonic seed phrases are an artifact part of BIP39.


Wallets derive a number of child keys from a parent key. To prevent relying on only the key, both private and public keys are extended with an extra 32 bytes of entropy. This entropy is called the chain code.

There are 2^31 child keys and 2^31 hardened child keys. The distinction is very important.

Deep Dive on Extended Keys

A derivation path is the descriptor for identifying the path along the BIP32 tree.


Wallet Standards

Due to the flexibility of BIP32 trees, standards were created for wallet operators. Standards for the BIP32 tree allows for saner backups and easier portability of seeds between wallet services.


The first of these standards is BIP-43 which defines the first level of the BIP32 tree as the purpose field.


BIP-44 expands on BIP-43 by specifying the coin and account levels of the BIP32 tree. In addition, the derivation path can describe whether the wallet should derive a change (or internal) address or receive (or external) address.





Since SegWit, couple of changes to wallets were needed:SegWit wallet dev guide

One of the immediate problems that SegWit solves is mitigating transaction malleability.


A covenant is a bitcoin script that restricts the type of transaction that can spend a coin.

Greg Maxwell’s Bitcoin Talk thread on covenants

OP_CAT and Schnorr - Part 1

OP_CAT and Schnorr - Part 2


Vaults without Covenantsmore by bishop

proof of reserves - blockstream

BIP-127 proposes a standard way to do proof of reserves using a PSBT to bip

There’s rust implementation of a Proof-of-Reserves Client. link to reserves

custody protocols using bitcoin vaults


Payment batching, more here, is including multiple payments inside a single transaction.

Variables to consider are # of inputs and # of outputs. Better to have a single input and many outputs. It is also nice to have a lower fee for the entire transaction.

Goal of batching is to lower vbytes per payment. Marginal improvmenent after 1 input and 5 outputs.

Coin Selection

Challenges of coin selection by lopp iohk on coinsel what is coinsel? murch transcript at scaling

bitcoinedge++ transcript

The naive approach would be to simply look for the smallest output that is larger than the amount you want to spend and use it, otherwise start adding the next largest outputs until you have enough outputs to meet the spend target. However, this leads to fracturing of outputs until the wallet becomes littered with unspendable “dust.”

“Our idea is to have the user the option (either global or per account or per transaction) to choose between”maximize privacy" or “minimize fees” (or even maybe “minimize UTXO”

”Dust” refers to transaction outputs that are less valuable than three times the mininum transaction fee and are therefore expensive to spend.

A transaction output is labeled as dust when its value is similar to the cost of spending it. Precisely, Bitcoin Core sets the dust limit to a value where spending an 2.3. Transactions 7 output would exceed 1/3 of its value. This calculation is based on the minimum relay transaction fee, a node setting that causes transactions that don’t at least include this lower bound of fee to be dropped from the memory pool, and not relayed to other nodes. With the default for the minimum relay transaction fee set to 1 000 satoshi per kilobyte, and the sizes of a P2PKH input being 148 bytes, and an output being 34 bytes, this computes to all outputs smaller or equal to 546 satoshis being considered dust by Bitcoin Core [Erha15].

utxo mgmt for enterprise wallets

Bitcoin Core Wallet

Bitcoin Core’s wallet is always evolving. Some changes to the Bitcoin Core wallet: Wallet Class Structure Changes Sipa describing wallet changes Wallet Architecture transcripts What’s Coming to Bitcoin Core Wallet in 2021 Descriptor Wallets MD


Bitcoin Issue 17190 Electrum on Descriptors Descriptors Overview coredev talk

Implementations… HWI Bitcoin #16528 Bitcoin Core parsing Bitcoin #15764


( Each transaction input has a sequence number. In a normal transaction that just moves value around, the sequence numbers are all UINT_MAX and the lock time is zero. If the lock time has not yet been reached, but all the sequence numbers are UINT_MAX, the transaction is also considered final.

Sequence numbers can be used to issue new versions of a transaction without invalidating other inputs signatures, e.g., in the case where each input on a transaction comes from a different party, each input may start with a sequence number of zero, and those numbers can be incremented independently.

Signature checking is flexible because the form of transaction that is signed can be controlled through the use of SIGHASH flags, which are stuck on the end of a signature. In this way, contracts can be constructed in which each party signs only a part of it, allowing other parts to be changed without their involvement. The SIGHASH flags have two parts, a mode and the ANYONECANPAY modifier:

  1. SIGHASH_ALL: This is the default. It indicates that everything about the transaction is signed, except for the input scripts. Signing the input scripts as well would obviously make it impossible to construct a transaction, so they are always blanked out. Note, though, that other properties of the input, like the connected output and sequence numbers, are signed; it’s only the scripts that are not. Intuitively, it means “I agree to put my money in, if everyone puts their money in and the outputs are this”.
  1. SIGHASH_NONE: The outputs are not signed and can be anything. Use this to indicate “I agree to put my money in, as long as everyone puts their money in, but I don’t care what’s done with the output”. This mode allows others to update the transaction by changing their inputs sequence numbers.
  1. SIGHASH_SINGLE: Like SIGHASH_NONE, the inputs are signed, but the sequence numbers are blanked, so others can create new versions of the transaction. However, the only output that is signed is the one at the same position as the input. Use this to indicate “I agree, as long as my output is what I want; I don’t care about the others”.

There are two general patterns for safely creating contracts:

  1. Transactions are passed around outside of the P2P network, in partially-complete or invalid forms.
  1. Two transactions are used: one (the contract) is created and signed but not broadcast right away. Instead, the other transaction (the payment) is broadcast after the contract is agreed to lock in the money, and then the contract is broadcast.

This is to ensure that people always know what they are agreeing to. Together, these features let us build interesting new financial tools on top of the block chain.

It may even be that people find themselves working for the programs because they need the money, rather than programs working for the people.

old oracle services…

  1. Scriptless Scripts

    SuredBits’ blog on scriptless scripts

    Poelstra ppt

Fee Estimation

lopp on fee estimation

Fee estimation is the process of estimating a particular fee rate to use for a transaction in order to incentivize block inclusion at a particular block target.

Supply (blocks) and demand (txns) are unpredicable.

John Newbery’s intro to Bitcoin Core Fee Estimation pt2

  1. Outline of Newbery’s post

    At broadcast, the transaction is not going to get into the next block. But rather likely the next block in 10 minutes. Block production follows Poisson distribution.

    As a result, the fee rate should be competitive not only of the current mempool but the likely mempool in ten minutes.

    Looking only at mempool does not consider lucky block runs.

  1. Bitcoin Core’s Fee Estimation Also, the following is recorded:

    High level desc of Bitcoin Core’s fee estimation algorithmcode Bitcoin core groups transaction fee rates into buckets. Each buck is a range of fee rates. A track of block targets from 1 block to 1008 blocks is kept.

    1. number of transactions that entered the mempool in each fee rate bucket.
    1. for each bucket-target pair, the number of transactions that were included in a block within the target number of blocks.

    For any target-bucket pair, Bitcoin Core can find the probability that a transaction with the fee rate can be included. This is B/A.

    Additional overview

  1. Mempool File Format

    Mempool File Format can be useful for fee by kalle Time series of a txn lifecyle until block inclusion in a small file format.

  1. Light Clients

    Using AI for Fee Estimation

Backup and Recovery


US NIST recommends a salt length of 128 bits. Passphrase entropy in bits is log2(# of combinations).

BIP39 Wordlist is 2048 word dictionary. So log2(2048^s) = 22 bits of entropy.

Shamir’s Secret Sharing

3Shamir’s Secret Sharing (SSS) is an algorithm to divide a secret into parts that can be recovered by combining a minimum number of parts.

Each part is called a share. The threshold is the number of shares that is needed to recover the original secret. There can be more shares than the threshold.

There are several criticisms of SSS.

  1. Shamir Secret Snakeoil
  1. Shamir’s Secret Sharing Shortcomings

Sharding vs Multisig?

Lightning Network

Lightning Network and related off-chain protocols.

A few exceptional resources to get started:

Master Lightning Book Lightning Overview t-bast’s notes

Lightning Network is a scaling solution to keep most transactions off-chain while leveraging the security of the bitcoin chain as an arbitration layer. There are several concepts to review before jumping into the domain. We will start small by covering lightning primitives, then apply these primitives to describe the Lightning Network.

Payments channels is a construct between two parties that commit funds and pay each other by updating a balance redeemable by either party. Moving funds between each part is near instant. Channels have a total capacity that is established by the on-chain funding transaction. Additionally, each party in the channel has their own balance. For example, a channel between Alice and Bob can have a 1 BTC capacity, but 30% of the bitcoin is owned by Bob. For Alice, this means that her local_balance is 0.7 BTC while the remote_balance (Bob’s balance) is 0.3 BTC.

To create the payment channel construction, a funding transaction is created on-chain. Any updates to the channel involves updating the commitment transaction.

Hash Time-Locked Contracts (HTLCs) allow transactions to be sent between parties who do not have a direct channels by routing it through multiple hops, so anyone connected to the Lightning Network is part of a single, interconnected global financial system.

Payment channels are the main workhorse of the Lightning Network. They allow multiple transactions to be aggregated into just a few on-chain transactions. In the vast majority of cases, someone only needs to broadcast the first and last transaction in the channel.

channel updates

Payment channels & revocable transactionsgreat graphical overview

txn: Bob’s signature and a relative timelock (Bob’s spend branch); or Alice’s signature and a secret revocation hash provided by Bob (Alice’s revocation branch).

usually have multiple utxos. Once bob reveals his secret, alice can collect her spend TXO and rTXO.

revocable transaction script_pub_key: OP_IF # Bob’s spend branch - after the revocation timeout duration, Bob can spend with just his signature OP_CHECKSEQUENCEVERIFY OP_DROP <Bob’s public key> OP_ELSE # Revocation branch - once the revocation pre-image is revealed, Alice can spend immediately with her signature OP_HASH160 <h(rev)> OP_EQUALVERIFY OP_DROP <Alice’s public key> OP_ENDIF OP_CHECKSIG

recovcation keys used base points and blinding key. similar to bip32, keys derived using base key.

revocable transactionsHTLCs

enterprise lightning presentation


great overview of BOLT by Jim Posen how onion routing works with HTLCs presentation by Rene

BOLT is the Basics of Lightning Technology.

The BOLT repo found here describes the specification for the Lightning Network.

  1. BOLT #0

    Provides a basic glossary defining terminology that is used throughout the rest of the specification.

  1. BOLT #1

    Describes the base message protocol including the TLV format and the setup messages.

    TLV is Type-Length-Value.

    Funny enough, the unicode code point for lightning is 0x2607. In decimal, 9735 which is also the default TCP port.

  1. BOLT #2

    Contains peer channel protocol lifecycle.

    A channel_id is used to identify a channel. channel_id = XOR(funding_txid, funding_output_index)

    Before a channel is created, a temporary_channel_id is used which acts a nonce. This nonce is local and can be duplicate across the rest of the protocol.

    1. Channel Establishment
    1. Channel Close
    1. Normal Operation

      Once both nodes have exchanged funding_locked, the channel is used to make payments with HTLCs.

  1. BOLT #3

    Describes transaction and script formats.

  1. BOLT #4
  1. BOLT #5

    Channels can end with a mutual close, unilateral close, or a revoked transaction close.

    In a mutual close, local and remote nodes agree to close. They generate a closing transaction.

    In a unilateral close, one side publishes its latest commitment transaction.

    In a revoked transaction close, one party is cheating and publishes an oudated commitment transaction.

    A commitment transaction has up to six types of outputs:

    1. local node’s main output: Zero or one output, to pay to the local node’s delayed_pubkey.
    1. remote node’s main output: Zero or one output, to pay to the remote node’s delayed_pubkey.
    1. local node’s anchor output: one output paying to the local node’s funding_pubkey.
    1. remote node’s anchor output: one output paying to the remote node’s funding_pubkey.
    1. local node’s offered HTLCs: Zero or more pending payments (HTLCs), to pay the remote node in return for a payment preimage.
    1. remote node’s offered HTLCs: Zero or more pending payments (HTLCs), to pay the local node in return for a payment preimage.

    If the local node publishes its commitment transaction, it will have to wait to claim its own funds, whereas the remote node will have immediate access to its own funds.

  1. BOLT #7


  1. BOLT #8
  1. BOLT #9
  1. BOLT #10
  1. BOLT #11

    Invoice spec.

  1. WIP: BOLT #12

    BOLT 12 describes a new invoice format and flow called Offers.

    The Draft of the PR can be found here.

    The flow described is the following:

    1. Receiver publishes an offer.
    1. Payer requests a new unique invoice over LN using the offer.
    1. Receiver responds with a unique invoice.
    1. Payer pays the invoice.

    There are a number of improvements over BOLT11.

    Payment proof is designed to allow the payer to prove that they were the unique payer.

    Merkle tree is used to be able to prove only specific fields of the invoice, not the enture invoice!

    Some offers are periodic, meaning that payments are expected on a recurring period. This allows for new applications that require subscription-based payments.


There are several implementations following the BOLT specification.

  1. LND

    Exploring LND 0.4 LND 0.6-Beta

anecdotal example

Suppose Alice has a channel with Bob, who has a channel with Carol, who has a channel with Dave: A<->B<->C<->D. How can Alice pay Dave? Alice first notifies Dave that she wants to send him some money. In order for Dave to accept this payment, he must generate a random number R. He keeps R secret, but hashes it and gives the hash H to Alice.

Alice tells Bob: “I will pay you if you can produce the preimage of H within 3 days.” In particular, she signs a transaction where for the first three days after it is broadcast, only Bob can redeem it with knowledge of R, and afterwards it is redeemable only by Alice. This transaction is called a Hash Time-Locked Contract (HTLC) and allows Alice to make a conditional promise to Bob while ensuring that her funds will not be accidentally burned if Bob never learns what R is. She gives this signed transaction to Bob, but neither of them broadcast it, because they are expecting to clear it out later. Bob, knowing that he can pull funds from Alice if he knows R, now has no issue telling Carol: “I will pay you if you can produce the preimage of H within 2 days.” Carol does the same, making an HTLC that will pay Dave if Dave can produce R within 1 day. However, Dave does in fact know R. Because Dave is able to pull the desired amount from Carol, Dave can consider the payment from Alice completed. Now, he has no problem telling R to Carol and Bob so that they are able to collect their funds as well.

Alice knows that Bob can pull funds from her since he has R, so she tells Bob: “I’ll pay you, regardless of R, and in doing so we’ll terminate the HTLC so we can forget about R.” Bob does the same with Carol, and Carol with Dave.

Now, what if Dave is uncooperative and refuses to give R to Bob and Carol? Note that Dave must broadcast the transaction from Carol within 1 day, and in doing so must reveal R in order to redeem the funds. Bob and Carol can simply look at the blockchain to determine what R is and settle off-chain as well.

Lightning Conf 2019 Berlin

electrum slides on lightning Circular routes: send to self. Suggestions

Command line tools

Make Me an Offer (Bolt 12) introduced.


Hedging the Chain



htlcs are harmful

Discrete Log Contracts



securing lightning nodes by devrandomlink to the lightning-signer project on GitLabkey mgmt

blackmail attack

  1. LSAT

    Lightning Service Authentication Tokenlsat talk

    using macaroon based bearer API credential with lightning network payment

  1. Key management

    Overview of each key in the channel lifecycle.

    talk on key mgmt need onchain hot wallet to open channels (only need once)

    1 of 2 keys must be hot for the funding transaction. If counterparty gets key, funds are lossed. If 3rd party gets it, they must collude.

    Commitment secret: must be hot. Used to generate “local_pubkey” and “remote_pubkey” Used to derive subsequent secrets and public keys. If leaked, peer can steal all money in commitment txn.

    Revocation basepoint secret: can be cold. Used to claim peer funds if they try to cheat. Can be cold if accessible before “to_self_delay”

    If your counterparty gets access to this key, they can claim their funds in their to_local output immediately by circumventing the locktime

    Payment basepoint secret: claim money from the “to_remote” output on peer commitment txn. can be cold if peer gets access to this key, all funds can be taken in the “to_remote”.

    Delayed Payment Basepoint Secret: claim money on “to_local” output of commitment txn. can be cold.

    HTLC Basepoint Secret: secret needed to sign for HTLCs. must be hot.

    hosted channelsgist on hosted channels interesting idea but need to look more into security assumptions..


An Empirical Analysis of Privacy in the Lightning Network


Routing involves routing a lightning payment through either a public or private channel.

Routing is generally constructed for a specified payment amount. Other considerations, however, includes value of open channels, decision to make new channels, re-balancing decisions, multi-path payments or multi-part payments (MMP, formerly AMP).

amount independent routing

One of problem in routing is payment privacy. Two proposals to increase the privacy of paymnet senders and recipients are rendevous routing and route blinding.

  1. Rendezvous Routing

    Rendevous routing is a proposal aimed to protect the privacy of payments on the lightning network. In the initial proposal, an argument is made that private channels should not be revealed to payers. The solution is to have the payee choose one or more routes from certain third-party nodes on the public network to himself, and pass sphinx-encryped blogs for those routes to the payer. Then, the payer complets the route by finding routes from himself to the selected third-party nodes.

    Rendezvous mechanism on top of sphinx

  1. Route Blinding

    Route Blinding is currently a proposal that aims to provide recipient anonymity by blinding an arbitrary amount of hops at the end of an onion path. Like rendezvous routing, this proposal is aimed and hiding the final portion of the route from the sender. The recipient chooses an “introduction point” and a route to himself from that point. The recipient blinds each node and channel for that route with ECDH. This blinded route and a hop-binding secret are included in the invoice.

  1. Upfront Payments

    Jamming attacks are possible where an attack can delay a payment resolution and therefore lock bitcoin along a route for a period of time. This attack is described here.

    Fidelity Bonds are a solution to


Atomic Multi-path Payments (AMP)

Mailing List Discussion

Atomic multi-path payments allow a single logical payment to be sharded across multiple paths across the network. This is done at the sender side. Multiple subtransactions can be sent over the network and take their own paths and then the necessary constraint is that they all settle together. If one of the payments fails then we want them to all fail. This is where the atomicity comes in. This enables better usage of in-bound and out-bound liquidity. You can send payments over multiple routes, and this allows you to split up and use the network better. This is a more intuitive user experience because like a bitcoin wallet you expect to be able to send most of the money in your wallet. Without AMPs, this is difficult because you can only send a max amount based on current channel liquidity or something, which doesn't really make sense to a user.

Only the sender and receiver need to be aware of this technology.


Mailing List Discussion

With a splice-in, funds can be added to the channel, and they subsume an existing UTXO. And splice-out can remove funds from a participant balance and this creates a UTXO. You can take what's in the channel, splice it off to an address that a person I'm trying to pay controls.

This removes the concept of my "funds are locked in the lightning network" because now you can do both on-chain payments into a channel and you can also do a payment out of a channel without interrupting the normal operation of the channel.

Submarine Swap

SF Bitcoin Devs Talk on Submarine Swaps

Submarine swaps allow you to pay someone on-chain and have the payment to them be contingent on them paying a Lightning invoice you give them. If they don't pay the invoice, after a timeout you can get your money back.

Hold Invoices

LND implementation

Instead of immediately locking in and settling the htlc when the payment arrives, the htlc for a hold invoice is only locked in and not yet settled. At that point, it is not possible anymore for the sender to revoke the payment, but the receiver still can choose whether to settle or cancel the htlc and invoice.

Trampoline Payments

Lightning network currently relies on source routing where sender calculates the route. Sender needs to maintain graph state.

Trampoline payments is a new suggested way of outsourcing that aims at having lite clients outsourcing the route computation to trampoline nodes, nodes of higher Memory, bandwidth and computation power.

design decisions on trampoline routing

Static/Send/Spontaneous/Push Payments

Wow, lots of names for an overlapping concept.

OffersStatic PaymentsPush Invoices


HTLCs..Hashed Time Lock Contracts.

The initiator of a Lightning channel pays the closing fee. Lots of HTLCs = large fee. See thread.

Thread on free HTLC forwarding

An interesting idea to handling the edge cases around HTLCs is to have a firewall. An example.


Payment Pointsexcellent SuredBits blog on PTLCs


challenges and opportunites for ln 2

Why We Fail Lightning


The challenges of operating a lightning node deserves its own section. The lightning domain is distinct from on-chain bitcoin due to its own security assumptions, state changes, and end-user experience.

The most immediate concern is backup maintance. With on-chain bitcoin, one can is familiar with BIP39 mnemonic seed phrases as the ultimate backup for bitcoin. In lightning, the backup file is responsible for channels. Do not take backups of channel state itself. Inaccurate or revoked channel state is can lead to a justice transaction and punishment (loss of all funds in the channel). As a result, backups are tricky in lightning.

Static channel backups (SCBs) are the best backups for lightning node operators. The backups are called static because they are only obtained once - when the channel is created. Afterwards, the backup is valid until the channel is closed. A SCB allows a node operator to recover funds that are fully settled in a channel. Fully settled funds are bitcoin in commitment outputs, but not HLTCS.

LND Recovery DocumentationLND PR#2313Automating channel backups for LNDSubscribe to channel backups for LND

In addition to backups, channel management is a large area of focus. A node operator wants to be connected to reliable and honest peers. Factors to consider are uptime, balance, and cost of rebalancing. It is convenient to create a list of decent nodes and maintain a relationship with them. For inbound liquidity, swaps can be used or swap services like Lightning Labs Loop. Loop can be used to refill channels. Managing incoming channel requests can be important in order to prevent undesirable peers. For example, setting a threshold for channel capacity can prevent dust limit problems in the future. It is better to have fewer channels that are well capitalized than many channels with poor capacity.

Watchtowers can be used to monitor private nodes.



Privacy and techniques used in chain-analysis.

Privacy Wiki

snowball presentation at ldn bitdevs

common input hueristic: “different public keys used as inputs to a transaction as being controlled by the same user”original paper on blockchain analysis

coin join wiki

Bitcoin vs “privacy coins”


“So a world where”basically everyone uses CoinJoin" is cool for privacy, but could end up pretty bad for scalability, because these transactions are in addition to the normal payments." - waxwing

  1. PayJoin

    payjoin by waxwing PayJoin is coinjoin + payment

    “Let Bob do a CoinJoin with his customer Alice - he’ll provide at least one utxo as input, and that/those utxos will be consumed, meaning that in net, he will have no more utxos after the transaction than before, and an obfuscation of ownership of the inputs will have happened without it looking different from an ordinary payment.”

    “the main point is with PayJoin - we break the heuristic without flagging to the external observer that the breakage has occurred.” … unlike coinjoins

    “snowball effect” … payjoin/p2ep reduces utxo set and receiver’s utxo gets bigger after each payment txn.

    who pays for the fee? “every payment to the merchant creates a utxo, and every one of those must be paid for in fees when consumed in some transaction.”

    real world implementation is samourai wallet

    join market

  1. Pay To EndPoint (P2EP)

    p2ep blockstream “The basic premise of P2EP is that both Sender and Receiver contribute inputs to a transaction via interactions coordinated by an endpoint the Receiver presents using a BIP 21 compliant URI.”


    1. Receiver generates a BIP 21 formatted URI with an additional parameter that specifies their P2EP endpoint.
    1. The Sender initiates interaction with the Receiver by confirming that the endpoint provided is available. If not, the transaction is broadcast normally, paying to the Receiver’s BIP 21 regular Bitcoin address. If the Receiver’s endpoint is available, the Sender provides a signed transaction to the Receiver as proof of UTXO ownership.
    1. The Receiver then sends a number of transactions to the Sender for them to sign. Out of these transactions, only one includes a UTXO that is actually the owned by the Receiver, the rest can be selected from the pool of spendable UTXOs.
    1. Receiver obtains a signed transaction that corresponds to their UTXO they can sign and broadcast the transaction, which will now contain inputs from both the Sender and the Receiver.

    Example: If Alice wants to pay Bob 1 BTC:

    1. Alice inputs 3 BTC to a transaction.
    1. Bob inputs 5 BTC to the same transaction.
    1. Alice receives 2 BTC (as her change).
    1. Bob receives 6 BTC (as his change, plus the 1 BTC payment from Alice).

    Disadvantages: Receiver and Sender must be online. Interactive. More Cons/Pros listed in blogpost.


link to bip


maxwell on coinswapswaxwing on coinswaps

“We can use a cryptographic commitment scheme to create atomicity that binds two, independent Bitcoin transactions”

Make a random x, hash it. Make a p2sh output that is spendable with proving hash(x) is hash in scriptpubkey and pubkey owns output.

Other party can see x and then solve for their p2sh with their pubkey.

great explainer on cross-chain swaps

problem here is that x is revealed and a connection exists between both parties.

HTLCs with presigned transactions can help avoid revealing x.htlcs wiki

“An advantage of Coinswap over Coinjoin is a potentially bigger anonymity set (a lot more could be said)”

visual guide


new coinswap implementation


waxwing on tumblebitoriginal paper

“A blind signature is allows a central authority to sign data which is hidden from them”

“Chaumian cash” is a central mint authorised to blind-sign transfers of this cash

" At a very high level, it’s using commitments - I promise to have X data, by passing over a hashed or encrypted version, but I’m not yet giving it to you - and interactivity - two-way messaging, in particular allowing commitments to occur in both directions."

blind signatures


link to bip

SNICKER (Simple Non-Interactive Coinjoin with Keys for Encryption Reused)

allowing the creation of a two party coinjoin without any synchronisation or interaction between the participants.


dev mailing list

More Cryptography

  1. Adaptor Signatures

    explainer using atomic swaps “An”adaptor signature" is a not a full, valid signature on a message with your key, but functions as a kind of “promise” that a signature you agree to publish will reveal a secret, or equivalently, allows creation of a valid signature on your key for anyone possessing that secret."

  1. Schnorr

    waxwing on schnorr sigsscriptless scripts and schnorr

    multiparty schnorr coinshuffle

  1. Ring Signatures

    waxwing on ring sigs

Chain Analysis

Peel chains are strings of transactions commonly used for money laundering, in which entities send funds through several wallets in quick succession, usually breaking off small amounts to cash out at each step and sending the majority on to the next wallet.


Security related information.

Everything is Broken

Bitcoin is Improving

Identifying Key Leakage in Bitcoin

Hardware Wallets

List of Hardware Wallet Hacks

Remote MultiSig Theft Attack on ColdcardKey Exfiltration


Selfish mining attack is when a miner withholds a valid and worked block, and begin mining the next block. The miner has an edge over the network if they withhold the block and attempt to work on the next block.

Bitcoin Core

Notes on Bitcoin Core architecture and development.


debug wiki

LogPrintf("") cat debug.log | grep @@@

lldb src/bitcoind

unit tests in src/test/ using BOOST lib test framework.

Run just one test file: src/test/test_bitcoin –log_level=all –run_test=getarg_tests Run just one test: src/test/test_bitcoin –log_level=all –run_test=*/the_one_test

Logging from unit tests… BOOST_TEST_MESSAGE(“@@@”);

functional tests in test/functional using python –loglevel=debug self.log.debug(“bar”)

Use –tracerpc to see the log outputs from the RPCs of the different nodes running in the functional test in std::out.

on testson unit testson functional tests

core review tools


overview of arch


wallet dev presentation by John Newbery CPubKey - a public key, used to verify signatures. A point on the secp256k1 curve. CKey - an encapsulated private key. Used to sign data. CKeyID - a key identifier, which is the RIPEMD160(SHA256(pubkey)) CTxDestination - a txout script template with a specific destination. Stored as a varint variable

Wallet component is intialized through the WalletInitInterface. For builds with wallet, the interface is overrridden in src/wallet/init.cpp

For –disable-wallet, there is DummyWalletInit

initiation interface methods are called during node initialization

During loading… WalletInit::Construct() adds a client interface to the wallet. Node then tells wallet to load/start/stop/etc through the ChainClient interface in src/interfaces/wallet.cpp Most methods in that interface call through to functions in src/wallet/load.cpp

Node <> Wallet Interface Node holds a WAlletImpl interface to call functions on the wallet. Wallet holds a ChainImpl interface to call functions on the node. Notifications handler Node notifies the wallet about new transactions and blocks through the CValidationInterface

Identifying Transactions When a transaction is added to the mempool or block is “connected”, the wallet is notified through CValidationInterface. SyncTransaction() … calls AddToWalletIfInvolvingMe() IsMine() : takes the scriptPubKey, interprets it as a Destination type, and then checks whether we have the key(s) to watch/spend.

Generate Keys Originally a collection of unrelated private keys. Keypools introduced in 2010 by Satoshi. Cache 100 private keys. When a new key is needed, draw it from keypool and refresh. HD wallets introduced to Bitcoin Core in 2016. Keypool essentially became an address lock-ahead pool. It is used to implement a ‘gap limit’.

Constructing Transactions sendtoaddress sendtomany {create,fund,sign,send}rawtransaction The address is decoded into a CDestination. Other parameters can be added for finer control (RBF, fees, etc). Wallet creates the transaction in CreateTransaction().

Coin Selection By default, coin selection is automatic. Logic starts in CWallet:SelectCoins(). By preference, we choose coins with more confirmations. Manual coin selection (coin control) is possible in CCoinControl.

Signing Inputs Last step in CreateTransaction() CWallet is an implementation of SigningProvider interface. Signing logic for the SigningProvider is all in src/script/sign.cpp.

Sending Transactions Wallet saves and broadcats the wallet in CommitTransaction() submitToMemoryPool(), relayTransaction()


Bitcoin history and misc. trivia items.

Bitcoin’s Academic Pedigree

b10c’s Incomplete History of Bitcoin Development

History of segwit activation

History of P2SH


Notes that do not fit neatly in the other categories.

Merkelized Abstract Syntax Trees are a general concept: when bitcoin developers talk about it, they’re talking about reworking bitcoin scripts into a series of “OR” branches, and instead of the output committing to the whole script, you commit to the head of the tree.  To spend it, you only need to provide the branch of the script you’re using, and the hashes of the other branches. This can improve privacy, and also shrink the total size of large scripts, particularly if there’s a short, common case, and a long, complex rare case. Note that each key is 33 bytes and each signature about 72 bytes, and each merkle branch only 32 bytes.

Sidechains are based on cross-chain consensus validation through SPV and reorganization proofs (an idea that dates back to my P2PTradeX protocol), while drivechains are based on miners being consensus proxies.

The idea behind JoinMarket is to help create a special kind of bitcoin transaction called a CoinJoin transaction. It’s aim is to improve the confidentiality and privacy of bitcoin transactions, as well as improve the capacity of the blockchain therefore reduce costs. The concept has enormous potential, but had not seen much usage despite the multiple projects that implement it. This is probably because the incentive structure was not right. A CoinJoin transaction requires other people to take part. The right resources (coins) have to be in the right place, at the right time, in the right quantity. This isn’t a software or tech problem, its an economic problem. JoinMarket works by creating a new kind of market that would allocate these resources in the best way.

Merged mining is the act of using work done on another block chain (the Parent) on one or more Auxiliary block chains and to accept it as valid on its own chain, using Auxiliary Proof-of-Work (AuxPoW), which is the relationship between two block chains for one to trust the other’s work as their own. The Parent block chain does not need to be aware of the AuxPoW logic as blocks submitted to it are still valid blocks.

Future directions of bitcoin

transcript Schnorr Signature Scheme

SIGHASH_NOINPUT - sign scripts, not txid

Taproot basic idea-> tweak pubkey Q = P+H(P,S)G Q in output key spend sign(Q) script spend: P,S, inputs

Graftroot if a key exists to represent everyone use delegation instead of merkle tree inherently interactive key setup




The idea of graftroot is that in every contract there is a superset of people that can spend the money. In graftroot, if all the participants agree, then they can just spend. So they can do pubkey aggregation on P

Taproot: P = c + H(c || script) G

Graftroot: sigp(script)

graftroot vs taproot


You get a serialized UTXO set snapshot obtained by a peer. This all hinges on a content-based hash of the UTXO set. The peer gets headers chain, ensures base of snapshot in chain, load snapshot. They want to verify the base of the snapshot or the blockhash is in the header chain. We load the snapshot which deserializes a bunch of coins and loads it into memory. Then we fake a blockchain; we have a chainstate but no blocks on disk, so it’s almost like a big pruned chain. We then validate that the hash of the UTXO set matches what we expected through some hardcoded assumeutxo. This is a compiled parameter value, it can’t be specified at runtime by the user which is very important. At that point, we sync the tip and that will be a similar delta to what assumevalid would be now, maybe more frequent because that would be nice. Crucially, we start background verification using a separate chainstate where we do regular initial block download, bnackfill that up to the base of the snapshot, and we compare that to the hash of the start of the snapshot and we verify on assumeutxo

bitcoin-dev email

The initializing node syncs the headers chain from the network, then obtains and loads one of these UTXO snapshots (i.e. a serialized version of the UTXO set bundled with the block header indicating its “base” and some other metadata).

hardcoded hashs exist in software ..hash(utxoset). similar to assumevalid.

snapshots can obtained in same manner as block download. Doesn’t matter about source cuz of content hash.


Applications of ZK Snarks… “. Instead of embedding the rules that govern an output inside the blockchain, you’d instead embed a proof that the rules were followed. Instead of everyone checking that a transaction was permitted to be spent, they’d instead check that you checked.” - Maxwell

coin witness

“You write down a small program which verifies the faithfulness of one of these transcripts for your chosen verifiable off-chain system. The program requires that the last transaction in the transcript is special in that it pays to a Bitcoin scrippubkey/p2sh. The same address must also be provided as a public input to the program. We call this program a”witness" because it will witness the transcript and accept if and only if the transcript is valid.

You then use the SCIP proof system to convert the program into a verifying key. When someone wants to create a Bitcoin in an off-chain system, they pay that coin to the hash of that verifying key. People then transact in the off-chain system as they wish. To be confident that the system works faithfully they could repeat the computationally-expensive verifying key generation process to confirm that it corresponds to the transaction rules they are expecting.

When a user of one of these coins wants to exit the system (to compact its history, to move to another system, to spend plain Bitcoins, or for any other reason), they form a final transaction paying to a Bitcoin address, and run the witness on their transcript under SCIP and produce a proof. They create a Bitcoin transaction redeeming the coin providing the proof in their script (but not the transcript, thats kept private), and the Bitcoin network validates the proof and the transaction output. The public learns nothing about the intermediate transactions, improving fungibility, but unlike other ideas which improve fungibility this idea has the potential to both improve Bitcoin’s scalability and securely integrate new and innovative alternative transaction methods and expand Bitcoin’s zero-trust nature to more types of transactions."


A covenant in its most general sense and historical sense, is a solemn promise to engage in or refrain from a specified action.maxwell on covenants

scaling bitcoin “Covenants can be recursively enforced down the chain for as long as you need to reinforce them.”

“Covenants can be used to break fungibility.”whitepaper

Bitcoin Covenants: Three Ways to Control the Future

Zero Knowledge Contigent Payment

zero knowledge payment ZKCP

swapping information for value

Discreet Log Contracts

WhitepaperDLC Spec


Analysis of the Bitcoin Blockchain.

At this momement, the size of the Bitcoin Blockchain is 300 GB. Dating back to 2009, there is a trove of interesting data on how users have used and continue to use Bitcoin’s chain as a settlement layer. Monitoring the chain is useful exercise to detect trends, understand second-order affects from technical changes, and satisfy the data-curious.

TxStats - Latest stats on Bitcoin transaction types

Johoe’s Bitcoin Mempool Statistics

Bitcoin Optech Dashboards

Bitcoin Monitoring - P2P

UTXO Stats

Mempool Observer