区块链可谓是最近最火的概念了。随着比特币的暴涨,区块链开始从一种小众技术走入大众视野。算算我从12年底因为因为搞GPU并行计算的缘故接触比特币,到今天也已经5年多了。
在去年底比特币最疯狂的那段日子里,不断有人问我,是不是赚翻了,土豪快请客。其实大家都是凡人,对于一种涨跌不定的虚拟货币,怎么可能拿住不抛呢?肯定都是一路一点一点抛的呀。
其实最后算下来,除了学习了一些基础的金融常识,结识了一两个大佬,还莫名其妙被新华社采访了一次外,最主要的还是让我看清了自己人性的弱点。我只是个凡人,只能尽量克服自己的贪婪和犹豫,但是却无法完全避免。所以跳进去炒,总归只能赚到点零花钱。
所以我还是长期持有着,不去管它的涨跌好了。不过研究一下技术还是很有趣的。
由于最近Python用得比较顺手,就用Python来实现了。目录如下:
1.单机区块链构造
1-1.区块链的数据结构
1-2.区块的创建
1-3.创世区块的生成
1-4.工作量证明
2.区块链的使用
2-1.进行交易
2-2.挖矿
2-3.非对称加密
3.P2P网络的生成
3-1.节点注册和添加
3-2.NAT网络穿透和P2P网络构建
4.一致性(共识)
4-1.实现共识
4-2.分叉
5.其他...(未完待续)
看起来即使是区块链的hello world也是个宏大的工程,我会一点一点慢慢讲。这里面的代码随后也会发布在Github上,欢迎访问。
1-1 区块链的数据结构
区块链由若干个区块组成。一个简单的区块结构如下所示:
{
'index':2,
'timestamp':1520216054.5654142,
'transactions':[],
'proof':432,
'previous_hash':'3c801881e16616f387e...'
}
其中:index是区块链的标识符。timestamp是生成块时的时间。transactions是这个区块包含的交易数量。proof是工作量证明,previous_hash是上一个区块的hash值,保证区块链信息完整不被更改的保证。
1-2.区块的创建
在进行创建之前,我们需要预设一些变量用于储存信息。
令chain=[],存储区块链信息。随着区块链的增长,数据量会逐渐增大,因此需要将交易信息构建为Merkle树的形态,并进行分支拔除(stubbing)的方法,对老区块进行压缩。这是后话,太复杂了以后再说。
令current_transactions=[],存储交易信息。新的交易信息被存储在current_transactions中,以备在下一个区块被开采出来的时候添加进新的区块中。这也是后话,下次更新再说吧。
index=len(chain),确定标识符
timestamp=time.time(),确定时间戳
transactions=current_transactions,把最新的交易信息纳入到新的区块中
proof=_proof,工作量证明,下文将解释如何获取工作量证明
previous_hash=_previous_hash or hash(chain[-1]),取上一个区块的hash作为本区块的previous_hash的值
然后清空current_transactions即可。
1-3.创世区块的生成
为了系统的正常运行,我们需要一个创世区块,即第一个没有前置区块的区块。我们可以随意为其制定一个proof和previous_hash,不过为了方便还是都取值为1好了。
1-4.工作量证明
工作量证明是防止数据造假的关键。其本质是通过hash进行碰撞,得出特定的proof值,这个值应当是非常难于计算(只能穷举并不断验证),但是易于验证(只需要进行一次hash然后对比结果)。
这部分应该是不同的区块链最主要的区别的来源。关于究竟上限是多少个币,挖矿的难度如何递增,是否可以用矿机挖矿,等等。关于这部分的算法,就要玩数学和密码学游戏了,我就不展开讲了。在这里我才用了一个最简单粗暴的方法,直接取hash的前n个字符是0的情况。
验证proof是否有效的语句如下:
valid_proof = hashlib.sha256(f''.encode()).hexdigest()[:n] == '0'*n
其中lastproof是上一个区块的proof,而proof是本区块的proof。需要将它们合并起来进行hash,前n个字符都是0才算有效。
这种算法没有上限,并且难度一直固定。其实只要在算法上多作一点文章,就可以实现难度的递增、控制以及总数的上限控制等等。大家自行发挥…
到此为止一个单机区块链最基础的功能已经大致有了眉目了。加上交易和挖矿功能的话,就是一个最原始的区块链了。
未完待续...
领取专属 10元无门槛券
私享最新 技术干货