How does a bitcoin transaction actually work?

I wrote this post for myself to understand how Bitcoin really works. I thought it may be helpful for others as well, but if I misstated anything I would love to understand what and why. My intent is to make this a series of posts about Bitcoin, eventually Ethereum, and perhaps others I find interesting.


Public/Private Key Pairs

To get started on the Bitcoin network, you first create a public/private key pair. Private keys are any 256-bit number, so you could come up with one on your own, download a program that randomly creates private keys or purchase a hard wallet such as Trezor or Ledger, which generates private keys based on a seed code. This one seed code generates infinitely many private keys, but all you have to remember is the seed code to access these private keys.

Your private key uses the Elliptic Curve Digital Signature Algorithm (ECDSA) to create a corresponding public key. The algorithm uses mathematical operations to change the 256-bit private key number into a corresponding string of numbers called the public key. You can always use the private key to create the public key, but you cannot use the public key and work backwards to get the private key. Public and private keys are used to encrypt and decrypt data. You can lock/encrypt data with a public key such that the only way to decrypt or unlock the data is with the corresponding private key that created the public key.

Digital Signatures

Bitcoin uses a process called Digital Signatures to validate authenticity of a transaction and the sender of that transaction. You use the public/private key pairs to digitally sign data in order to prove that the data has not been tampered with and validate that the data must have been send by the person who owns the private key to the given public key.

Step 1: The sender has some data that he/she would like to send to the receiver. The receiver wants to ensure that the data he/she receives from the sender has not been tampered and must have come from the sender and nobody else.

Step 2: The sender collects the data to be sent. Once finalized, the sender uses the SHA256 hash function to hash the data into a 256-bit number.

Step 3: The sender then signs the 256-bit number with his/her private key encrypting the 256-bit number into what’s called a Digital Signature. Now the sender sends the data, the Digital Signature, and his/her public key to the receiver (remember, you can’t use the public key to figure out the corresponding private key so it is ok to share).

The receiver must authenticate that the data sent was not altered and must have been sent by the person who has the corresponding private key to the shared public key.

Step 1: The receiver takes the Digital Signature and decrypts it with the received public key to get a 256-bit number. Applying the public key to the Digital Signature ‘reverses’ the sender’s step 3 above.

Step 2: Then, the receiver takes the received data and applies the SHA256 hash to it to get a 256-bit number. This is the same thing as the sender’s step 1 and 2.

Step 3: The receiver then checks to make sure the two 256-bit numbers are equal. If false, then somebody has tampered with the data or provided a public key that does not correspond to the private key of the sender. If true, the receiver knows the data is good to go.

A Bitcoin transaction

Now that you have created your public/private key pair, you are ready to join the network and receive bitcoin. Your friend, Tom, said he is willing to give you 10 bitcoin if you provide him your address. In order to create an address your public key is hashed into a pubkeyhash and converted to a base58check format, which generates the addresses you see today that start with a ‘1’ or ‘3’. Note again, you can always use your private key to create a public key and you can always use your public key to create the pubkeyhash, but you can’t work backwards. It is a one-way street. You can, however, go back and forth between a pubkeyhash and a Bitcoin address.

Now, you can give Tom your address and receive your 10 bitcoin. In order for Tom to send you your bitcoin, he must create a transaction output using your address. Outputs consist of an index/location to help the network find this transaction when the owner of the provided address (you) is ready to spend the bitcoin, the amount of bitcoin being sent in satoshis, and a locking script called the PubKey Script. The PubKey Script locks the satoshi’s in the pubkeyhash (your address) that you provided to Tom. Now, you are the only one (hopefully!) with the private key to feed to the PubKey Script and unlock the satoshi’s in the address you provided.

Once this transaction is validated and mined by the miners. Your wallet, which corresponds to your address, shows that you own 10 bitcoin. In reality, your wallet just tracks the outputs that correspond to your address. These outputs are called Unspent Transaction Outputs (UTXOs) and they stay idle until somebody can come along and provide the information needed to unlock the output and send the bitcoin to another address creating another UTXO. The Bitcoin network is just a web of UTXOs that wait to be unlocked and sent somewhere else as a new UTXO. Bitcoin is not an account-based system, meaning users don’t have one account that accumulates bitcoin like you see with a bank account. Instead users hold private keys that unlock UTXOs on the network. This also means that you cannot send a partial amount of satoshis from one UTXO. Every time you create a new transaction you are sending all of the satoshis locked in the UTXO. If you don’t want to send all of the satoshis to one person then you must also include an address for the remaining satoshis that you want to keep and those satoshis are just sent right back to you. Although it is not ideal, you can reuse the same address to send back your remaining satoshis. Ideally, you should create a new address that you own to send the remaining satoshis for increased privacy.

Now, that you have access to the UTXO that you and Tom created with 10 bitcoin locked in it, your friend Sarah also wants to join the network and use bitcoin. In order for you to send your 10 bitcoin, you must create a new transaction consisting of an input and an output.

The Input

First, you use the transaction ID and index from Tom’s output to correctly find the right UTXO and corresponding PubKey Script that somebody must satisfy in order to be able to spend the locked bitcoin.

Next, you create a Signature Script, which will be used to satisfy the PubKey Script. A Signature Script contains a signature and your public key. The signature is a Digital Signature, as discussed above, where the ‘data’ corresponds to essentially the entire transaction you are creating for Sarah. Specifically, the data refers to the transaction ID, index, Tom’s PubKey Script, your new PubKey Script for Sarah and the amount of satoshis you are sending Sarah. All of this data is hashed twice using the SHA256 hash algorithm. Then, you sign 256-bit number with your private key to create the signature. This combined with your public key makes up the Signature Script.

The Output

Just like Tom’s output, your output consists of: a new index to locate this transaction, amount of satoshis, and a new PubKey Script using the address Sarah provides you, which locks the bitcoin in Sarah’s address. Now only the person (hopefully Sarah!) who has the private key that corresponds to the address can send those bitcoin on to somebody else.

The PubKey Script

Once the above transaction is created, you will broadcast it to the network of miners. The miners grab your Signature Script and run it through the PubKey Script. If the result of the PubKey Script is true, then your transaction will be added to a block and validated on the network.

The PubKey Script looks like this:

<Sig> <PubKey> OP_DUP OP_HASH160 <PubkeyHash> OP_EQUALVERIFY OP_CHECKSIG

Bitcoin is a scripting stack-based language. The way this operation is interpreted is as follows:

Step 1: Add your Signature Script. First add your signature then add your public key.

Step 2: OP_DUP duplicates whatever is on top of the stack, in this case the public key.

Step 3: OP_HASH160 hashes the top of the stack, in this case the duplicated public key. Now you have the signature, the public key, and the hash of the public key.

Step 4: The PubKey Script adds the PubKey Hash that you gave Tom in the first transaction.

Step 5: OP_EQUALVERIFY checks the top two components on top of the stack, which is currently the PubKey Hash you gave Tom in the first transaction and the hash of the public key you provided for the Signature Script. These two should be the same. If no, the transaction fails and nothing happens. If yes, the PubKey Script will pop these two components off the stack so that you are left with the signature + the public key.

Step 6: As described in the Digital Signature section above, OP_CHECKSIG uses the public key to decrypt the signature. Then the function checks to see if the decrypted signature equals the twice hashed output of all the data that you signed to create the signature. If no, the transaction fails. If yes, the public key and signature are popped off and you are just left with True.

If True, miners can add it to a block and validate on the network.


Hopefully this was helpful. If not, the best resources I found for this post are:

  1. Bitcoin.org — Transactions
  2. Bitcoin Wiki
  3. Videos from Matt Thomas