Understanding The Satoshi Codebase : Bitcoin V0.1.5
With the influx of new users to bitcoin I think it is important people understand some of the underlying code behind bitcoin in this I will highlight parts of the codebase that people might find interesting or have heard words such as genesis block ect and are not quite sure what or where to find this in the codebase.
I would like to create a topic that users can contribute from the early code base and create a reference resource that people can quickly reference to learn about the early codebase.
Posts should in the format of
Heading = Part 1 Genesis block
File Name Ref = main.cpp
Line = 1467
(Context / text / code reference)
please use code tags.
We will be looking at Version 0.1.5 which can be downloaded from the following link.
https://github.com/bitcoin/bitcoin/releases/tag/v0.1.5Please only use V0.1.5 for this purpose.
================================================
Part 1. Genesis Block.
Blockchain link :
https://www.blockchain.com/btc/block/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26fReference : File main.cpp
Line 1467
// Genesis Block:
// GetHash() = 0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
// hashMerkleRoot = 0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
// txNew.vin[0].scriptSig = 486604799 4 0x736B6E616220726F662074756F6C69616220646E6F63657320666F206B6E697262206E6F20726F6C6C65636E61684320393030322F6E614A2F33302073656D695420656854
// txNew.vout[0].nValue = 5000000000
// txNew.vout[0].scriptPubKey = 0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704 OP_CHECKSIG
// block.nVersion = 1
// block.nTime = 1231006505
// block.nBits = 0x1d00ffff
// block.nNonce = 2083236893
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
// CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
// CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
// vMerkleTree: 4a5e1e
// Genesis block
char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks";
CTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((unsigned char*)pszTimestamp, (unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
CBlock block;
block.vtx.push_back(txNew);
block.hashPrevBlock = 0;
block.hashMerkleRoot = block.BuildMerkleTree();
block.nVersion = 1;
block.nTime = 1231006505;
block.nBits = 0x1d00ffff;
block.nNonce = 2083236893;
//// debug print, delete this later
printf("%s\n", block.GetHash().ToString().c_str());
printf("%s\n", block.hashMerkleRoot.ToString().c_str());
printf("%s\n", hashGenesisBlock.ToString().c_str());
txNew.vout[0].scriptPubKey.print();
block.print();
assert(block.hashMerkleRoot == uint256("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"));
assert(block.GetHash() == hashGenesisBlock);
The genesis block is the beginning of the blockchain,
This block is hard coded into the application of bitcoin.
You can see from the above code on the first line we see
0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
This is the block hash which can be found by searching in any block explorer which would give you
Block #0
Summary
Number Of Transactions
1
Output Total
$ 208,999.50
Estimated Transaction Volume
$ 0.00
Transaction Fees
$ 0.00
Height
0 (Main Chain)
Timestamp
2009-01-03 18:15:05
Received Time
2009-01-03 18:15:05
Relayed By
Unknown
Difficulty
1
Bits
486604799
Size
0.285 kB
Weight
0.896 kWU
Version
1
Nonce
2083236893
Block Reward
$ 208,999.50
Hashes
Hash
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
Previous Block
0000000000000000000000000000000000000000000000000000000000000000
Next Block(s)
00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
Merkle Root
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Transactions
4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b 2009-01-03 18:15:0
No Inputs (Newly Generated Coins)
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa (Genesis of Bitcoin ) $ 208,999.50
We can also see the reward of 50 Bitcoin for the block in :
txNew.vout[0].nValue = 50 * COIN;
The reward was sent to 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa ,
How is the bitcoin reward set in bitcoin?If we move to lines 657 to 729 in main.cpp we see the following :
//////////////////////////////////////////////////////////////////////////////
//
// CBlock and CBlockIndex
//
bool CBlock::ReadFromDisk(const CBlockIndex* pblockindex, bool fReadTransactions)
{
return ReadFromDisk(pblockindex->nFile, pblockindex->nBlockPos, fReadTransactions);
}
uint256 GetOrphanRoot(const CBlock* pblock)
{
// Work back to the first block in the orphan chain
while (mapOrphanBlocks.count(pblock->hashPrevBlock))
pblock = mapOrphanBlocks[pblock->hashPrevBlock];
return pblock->GetHash();
}
int64 CBlock::GetBlockValue(int64 nFees) const
{
int64 nSubsidy = 50 * COIN;
// Subsidy is cut in half every 4 years
nSubsidy >>= (nBestHeight / 210000);
return nSubsidy + nFees;
}
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast)
{
const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const unsigned int nTargetSpacing = 10 * 60;
const unsigned int nInterval = nTargetTimespan / nTargetSpacing;
// Genesis block
if (pindexLast == NULL)
return bnProofOfWorkLimit.GetCompact();
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
return pindexLast->nBits;
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
// Limit adjustment step
unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
printf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;
/// debug print
printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
return bnNew.GetCompact();
}
On line 677 we can see the block reward for bitcoin
int64 nSubsidy = 50 * COIN;
This was the initial block reward for bitcoin minting a new block would yield a reward of 50 bitcoin to the lucky miner at this time CPU is thought to have been the only mining that was available though as there has been research into this and thoughts are GPU mining did not surface until around 2011 time.
Every 4 years or 210,000 blocks bitcoin undergoes what is called the halving. Where block reward subsidy is halved starting from 50 bitcoin the protocol follows the following structure in the codebase.
// Subsidy is cut in half every 4 years
nSubsidy >>= (nBestHeight / 210000);
The estimated next date for bitcoin halving is 24 May 2020 09:01:59
Currently the block reward is 12.5 Bitcoins this will drop to 6.25 bitcoins around this time.
Current information on bitcoin : Correct at time of writing..
Total Bitcoins in circulation:
17,397,963
Total Bitcoins to ever be produced:
21,000,000
Percentage of total Bitcoins mined:
82.85%
Total Bitcoins left to mine:
3,602,038
Total Bitcoins left to mine until next blockhalf:
977,038
Bitcoin price (USD):
$4,246.80
Market capitalization (USD):
$73,885,667,145.00
Bitcoins generated per day:
1,800
Bitcoin inflation rate per annum:
3.85%
Bitcoin inflation rate per annum at next block halving event:
1.80%
Bitcoin inflation per day (USD):
$7,644,240
Bitcoin inflation until next blockhalf event based on current price (USD):
$4,149,282,855
Total blocks:
551,837
Blocks until mining reward is halved:
78,163
Total number of block reward halvings:
2
Approximate block generation time:
10.00 minutes
Approximate blocks generated per day:
144
Difficulty:
6,653,303,141,406
The bitcoin difficulty re-target is also part of this code :
const unsigned int nTargetTimespan = 14 * 24 * 60 * 60; // two weeks
const unsigned int nTargetSpacing = 10 * 60;
const unsigned int nInterval = nTargetTimespan / nTargetSpacing;
// Genesis block
if (pindexLast == NULL)
return bnProofOfWorkLimit.GetCompact();
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
return pindexLast->nBits;
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
// Limit adjustment step
unsigned int nActualTimespan = pindexLast->nTime - pindexFirst->nTime;
printf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;
/// debug print
printf("\n\n\nGetNextWorkRequired RETARGET *****\n");
printf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
printf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
printf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
return bnNew.GetCompact();
}
In this process we see the following
First is to translate the bits of block N + 2015 to a BigNum target and then calculate the timespan between blocks N and N +2015 into a inumber of seconds.
We would then multiply the old target by the timespan then to divide the result by the timespan ie. 2 weeks = 1209600 s this integer is arithmetic so it is rounded down and the result would be the new target.
The difficulty retarget is such that is should retarget ever 2 weeks you can check the difficulty retargeting on charts such as.
https://fork.lol/pow/retargethttps://bitcoinwisdom.com/bitcoin/difficultyIn part 2 we will look at the networking and P2P structure of the codebase,
Please feel free to contribute to this project it will become a great resource for people to reference without having to trawl the internet for information.