首发于编程教室
把区块链的概念一顿暴看,不如用 Python 亲手写一个!

把区块链的概念一顿暴看,不如用 Python 亲手写一个!

普通程序员如何摆脱 985、996、251 的人生轨迹,走上人生巅峰 ?

除了投身人工智能,我只能想到 区块链 了……

今年 “区块链” 又结结实实火了一把:脸书发行 Libre、央行推行 DECP 数字货币、比特币暴涨暴跌……在 2019 年度热门词汇排行中,“区块链” 甚至超过了 “996”、“我不要你觉得” 等热门词语,排名第二。

说实话,从 2017 到 2019,区块链的概念我看过不下十个版本了!但你问我 “区块链是啥”,我还是……

(相信不止我一个人如此)

看懂是不可能看懂了,这辈子不可能看懂了,不如还是亲手写一条吧。

如果你会 Python 的话,跟着下面的教程,你自己就能实现一条区块链!相信我,做完之后你就会恍然大悟:

区块链,原来如此呀!

1.1 实验知识点

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

1.2 实验环境

  • Python 2.7

哈希指针

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

区块链

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

(抄三遍,期末必考。下次别人再问你什么是区块链,直接复说一遍,装逼一百分! )

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

import hashlib as hasher

classBlock:
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
returnBlock(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
returnBlock(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)
printsub_t
if len(sub_t) == 1:
returnsub_t[0]
else:
return m_tree(sub_t)

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

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

区块链结构

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

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

总结

在本节中,我们通过学习哈希指针,区块链,默克尔树,对区块链相关的重要数据结构有了基本的理解,后续实验点击这里继续学习~

比特币基础概念入门_区块链 - 实验楼www.shiyanlou.com图标

本课程从比特币的密码学原理,交易原理等等方面展开,一层一层地揭开区块链技术的面纱,带领同学们领略来自未来的技术。


其他课程:

走进以太坊:从入门到实战

走进以太坊:从入门到实战_区块链 - 实验楼www.shiyanlou.com图标

从最基础的概念开始,以使用的角度,一步一步揭开了最流行的区块链平台 —— 以太坊( Ethereum )的神秘面纱。你讲学习到以太坊的基本概念、以太坊客户端的基本使用、基于 Solidity 的智能合约开发、基于 truffle 的智能合约开发与测试,最终实现一个线上以太坊发牌小游戏。

发布于 2019-12-05

文章被以下专栏收录