Empty Blocks in the Bitcoin Blockchain?

Empty Blocks in the Bitcoin Blockchain?


In this notebook we'll have a brief look at a peculiar case: empty blocks in the Bitcoin Blockchain.

Pretty interesting there are "empty" blocks in the Bitcoin Blockchain. Well, they are not entirely empty. They just have only one transaction, which is the coinbase reward. 

No other transactions. Miners earn fees from transactions, so why they should mine empty blocks? 

Here's a brief explanation:
When a mining pool receives a new block, it needs to download the full block, validate its transactions and define a new block to mine on. To avoid wasting hashing power, they just start mining a new block with only the coinbase transaction. By mining an empty block, a miner removes the risk of duplicate transactions in their new block, which would instantly be rejected by the Bitcoin network. If the Bitcoin network rejects a block due to duplicate transactions, the miner that mined the block loses out on the coinbase reward, hence the incentive to mine empty blocks.

But let's start playing our favourite game.

In [1]:

# First we import blocksci
import blocksci

# We import Counter from collections, which we will use to count items in the lists we'll create
from collections import Counter

# we instantiate the chain object
chain = blocksci.Blockchain("/BlockSci/config_file")

# we also import 
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set()

%time 
CPU times: user 2 µs, sys: 2 µs, total: 4 µs
Wall time: 7.63 µs
Let's start to collect all miners information from all the Blockchain. We will use the function miner() that returns the name of the Miner if he chose to write it in the Block.

In [2]:

#instantiate the list of Miners of all Blocks in Bitcon Blockchain 
list_of_Miners = []

#collect all Miners from Blockchain
for x in chain :
    list_of_Miners.append(x.miner())
Let's see what we found:

In [3]:

#print list of blocks of the Blockchain
print(len(list_of_Miners))
684080

In [4]:

#Enumerate Miners and Blocks mined each one
Counter(list_of_Miners)

Out[4]:

Counter({'Unknown': 329360,
         'Eligius': 11425,
         'BitMinter': 6464,
         'BTC Guild': 32935,
         'NMCbit': 105,
         'Yourbtc.net': 226,
         'simplecoin.us': 43,
         'OzCoin': 4845,
         'BTCServ': 9,
         'poolserverj': 5596,
         'SlushPool': 34600,
         'EclipseMC': 5791,
         'BitLC': 326,
         'pool.mkalinin.ru': 83,
         'MaxBTC': 449,
         'TripleMining': 333,
         'CoinLab': 346,
         'HHTT': 623,
         'stratum': 394,
         'stratumPool': 1802,
         'Mt Red': 77,
         '50BTC': 6392,
         'Bitparking': 583,
         'ASICMiner': 3127,
         'F2Pool': 34915,
         'ST Mining Corp': 48,
         'GHash.IO': 789,
         '175btc': 22,
         'Pierce and Paul': 548,
         'MegaBigPower': 282,
         '50btc.com': 14,
         'Polmine': 1069,
         'AntPool': 54913,
         'mmpool': 40,
         'nodeStratum': 837,
         'KnCMiner': 6290,
         'digitalBTC': 612,
         'bcpool.io': 8,
         'Bitcoin Affiliate Network': 438,
         'Solo CKPool': 245,
         'KanoPool': 2432,
         'BTCC Pool': 17964,
         'TangPool': 297,
         'BW.COM': 12414,
         'HASHPOOL': 1,
         'BitClub Network': 5671,
         '21 Inc.': 42,
         'BitFury': 17268,
         '8baochi': 51,
         'TBDice': 4,
         'NiceHash Solo': 20,
         'A-XBT': 7,
         'Nexious': 1,
         'Bravo Mining': 13,
         'HotPool': 11,
         'BCMonster': 15,
         'ViaBTC': 21384,
         'Bixin': 2374,
         'GBMiners': 2093,
         'BTC.com': 31616,
         'Bitcoin.com': 2475,
         'shawnp0wers': 4,
         'Bitcoin India': 114,
         'PHash.IO': 44,
         'BTC.TOP': 16647,
         'ConnectBTC': 153,
         'BATPOOL': 441,
         'xbtc.exx.com&bw.com': 116,
         'CANOE': 321,
         'MiningKings': 41,
         'HAOZHUZHU': 25,
         'BitcoinRussia': 127,
         'Waterhole': 35,
         '7pool': 1,
         'CKPool': 86,
         '58COIN': 745,
         'DCExploration': 3,
         'HashBX': 1,
         'DPOOL': 1918,
         'Haominer': 10,
         'SigmaPool.com': 91})
Now let's show the data in a chart:

In [5]:

data1 = dict(Counter(list_of_Miners))

# Data to plot
labels = []
sizes = []

for x, y in data1.items():
    labels.append(x)
    sizes.append(y)

# Plot

plt.figure(figsize=(30,30))
plt.pie(sizes, labels=labels)

plt.axis('equal')
plt.show()

#Bars

names = list(data1.keys())
values = list(data1.values())

#tick_label does the some work as plt.xticks()
plt.bar(range(len(data1)),values,tick_label=names)
plt.savefig('bar.png')

# plotting a line plot after changing it's width and height
plt.xticks(rotation='vertical')
fig = plt.gcf()
fig.set_size_inches(20,10) 

plt.show()
So 329360 blocks on a total of 684080 blocks shows 'Unknown' as Miner. That's 48.14% of the total.

In [6]:

#Now We exclude 'Unknown', in order to make the chart more readable
data1.pop('Unknown', None)

# Data to plot
labels = []
sizes = []

for x, y in data1.items():
    labels.append(x)
    sizes.append(y)

# Plot

plt.figure(figsize=(30,30))
plt.pie(sizes, labels=labels)

plt.axis('equal')
plt.show()

#Bars

names = list(data1.keys())
values = list(data1.values())

#tick_label does the some work as plt.xticks()
plt.bar(range(len(data1)),values,tick_label=names)
plt.savefig('bar.png')

# plotting a line plot after changing it's width and height
plt.xticks(rotation='vertical')
fig = plt.gcf()
fig.set_size_inches(20,10) 

plt.show()
Now we'll check the number of empty blocks and see its distribution between the miners.

In [7]:

# Let's collect all blocks with zero fees (except coinbase reward)
# We instantiate a list variable to collect blocks with zero fees
zero_fees_blocks = []
 
# collect blocks with zero fees    
for x in chain :
    if x.fee == 0 :
    
     zero_fees_blocks.append(x)

In [8]:

# We print the lenght of the list of blocks with zero fees and the lenght of the used blockchain data
print("Number of blocks without fees:", len(zero_fees_blocks))
print("On a total number of blocks: ", len(chain))
Number of blocks without fees: 125451
On a total number of blocks:  684080

So we found 125.451 blocks with zero fees. On a total of 684080 blocks analyzed, it’s about 18,33% of the blocks.In [9]:

# So we instantiate a list variable to collect miners name from the list of the blocks with zero fees
list_zero_fee_block_miners = []

# Collect names of miners that have mined zero fee blocks
for x in zero_fees_blocks :
    list_zero_fee_block_miners.append(x.miner())

In [10]:

# Eumerate list of Miners of zero fees Blocks and put in a dict call data
data = dict(Counter(list_zero_fee_block_miners))
data

Out[10]:

{'Unknown': 120078,
 'Eligius': 454,
 'BitMinter': 192,
 'BTC Guild': 78,
 'Yourbtc.net': 2,
 'OzCoin': 8,
 'SlushPool': 280,
 'EclipseMC': 86,
 'BitLC': 7,
 'poolserverj': 5,
 'CoinLab': 1,
 'TripleMining': 2,
 '50BTC': 3,
 'F2Pool': 883,
 'ASICMiner': 9,
 'HHTT': 1,
 'Pierce and Paul': 31,
 'Polmine': 2,
 'AntPool': 1746,
 'KnCMiner': 220,
 'TangPool': 7,
 'BTCC Pool': 422,
 'Bitcoin Affiliate Network': 2,
 'BW.COM': 319,
 'Bixin': 42,
 'ViaBTC': 66,
 'BTC.com': 384,
 'PHash.IO': 1,
 'BTC.TOP': 83,
 'CANOE': 1,
 'Bitcoin.com': 7,
 'Waterhole': 1,
 '58COIN': 27,
 'GBMiners': 1}

On a total of 125451 blocks without fees, 120078 are labeled as ‘Unknown’. It makes the 95.71%. So most of the empty blocks are mined by Unknown entities. It is quite a different percentage between the distribution between known and unknown miners for all the Blocks. Let’s see the data in charts.In [11]:

# Data to plot
labels = []
sizes = []

for x, y in data.items():
    labels.append(x)
    sizes.append(y)

# Plot

plt.figure(figsize=(20,20))
plt.pie(sizes, labels=labels)

plt.axis('equal')
plt.show()

#Bars

names = list(data.keys())
values = list(data.values())

#tick_label does the some work as plt.xticks()
plt.bar(range(len(data)),values,tick_label=names)
plt.savefig('bar.png')

# plotting a line plot after changing it's width and height
plt.xticks(rotation='vertical')
fig = plt.gcf()
fig.set_size_inches(20,10) 

plt.show()

In [ ]:

 

In [12]:

#Now We exclude 'Unknown', in order to make the chart more readable
data.pop('Unknown', None)

# Data to plot
labels = []
sizes = []

for x, y in data.items():
    labels.append(x)
    sizes.append(y)

# Plot

plt.figure(figsize=(20,20))
plt.pie(sizes, labels=labels)

plt.axis('equal')
plt.show()

#Bars

names = list(data.keys())
values = list(data.values())

#tick_label does the some work as plt.xticks()
plt.bar(range(len(data)),values,tick_label=names)
plt.savefig('bar.png')

# plotting a line plot after changing it's width and height
plt.xticks(rotation='vertical')
fig = plt.gcf()
fig.set_size_inches(20,10) 

plt.show()
For this tutorial we finish here. There are many things that can be discovered and analyzed in the Bitcoin Blockchain. If you are curious, join our beta tester program, and join the fray! :) And don't forget to smile!

Leave a Comment

Your email address will not be published. Required fields are marked *