Dissecting the code responsible for the Bitcoin halving

栏目: IT技术 · 发布时间: 4年前

内容简介:In a few hours, the Bitcoin network will experience its third “halving”. So what is it and how does it work under the hood?Let’s deep-dive into the nitty-gritty details. The fun stuff.A quick recap:

In a few hours, the Bitcoin network will experience its third “halving”. So what is it and how does it work under the hood?

Let’s deep-dive into the nitty-gritty details. The fun stuff.

Block subsidy and reward halving

A quick recap: miners all around the world are, at this very moment, running hardware and software to calculate the hash of the next Bitcoin block.

If they manage to solve the mathematical puzzle in time, they can claim the block reward .

That’s a lot of buzzwords right there, isn’t it? Let’s break it down.

What’s a hash?

The whole concept of mining is extremely clever. There isn’t actually a puzzle to solve, it’s more of a brute force attempt at trying to guess a magic number.

The Bitcoin network uses SHA256 hashes pretty much everywhere. In a simplified version, miners all around the world are trying to run this function:

SHA256(
    $previousBlockHash,
    $newTransactionsToBeIncluded,
    $magicNumber
);

The $magicNumber is also called a nonce , a Number Used Once . By including the previous blocks’ hash in the new hash calculation, an actual chain is formed linking each block to the new one. A blockchain is essentially a linked list on steroids.

Miners are in the process of guessing the value of $magicNumber . They run the very same calculations over and over again, incrementing (or randomizing) the $magicNumber value. By doing so, they change the outcome of the function every time.

When do they “win”?

Once they find a hash with a sufficient number of zeroes at the beginning.

That’s right: sufficient zeroes .

It’s so simple it’s almost stupid. The difficulty of the calculations are determined by how many zeroes need to be at the front. When the very first block was mined , it only had 8 zeroes at the front:

00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048

When, at the time of writing, the last hash was calculated, it had 19 zeroes at the front.

0000000000000000000133e7bffe43530e508183ec48a89bad23a370692b16e8

The more zeroes are needed at the front, the more difficult it becomes to guess that magic number .

Sidenote: the brilliance of this algorithm is actually in the way it automatically re-calculates its difficulty target (aka: how many zeroes are needed) every 2016 blocks, but that’s for another write-up.

The reward

If you guess the number correctly, you get a reward. That reward comes in the form of newly minted Bitcoins.

These are Bitcoins that are essentially created out of thin air . Except it’s neither thin nor air. Effort was put into the network in the form of computational power and energy. As a result, you get Bitcoin. As a miner, your reward is the result for securing the network.

These newly created Bitcoin are created in what is called a Coinbase Transaction . This is a unique transaction, included in every block, that pays a certain amount of Bitcoin to the miner that guessed the correct hash.

(Yes, that’s probably where the popular cryptocurrency Exchange “Coinbase” got its name from, a reference to the miner reward transaction.)

The reward for each correct block is calculated automatically and auto-adjusts as the bitcoin network marches on. The way this works is quite beautiful, and I’d love to take you on a trip through the code.

The GetBlockSubsidy() function

The magic of the reward halving lies in function GetBlockSubsidy() , located in src/validation.cpp .

CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
    int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
    // Force block reward to zero when right shift is undefined.
    if (halvings >= 64)
        return 0;

    CAmount nSubsidy = 50 * COIN;
    // Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
    nSubsidy >>= halvings;
    return nSubsidy;
}

So, what’s in there? Let’s break it down. It’s been a while since I wrote C, but lucky for us it’s fairly readable.

How many halvings have there already been?

Let’s start at the top:

int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;

The last parameter, consensusParams.nSubsidyHalvingInterval , is defined in src/chainparams.cpp as part of the consensus rules . These are a set of rules everyone on the bitcoin network needs to honour.

Sidenote: any change on these consensus rules would create a “hard fork”, a new set of rules that no longer follow the original chain.

consensus.nSubsidyHalvingInterval = 210000;

Every 210,000 blocks, a halving occurs.

The nHeight refers to the current block “height”. Or, put differently, the number of blocks that have already happened.

Soon, we’ll reach block 630,000. At that point, the equation becomes:

int halvings = 630000 / 210000;

Which will give halvings a value of 3. This will be the third time the network has halved its block reward.

But what happens if there’s a floating point result value, clearly that doesn’t fit in an int variable?

int halvings = 620000 / 210000;

This would result in 2.952380952. However, since the variable is defined as an integer, it is rounded to the lowest integer value by dropping the fractional. Then, halving becomes 2.

The end of block rewards

Let’s take a look at this bit:

// Force block reward to zero when right shift is undefined.
if (halvings >= 64)
    return 0;
This is safety code for a condition I don’t quite understand: if, for some reason, consensusParams.nSubsidyHalvingInterval is too low or nHeight is very high, it would result in the variable halvings with a high value too. I don’t think this check matters, because of the code we’ll see lower down? Would love to know what race condition this is supposed to prevent.

Update: thanks to @niobos , I now know that the shift-by operand is masked. This is important for the code lower in this post, but it means that x >> 65 becomes x >> 1 , so the check for >= 64 needs to stay.

This part is often misinterpreted as “there will be 64 Bitcoin halvings”. That is incorrect. There will be 33 Bitcoin halvings, as we’ll see lower.

How many Bitcoin do you get as a reward?

The word “halving” refers to the process of limiting the amount of Bitcoin you can get as a miner. At every 210,000 blocks, that amount is cut in half .

CAmount nSubsidy = 50 * COIN;
nSubsidy >>= halvings;
return nSubsidy;

At the very start, more than 10 years ago, 50 Bitcoin were rewarded for every block found on the network.

Then, after 210,000 blocks, that got cut in half to 25. Another 210,000 blocks later, that became 12.5. That’s where we are today.

In a few hours, it’ll be cut in half again, and only 6.25 Bitcoins are rewarded to the miner. Fast-forward another 210,000 blocks and that becomes 3.125. And so on.

There’s a clever bitwise operation going on in that code that I want to highlight:

nSubsidy >>= halvings;

It’s not every day you see a >>= operator in your code.

Let’s rewrite that code with the filled in values for each variable:

CAmount nSubsidy = 50 * 100000000;
nSubsidy >>= 3;
return nSubsidy;

The block rewards have a fixed start value at 50. Each coin can be divided into 100,000,000 units, defined in src/amount.h . If we want to be correct, a miner doesn’t get “a Bitcoin” as a reward, it gets “100,000,000” pieces of a Bitcoin as a reward.

A hundred million tiny pieces that form a single bitcoin.

This gives us an initial value of nSubsidy at 5,000,000,000 . If you write that in binary, you get

The nSubsidy >>= 3 means: shift the bits 3 places to the right. This leaves us with:

When you convert that binary value to its decimal representation, you get 625,000,000 . In other words: “625,000,000 mBTC” or “6.25 BTC”.

At the next halving, another zero gets cut at the end of the decimal representation, effectively halving the reward value once again.

Because there are only 33 bits in total, we will run out of block rewards to halve after the 33rd halving, roughly in 2140.

(It’s assumed that at that point, the transaction fees being paid should be sufficient to compensate the miner power consumption and hardware.)

In conclusion

Bitcoin’s monetary supply is hard-coded, for everyone to see and review.

The whole idea that a network of thousands, if not millions, of miners can work in harmony is mindblowing. If you’ve ever tried to set up a 5-node cluster of anything , you’ll know reaching consensus or quorum can be hard.

  • How do you get all your nodes to agree?
  • How do you prevent drift?
  • Or split brains?
  • Or dataloss?
  • What if one node crashes in the middle of a write operation?

This all just works on the Bitcoin network, operating on unknown hardware, on unknown internet speeds with unknown node versions and software - all because of math and the social consensus that everyone follows the same rules on the network.

Fascinating.


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Java程序设计与应用开发

Java程序设计与应用开发

於东军 / 清华大学出版社 / 2005-3 / 27.00元

本书作为Java程序的入门与应用教材,共分为3部分:第一部分讲解Java程序设计的基础知识,包括Java基本编程语言、面向对象设计思想、类、对象、接口以及异常处理。第二部分讲解Java程序设计的高级知识,包括:GUI编程、套接口编程、I/O系统、数据库访问以及多线程编程。第三部分详细分析一个实际项目的开发过程,包括系统分析及功能实现。在项目实例中综合应用第一、二部分的Java知识,能够帮助读者进一......一起来看看 《Java程序设计与应用开发》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具