DEV Community

Cover image for How Bitcoin Works
NOWNodes
NOWNodes

Posted on

How Bitcoin Works

Due to the frequent questions about the inability to send payments “although there are assets on the balance”, we decided to describe the principle of operation of the Bitcoin network (and similar Litecoin, Dash, Dogecoin, etc.) in a clear way. Even if you already have an idea of “how it works”, we strongly recommend you to read this article and to “refresh” your knowledge. Perhaps you will learn something new for yourself or “sort out” what you have already known.

First, some maths (simplified)… If you take any (generate) a very large number (let’s call it a “private key”), then, using a certain (publicly-known) algorithm, you can find a very large number corresponding to it (the”public key”). There is no reverse algorithm. You can’t get a private key from a public key! The private key must always be known only to the owner. The public key is shared with everyone. The peculiarity of this pair of numbers is that if the message (data set) is “signed” (calculate the signature) with a private key, then this signature can be easily verified. by the single public key. It proves that the message has been created by the owner of this key pair. The Bitcoin address (simplified) is the public key.

Key point: as the owner of the address, you can sign messages “on behalf of the address”.

When you create a new address in the app, a private key is actually generated for you, and the public key and address are generated from it. It is very unlikely (almost impossible) that you will come across a pair of keys that have already been issued to someone before. Deleting an app or damaging its files usually leads to the loss of the private key, which means that the assets which are located at this address are lost.

Like any network, the Bitcoin blockchain network consists of connected devices running special software. Each such device (a part of the blockchain network) is usually called a “node”. All nodes are equal in rights. Very powerful nodes can “mine” (see below).

Each node stores a copy of the network database (ledger). The ledger consists of entries. You can add new entries to this ledger only. You cannot edit or delete existing records. Each entry is data about “sending” and/or “receiving” assets from an address to an address.

Key point: the ledger doesn’t store the address balance. The ledger stores all deposits (“outputs”) and all debits (“inputs”) addresses.

For example: Address A: received X1, received X2, sent Y1, received X3, sent Y2..

Key point: the current address balance is the sum of all outputs minus the sum of all inputs (see above).

For example: x came to address A (for all the time), and y left. This means that the address balance is equal to X — Y.

When you send assets, the app generates a message — “transaction”, which contains outputs in the format “address, output” for withdrawal (spending) and inputs in the format “address, amount” for receiving.

Note that the transaction sum must not be more than or equal to the received sum. The difference between the withdrawn and the deposited is called ” transaction fee “and it goes to the” miners ” (see below). Theoretically, you can create a transaction with fee = 0, and this will not be an error. If the transaction fee is higher than the desired sum, the unspent (“change”) is taken back by adding an entry to the list of inputs. The transaction has a size. More items in the lists means more data and longer transactions.

For example: Address A: exit X1 for the sum of “1”, exit X2 for the sum of”2″. Balance A = 1 + 2 = 3. You need to transfer the sum “2”to address B. Output X1 is not enough, we need the sum of output X2.

Initially, the transaction looks like this: outputs: “Address A, X2″, inputs:”Address B, 2”. Debited “2”, deposited “2”. This transaction has a fee = “2–2” = “0”. Miners are not likely to appreciate this. Let’s add a fee = “0.001”. Output X2 is fully used, so we use another output X1.

Initially, the transaction looks like this: outputs: “Address A, X2″, inputs:”Address B, 2”. Debited “3”, deposited “2”. This transaction has a fee = “3–2” = “1”. This is more than needed. Let’s return the change = “1–0.001” = “0.999”.

Initially, the transaction looks like this: outputs: “Address A, X2″, inputs:”Address B, 2”. Debited “3”, deposited “2”. This transaction has a fee = “3–2.999” = “0.001”. Now that’s all right! Let’s note that, although the deposited sum is “2.999”, it includes our “0.999” change, which will be returned to us and will not be spent actually.
Key point: transactions spend the entire output. You can not spend a part of the output, but you can return the “overspent” through the change.

Key point: you cannot create more transactions than there are outputs. The maximum: one output = one transaction. But you can have one output = multiple inputs (recipients).

Key point: the solution is any transfer (arrival) of assets, including the change.

A transaction generated and signed with “private keys” can be sent via any node. The node checks whether the signature is valid, whether it is formed correctly, and whether outputs are available. Then, the transaction is placed in the ”mempool” — the storage of new (unprocessed) transactions. Transactions located in mempool are visible to all nodes. From this point on, all outputs used in this transaction are considered used or “spent” and cannot be used in other transactions.

Adding new entries to the ledger occurs in batches (blocks) of several thousand at once. Blocks are formed by nodes — “miners”. Blocks have a size limit. You can’t create a block larger than the maximum size. A few (thousands) transactions from the mempool are combined into one unit, then the “mining” starts. Mining is the search for a specific block hash using a matching method. The first one to “mine” the block gives it to the other nodes for verification. Each node compares the block entries with previous entries in its ledger. They should not conflict. If the block passes verification, it is added entirely to the ledger of this node. Each node only works with its own ledger.

Key point: each node works independently with its own ledger.

If a block is not accepted on some nodes, then there is some discrepancy in ledgers or a “separate version of the blockchain”. In this case, the nodes are synchronised, and the most common version “wins”. Due to the possibility of desynchronisation, to make sure that the block and all transactions in it are included in the correct version of the blockchain, the final confirmation requires several more blocks after the current one

Key point: transactions are confirmed when new blocks appear after their block.
Key point: you can use the outputs from the confirmed transactions only.

For the correct block, the miner receives a fixed fee, plus the sum of all fees for all transactions in this block. It makes sense that the most profitable way is to form a block of transactions with the maximum fee, so the reward will be bigger. But you also need to remember: the block size is fixed, so you also need to look at the transaction length. In fact, it is most profitable to include transactions in which the “density fee ” (fee per unit of information) is higher. This indicator was called “sat/B” (Satoshi per byte). It is equal to “fee in Satoshi “divided by “transaction length”.

Key point: nobody knows how the miner selects transactions from the mempool. There is no way to force the miner to select your transaction. But for the miner it is more profitable to primarily take transactions that have a higher sat/B score.

Key point: if you want your transactions to get into the block more quickly (i.e., be confirmed), set a fee that makes your transaction’s sat/B score higher than the average for the mempool.

If everyone simultaneously wants their transactions to go faster (for example, because of a great rise in value), then everyone will increase the sat/b value. This means it may vary depending on the network load. This is a difficult choice between the speed and the transaction fee.

The Best Example

  • You have the address A. There are no exits on it. Its balance = 0 BTC.
  • 1 BTC is sent to your address A (this means that the transaction for this sum is confirmed). Now it has one output per 1 BTC Its balance = 1 BTC.
  • 0.2 BTC is sent to your address A. Now it has outputs: 1 BTC and 0.2 BTC. Its balance = 1.2 BTC.
  • You make a transfer from address A to address B in the sum of 0.3 BTC. To make it simple, the fee = 0.
  • Understandably, the output of 0.2 BTC is not enough, so we use 1 BTC.
  • This means that the transaction will have an output of “1 BTC” and inputs “address B, 0.3 BTC”, “address A(unspent), 0.7 BTC”.
  • Immediately after sending and placing it in the mempool, only one output to 0.2 BTC will remain on your address, because the output to 1 BTC has been just used (spent) in the transaction. From now on, the “available” balance of your address = 0.2 BTC.
  • The unspent of 0.7 will not be returned until the confirmation of the transaction. This means this sum cannot be used.
  • In theory, you have 0.2 + 0.7 = 0.9 BTC, but in practice you can’t use these 0.7 BTC.
  • This means that you will not be able to transfer even 0.20000001 BTC immediately after sending it.
  • Your 0.7 BTC will be “frozen” before the confirmation of your transaction.

General Conclusion

How to make everything “run like clockwork” without problems?

1) Have more outputs. This means you should either send multiple transactions to your address, or have more addresses.
2) Use fewer outputs. This means you should make fewer transactions, but with more recipients in a single transaction.
3) Make actions to get your exchange faster. In other words, set a fee so that the sat/B indicator will be currently competitive in the mempool.

Top comments (0)