比特币基础概念入门 2

区块链结构

一、实验介绍

1.1 实验知识点

  • 哈希指针
  • 区块链
  • 默克尔树
  • 比特币的区块链结构

1.2 实验环境

  • Python 2.7

二、哈希指针

首先我们要引入一个叫哈希指针的概念。一般来说一个普通指针可以告诉你数据存储的位置, 哈希指针除了能够告诉你数据存储的位置,由于它还存储了对应数据的哈希值,还能告诉你对应数据是否被篡改过。

三、区块链

区块链其实就是一个将普通指针换成哈希指针的链表,所以每个区块不仅包含了上一个区块的地址,还包括了上一个区块的哈希值 。

我们下面来看一看一个由python实现的简化版区块链:

import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_block , previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_block = previous_block
    self.previous_hash = previous_hash
    self.hash = self.hash_block()

  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) + 
               str(self.timestamp) + 
               str(self.data) + 
               str(self.previous_hash))
    return sha.hexdigest()

import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", None , "0")

def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data , last_block, this_hash)

# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 10

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash)

在区块链中,如果我们假设一个区块被篡改了:

那么如果我们对这个区块的数据计算哈希值, 就会跟后面一个区块中存储的哈希值对不上 ,就会发生验证的问题 。 那么如果要掩盖这个问题,就必须把再后面一个区块的哈希值给改掉,一直改到最近的一个区块。有一个特殊的哈希指针指向最近的区块,由于这个哈希指针无法被黑客篡改,所以黑客没有办法通过篡改区块的方式对区块链进行攻击。

四、默克尔树

其实所有带有指针的数据结构都可以把普通指针换为哈希指针,例如我们可以把二叉树的指针也换成哈希指针,然后就可以得到默克尔树 。

默克尔树底部的树叶是我们的交易数据,而每一个父节点是两个子节点哈希值之和的哈希值。

我们可以通过一个简化版的python程序来领略一下默克尔树

from hashlib import sha256 as sha

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]

def m_tree(transactions):
    """Takes an array of transactions and computes a Merkle root"""
    sub_t = []
    for i in chunks(transactions,2):
        if len(i) == 2:
            hash = sha(str(i[0]+i[1])).hexdigest()
        else:
            hash = sha(str(i[0]+i[0])).hexdigest()
        sub_t.append(hash)
    print sub_t
    if len(sub_t) == 1:
       return sub_t[0]
    else:
       return m_tree(sub_t)

m_tree(['a' , 'b' , 'c' , 'd' , 'e'])

树这种数据结构为我们快速验证一个交易是否存在提供了便利,在比特币中我们为每个交易存储了一个默克尔路径,比如我们要验证K这个交易,我们只用存储下图中蓝色的哈希值就能把根节点给重建出来 ,验证是否存在这笔交易。 而不需要整棵树的数据,这大大节约了空间和时间,在比特币的SPV轻钱包认证中默克尔树起到非常重要的作用。

五、区块链结构

最后我们可以来看一看在真实的比特币系统中交易是怎样被存储的。

通过上图我们可以看到在真实的比特币系统中,外层是一个区块链,而每个区块内部则是用一个默克尔树来存储交易。 外层的区块链保证了结构的简单 ,为后面将要介绍的挖矿与共识打下了基础,而默克尔树则为快速验证交易提供了基础。

读者可以尝试写一些代码,把区块链和默克尔树的知识结合起来,构建一个比特币系统区块链结构的原型。

总结

在本节中,我们通过学习哈希指针,区块链,默克尔树,对区块链相关的重要数据结构有了基本的理解,在下一节中我们要介绍的是比特币系统中的挖矿和共识机制。

你可能感兴趣的:(实验楼课程)