Please disable your adblock and script blockers to view this page

A from-scratch tour of Bitcoin in Python


Bitcoin
content).First
RSA
ECC
NIST
Generator
SHA-256
Bitcoin’s Proof of Work
ASICs
PublicKey
BTC
Coinbase
USD
Outputs
Transaction
UTXO
Unspent Transaction Output
Transactions
TxOuts
TxIn
Block Explorer
Elliptic Curve Cryptography
the Elliptic Curve Digital Signature Algorithm
ECDSA
Block 2005515
Blockstream
Block 2005671
DAG
SHA256


Jun 21
Python
Bitcoin
it.(btw
Andrea Corbellini’s
’d
Andrej
G. Notice
SHA256
mnNcaVkC35ezZSgvn8fhXEa9QTHSUtPfzQ
2NCorZJ6XfdimrFQuwWjcJhQJDxPqjNgLzG
Bitcoins
Satoshi
.encode
Mastering Bitcoin
Programming Bitcoin


OP_EQUALVERIFY
Kkthx!”We


Point

No matching tags


scratch?We
mnNcaVkC35ezZSgvn8fhXEa9QTHSUtPfzQ
OP_EQUALVERIFY
TxIns
Segwit

No matching tags

Positivity     44.00%   
   Negativity   56.00%
The New York Times
SOURCE: https://karpathy.github.io/2021/06/21/blockchain/
Write a review: Hacker News
Summary

In particular, it creates a fixed-sized, random-looking short digest of any variably-sized original message s.t. the scrambling is not invertible and also it is basically computationally impossible to construct a different message that hashes to any given digest.Bitcoin uses SHA256 everywhere to create hashes, and of course it is the core element in Bitcoin’s Proof of Work, where the goal is to modify the block of transactions until the whole thing hashes to a sufficiently low number (when the bytes of the digest are interpreted as a number). We are going to make this nice by creating a subclass of Point called PublicKey which is, again, just a Point on the Curve but now has some additional semantics and interpretation of a Bitcoin public key, together with some methods of encoding/decoding the key into bytes for communication in the Bitcoin protocol.We are not yet ready to take this class for a spin because you’ll note there is one more necessary dependency here, which is the b58 encoding function b58encode. This makes sense because if it did have any balance (in the naive case, modulo some subtleties with the scripting language we’ll go into) then anyone would just be able to spend it because they know secret key (1) and can use it to digitally sign transactions that spend it. Only the owner of the secret key will be able to both 1) provide the full public key, which will be checked to hash correctly, and 2) create the digital signature, as we’ll soon see.By the way, we can verify that of course our public key hashes correctly, so we’ll be able to include it in our upcoming transaction, and the all of the mining nodes will be able to verify condition (1). Very early Bitcoin transactions had locking scripts that directly contained the public key (instead of its hash) followed by OP_CHECKSIG, but doing it in this slightly more complex way protects the exact public key behind the hash, until the owner wants to spend the funds, only then do they reveal the public key. Every Input/Output of any bitcoin transaction must always be fully spent. The remainder will be the “change” (fee) that will be claimed by the winning miner who lucks out on the proof of work, and includes our transaction in their newly mined block.Let’s begin with the transaction input data structure:The first two variables (prev_tx, prev_index) identify a specific Output that we are going to spend. Anyway, in this case we are identifying the transaction that sent us the Bitcoins, and we’re saying that the Output we intend to spend is at the 1th index of it. This is where the digital signature will go, cryptographically signing the desired transaction with our private key and effectively saying “I approve this transaction as the possessor of the private key whose public key hashes to 4b3518229b0d3554fe7cd3796ade632aff3069d8”.sequence was in the original Bitcoin implementation from Satoshi and was intended to provide a type of “high frequency trade” functionality, but has very limited uses today and we’ll mostly ignore.Calculating the fee. The public key hash of the owner of the Output is sandwiched between a few Bitcoin Scripting Language op codes, which we’ll cover in a bit:We need to create this same structure and encode it into bytes, but we want to swap out the public key hash with the new owner’s hashes. Here it is:Ok we’re now going to effectively declare the owners of both outputs of our transaction by specifying the public key hashes (padded by the Script op codes). With the locking script specified as above, only the person who has the original public key (and its associated secret key) will be able to spend the UTXO.Now for the important part, we’re looping around to specifying the script_sig of the transaction input tx_in, which we skipped over above. In particular we are going to craft a digital signature that effectively says “I, the owner of the private key associated with the public key hash on the referenced transaction’s output’s locking script approve the spend of this UTXO as an input of this transaction”. As we did above, we will only cover the (by far) most common use case of signing the entire transaction and, and constructing the unlocking script specifically to only satisfy the locking script of the exact form above (OP_DUP, OP_HASH160, <hash>, OP_EQUALVERIFY, OP_CHECKSIG).First, we need to create a pure bytes “message” that we will be digitally signing. It is still missing our signature, which we are still trying to construct.Instead, when we are serializing the transaction input that we wish to sign, the rule is to replace the encoding of the script_sig (which we don’t have, because again we’re just trying to produce it…) with the script_pubkey of the transaction output this input is pointing back to. We then implement the serialization for the new Tx class, and also the serialization for TxIn and TxOut class, so we can serialize the entire transaction to bytes.Before we can call .encode on our Transaction object and get its content as bytes so we can sign it, we need to satisfy the Bitcoin rule where we replace the encoding of the script_sig (which we don’t have, because again we’re just trying to produce it…) with the script_pubkey of the transaction output this input is pointing back to. We are also identifying the exact outputs of this transaction (newly about to be minted UTXOs, so to speak) along with their script_pubkey fields, which in the most common case declare an owner of each output via their public key hash wrapped up in a Script. So what this message really encodes is just the inputs and the new outputs, their amounts, and their owners (via the locking scripts specifying the public key hash of each owner).We are now ready to digitally sign the message with our private key. For a reason that will become clear in a moment, it will contain exactly two elements: 1) the signature and 2) the public key, both encoded as bytes:Okay so now that we created both locking scripts (script_pubkey) and the unlocking scripts (script_sig) we can reflect briefly on how these two scripts interact in the Bitcoin scripting environment. We’re going to create a transaction with these two as inputs, and a single output into the third wallet mgh4VjZx5MpkHRis9mDsF2ZcKLdXoP3oQ4.

As said here by