ビットコインマイニングが実際にどのように機能するか

ビットコインが主流の採用と認識に近づくにつれ、マイニングとして特徴付けられるその基本的なセキュリティモデルが脚光を浴び、日々ますます精査されています。

人々は、ビットコインマイニングの環境への影響、基盤となるモデルのセキュリティと分散化の程度、さらにはビットコインやその他の暗号通貨の将来に対する量子コンピューティングの飛躍的進歩の潜在的な影響について、ますます懸念し、関心を持っています。

多くの場合、プルーフオブワークは「暗号パズル」と呼ばれますが、実際にはそのパズルとは何ですか?

これらの質問(および考えられる答え)を真に理解するには、ビットコインマイニング自体とその進化についての基本的な理解が必要です。

この記事では、プルーフオブワークのすべての技術コンポーネントと可動部分、およびそれらが互いにシームレスに同期して、ビットコインを現在の分散型プラットフォームにする方法について説明します。

マイニングが機能する理由:暗号化された一方向ハッシュ

ビットコインブロックチェーンは、暗号的に安全で、その後不変のデータベースとして説明されることがよくあります。この不変性とセキュリティを強化する基盤となるテクノロジーは、暗号化ハッシュです。

暗号化ハッシュ関数は、簡単に言えば、任意の入力を受け取り、それを固定サイズの文字列にマップする数学関数です。

ただし、これらの関数には4つの特別なプロパティがあり、ビットコインネットワークにとって非常に貴重です。彼らです:

  1. 決定論的—暗号化ハッシュ関数への入力について、結果の出力は常に同じになります。
  2. 高速—入力が与えられた場合のハッシュ関数の出力の計算は、比較的高速なプロセスです(大量の計算は必要ありません)。
  3. 一意—関数へのすべての入力は、完全にランダムで一意の出力になる必要があります(つまり、2つの入力が同じ出力になることはありません)
  4. 不可逆—ハッシュ関数の出力が与えられた場合、元の入力を取得できません

これらのルールは、ビットコインマイニングがネットワークを保護できるようにする基盤を提供します。

特に、ビットコインプロトコルの作成者である中本聡は、ビットコインマイニングの基礎としてSHA-256ハッシュ関数を使用することを選択しました。これは、上記のプロパティを保持することが数学的に証明されている特定の暗号化ハッシュ関数です。常に256ビットの数値(最も基本的な計算単位)を出力します。これは通常、人間が読みやすいように64文字の16進数システムで表されます。

SHA-256関数の出力は、通常、その入力のハッシュと呼ばれます。

SHA-256関数の入力と出力の例を次に示します(ここで自分で試すことができます)。

Input to SHA-256:  Output to SHA-256: 77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf

興味深いことに、ビットコインプロトコルでハッシュが使用されているほとんどの場所では、ダブルハッシュが使用されています。これは、元のSHA-256関数の出力がSHA-256関数に戻されて、別の出力を取得することを意味します。そのプロセスは次のようになります。

Input to SHA-256(first round):  Output (first round): 77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf Input to SHA-256 (second round): 77077b1f4c3ad44c83dc0bdb8d937e9b71c0ef07a35c2664bb7da85be738eacf Output (second round and final result): 3c6c55b0e4b607b672b50f04e028a6951aed6dc97b91e103fb0f348c3f1dfa00

ダブルハッシュは、誕生日攻撃から保護するために使用されます。誕生日攻撃は、攻撃者がまったく異なる入力を使用して別の入力と同じハッシュを生成できるシナリオです(衝突と呼ばれます)。これは、一意性の3番目のプロパティを壊しますこれがないと、2つの完全に異なるビットコインブロックがまったく同じハッシュで表される可能性があり、攻撃者がブロックを切り替える可能性があります。

SHA-256機能を使用すると、この攻撃が発生する可能性は非常に低くなります。それが不可能に近いものでなければ、SHA-256は壊れていると見なされます。

ただし、他のハッシュ関数は過去に「壊れた」ものでした。将来SHA-256で発生することを防ぐために(そしてビットコインのセキュリティモデルを効果的に破るために)、ハッシュハッシュするのが最善です。これにより、衝突が発生する可能性が半分になり、プロトコルがはるかに安全になります。

非常に高いレベルでは、ビットコインマイニングはすべてのビットコイントランザクションがビットコインマイナーに送信されるシステムです。マイナーは、1メガバイト相当のトランザクションを選択し、それらをSHA-256関数への入力としてバンドルし、ネットワークが受け入れる特定の出力を見つけようとします。この出力を見つけてブロックをネットワークに公開した最初のマイナーは、取引手数料と新しいビットコインの作成という形で報酬を受け取ります。

さらに一歩進んで、ビットコインブロックチェーン自体に飛び込み、マイナーがネットワークを安全にするために何をしているのかを正確に見てみましょう。

ビットコインマイニング:技術紹介

二重支払い問題の解決策としてマイニングが導入されました。私が1つのビットコインを持っていてそれをボブに送信し、次に同じビットコインをアリスに送信しようとすると、ネットワークは1つのトランザクションのみが受け入れられることを保証します。これは、マイニングと呼ばれるよく知られたプロセスを通じて行われます。

技術的な詳細に飛び込む前に、ネットワークを保護するためにマイニングが必要な理由を理解することが重要です。現在、法定通貨が存在するため、私たちが保有する通貨は、連邦準備制度によって作成および検証されます。ビットコインは分散化とコンセンサスの厳格な仮定の下で動作するため、その通貨の発行とその通貨で発生するトランザクションの検証を検証およびタイムスタンプする中央機関は存在できません。

Satoshi Nakamoto proposed the only known solution at the time to solving this validation problem in a consensus-oriented system. Titled in the Bitcoin whitepaper as proof-of-work, this scheme elegantly justifies that transactions are validated by those who are willing to expend enough physical computational energy and time to do so, while simultaneously introducing an incentive to induce market competition. This competition enables the property of decentralization to emerge and thrive organically within the ecosystem.

A Look Inside a Block

A Bitcoin block consists primarily of two components:

1. Transactions, in the form of a merkle tree

Mining computers collect enough transactions to fill a block and bundle them into a merkle tree.

A merkle tree is a relatively simple concept: transactions lie at the bottom of the tree as leaves and are hashed using the SHA-256 function. The combination of two leaf transactions are hashed again using the SHA-256 function to form a parent of the leaves. This parent is continuously hashed upwards in combination with other parents of hashed transactions, until a single root is created. The hash of this root is effectively a unique representation of the transactions that are underneath it.

The root of the merkle tree is a combination of the hashes of every transaction in the tree.

Recall that for any any input to a hash function, the output is entirely unique. Therefore, once most nodes on the network receive a mined block, the root of the merkle tree hash acts as an unchangeable summary of all the transactions in that given block.

If a malicious actor were to try and change the contents of a transaction in a block, its hash would be changed. This change of a hash would be propagated up the transaction’s merkle tree until the hash of the root is changed. Any node can then quickly catch this malicious act by comparing the root of the changed block’s merkle tree to that of a valid block’s merkle tree.

2. The block header

The block header is a summary of the contents of the block itself. It contains the following six components:

  • The version of software the Bitcoin client is running
  • The timestamp of the block
  • The root of its containing transactions' merkle tree
  • The hash of the block before it
  • A nonce
  • The target

Remember that the root of the transaction merkle tree acts as an effective summary of every transaction in the block without having to look at each transaction.

The hash of the previous block before it allows the network to properly place the block in chronological order. This is where the term blockchain is derived from — each block is chained to a previous block.

The nonce and target are what make mining tick. They are the basis for solving the SHA-256 puzzle that miners need to solve.

Please note that all of this data in the block header is compressed into 80 bytes using a notation called little-endian, making the transfer of block headers between nodes a trivially efficient process. For the purposes of this explanation, we’ll ignore this compression and assume data is in its original form.

Explaining the Mining Problem

The target stored in the block header is simply a numeric value stored in bits. In traditional base 10 notation, this target ranges anywhere between 0 to somewhere in the range of 2²²⁴ (a 67+ digitnumber), depending on how many miners are competing to solve this problem at the same time.

Recall that the output of SHA-256 is just a number. The goal of a miner is to take the current block’s header, add a random number to it called the nonce, and calculate its hash. This numeric value of the hash must be smaller than the target value.

That’s all there is to it. But it’s much easier said than done.

Recall the first property of SHA-256: an input into a hash function will always result in the same output. Therefore, if the miner took the block header, hashed it, and realized that the hash value wasn’t less than the target, they would have to change the input somehow in order to try finding a hash below the target value.

This is where the nonce comes in.

The miner adds a number (starting from 0), called the nonce, to the block header, and hashes that value. If the hash value isn’t less than the target, the miner will increment the nonce by 1, add it again to the block header, and hash that changed value. This process is repeated continuously until a hash less than the target value is found.

A Mining Example

Here’s a rough approximation of what made up the first block header:

  • The merkle root of the transaction in the Genesis block:
Merkle Root: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
  • The first known Bitcoin version: 0.1.0
  • The timestamp of the block: 2009–01–03 18:15:05
  • The target (this is also the highest the target will ever be):
Target: 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
  • No previous block hash — this was the first block, and so this is a unique case

The final block header after adding its components together:

Let’s take this large header and compute the double-hash:

SHA-256 of header: 7d80bd12dfdccbdde2c41c9f406edfc05afb3320f5affc4f510b05a3394e1c91 SHA-256 of the previous result (final result): c5aa3150f61b752c8fb39525f911981e2f9982c8b9bc907c73914585ad2ef12b

Both the target and the output hash are incredibly large numbers when converted to base 10 (remember, over 67 digits long). Instead of trying to demonstrate the comparison of the two here, the following Python function handles the comparison instead:

def isBlockHashLessThanTarget(blockHash, target): return int(blockHash, 16) < int(target, 16)

True is returned if the hash is less than the target, false otherwise.

Here is the result with our target and block hash:

Now we take the original block hexadecimal value and add 1 to it. Here is the following result:

We then run the same hashing algorithm and comparison on this changed data. If its not below the target, keep repeating.

Once a successful hash is found, the latest nonce used to find this solution is saved within the block.

The listed nonce on the Genesis block is 2,083,236,893.

This means Satoshi Nakomoto iterated through this process over 2 billion times before he found a hash that was acceptable.

I’ve written a small Python implementation of this Genesis block mining process that can be found on my GitHub.

subhan-nadeem/bitcoin-mining-python

bitcoin-mining-python - A Python implementation of the Bitcoin mining algorithm

github.com

See how long it would take for you to successfully mine the Genesis block!

A Caveat: extraNonce

The nonce value in a block header is stored as a 32-bit number. This means that the highest nonce anybody is able to achieve is 2³² (approximately 4 billion). After 4 billion iterations, the nonce is exhausted, and if a solution is not found, miners are once again stuck.

The solution to this is to add a field to the coinbase (the transaction contents of a block, stored as the merkle tree) called the extraNonce. The size of this extraNonce is only limited by the size of block itself, and so it can be as large as miners wish as long as the block size is within protocol limits.

If all 4 billion possible values of the nonce are exhausted, the extraNonce is added and incremented to the coinbase. A new merkle root and subsequently new block header are calculated, and the nonce is iterated over once again. This process is repeated until a sufficient hash is found.

It’s best to avoid adding the extraNonce until the nonce is exhausted, because any change to the extraNonce changes the merkle tree. This requires extra computation in order to propagate the change upwards until a new root of the merkle tree is calculated.

The Miner Reward

A miner who successfully publishes a block the fastest is rewarded brand new Bitcoin, created out of thin air. That reward currently stands at 12.5 BTC. Just how do these Bitcoins come into existence?

Each miner simply adds a new output transaction to their block that attributes 12.5 Bitcoins to themselves before beginning to mine the block. The network protocol will accept this special transaction as valid upon receiving a newly validated block. This special transaction is called a generation transaction.

Its the miner’s responsibility to add this transaction into the block before mining it. There has been at least one case where miners forgot to add the reward to the transaction before mining a block, effectively destroying 12.5 BTC!

Validating Proof-of-Work

Let’s say our miner has found a hash that is less than the target. All this miner has to do is publish the mined block with the original six components to any connected nodes.

This node receiving the block will first verify the transaction set, ensuring all transactions are valid (for example, all transactions are appropriately signed, and coins aren’t being double-spent and/or being created out of thin air).

It will then simply double-hash theblock header and ensure the value is below the block’s included target value. Once the block is deemed valid, the new node will continue to propagate this block across the network until every node has an up-to-date ledger.

As you can see, newly published blocks can easily be verified by any given node. However, publishing a valid block to the network requires an incredibly large amount of computational power (thus, electricity and time). This asymmetry is what allows the network to be secured while simultaneously allowing individuals who wish to conduct economic activity on the network to do so in a relatively seamless manner.

The Block Time and Adjusting the Target

As the first miners began mining, they each monitored the block time. Each Bitcoin block has a set block time of 10 minutes. What this means is that given the current level of computing power (networkhashrate) on the network, nodes will always expect newly validated blocks to be produced every 10 minutes on average.

We can reasonably expect blocks to be produced within 10 minutes because the probability of finding a block, given the network hashrate, is known.

For example, let’s take the easiest target that’s ever existed in Bitcoin: the genesis block. The probability of any single hash being less than the easiest target is 1 in 2³². That’s one in over four billion. Therefore, we can reasonably expect somebody to run 2³² iterations of the mining problem in order to find a proper hash. Nodes on the network expected four billion of these iterations to be run across allminers on the network every 10 minutes.

If, over a large sample size of blocks, blocks start appearing faster than 10 minutes, this is a pretty clear indication that nodes on the network are iterating through four billion hashes much faster than 10 minutes. This situation prompts every node to adjust the target proportionally based on the increase (or decrease) in network power to ensure blocks continue to be produced every 10 minutes.

In actuality, nodes on the network monitor the block time across 2016 blocks, which comes out to exactly two weeks. Every two weeks, the total block time is compared to the expected block time (which is 20160 minutes).

To obtain the new target, simply multiply the existing target by the ratio of the total actual block time over the last two weeks to get the expected block time. This will adjust the target proportionally to the amount of entering or exiting computing power on the network.

The block time and the ability to easily calculate the probability of finding a valid block lets nodes easily monitor and determine the total hashpower on the network and adjust the network. No matter how much computing power is added to the network or how quickly its added, on average the block time will always remain at 10 minutes.

The current total hash rate on the network is 28.27 exahash per second. That’s 28.27 x 10¹⁸ hashes run every second across all computers on the network.

In summary

We have now comprehensively covered the following:

  • Why cryptographic one way hashing is vital to proof-of-work
  • A breakdown of the construction of a Bitcoin block
  • The actual mining process and iteration itself
  • How nodes can easily validate other blocks
  • How the network manages to maintain the algorithm and competitiveness by monitoring the block time and adjusting the target

You should now be able to understand and explain how proof-of-work actually functions and why it is considered to be an entirely secure algorithm that enables decentralization and consensus!

Follow me on Twitter and Medium if you’re interested in more in-depth and informative write-ups like these in the future!