极简区块链实现

前两天在微信公众号《学习学习再学习》中看到了这么一篇文章《用 Go 打造区块链(1)基础原型》,顿时引起了我的兴趣。这也是为什么之前突然学习了一下Go语言,并发布了Go语言基础语法的原因。

其实我一直都想看区块链的代码,只是自己时间精力有限没有来得及去深挖比特币的代码。这次看到这篇文章,发现有人从头到尾一步步讲解区块链的实现,并且代码量不是很多我就抽空学习了一下。

文章的内容真的是很不错的,尤其对于像我这种区块链的初学者,又是没事喜欢码代码的码农来说更是能从浅到深深入学习。不过在学习的过程中发现,对于一个只想敲两行命令看看运行结果的人来说,文章还缺了一些具体的实验步骤。没有这些步骤,对大多数的读者来说可能就是一个障碍,导致丧失进一步了解和学习的兴趣。

本文就是对这个系列的一个补充,说直白一点就是这个系列的

实验手册

准备环境

准备环境真的是一件没有什么技术含量,但是绝对会挡住90%入门者的一道坎。可以说这个实验手册的关键内容就在环境准备上了。

安装go语言

我尝试了在两个平台上安装。

在mac上安装比较简单,直接执行一行命令就可以了。

brew install go

在linux上安装稍微有点麻烦,详细步骤请参照链接How to Install Go 1.8 on Ubuntu。

如果你没有linux环境,可以安装虚拟机来代替。对linux虚拟机的安装可以参考我这篇文章--编程环境搭建。

安装依赖库

除了安装go运行环境,区块链原型还需要使用数据库和加密算法。然而依赖库的安装方式在各平台上是一样的,就不用区分了。

go get github.com/boltdb/bolt/...
go get golang.org/x/crypto/...

因为原文还在持续更新中,现在的环境准备是基于part5分支的。后续是否需要其他的环境还得看原作者的文章了。

下载代码

环境准备好了,就可以下载代码了。

git clone https://github.com/Jeiwan/blockchain_go.git

构建工程

在原文中使用的运行命令是:

blockchain_go createblockchain -address

但是实际上blockchain_go是编译出来的,然而在原文中这点并没有给出步骤。当然了,有可能是作者觉得这个实在太简单了,不值得一说。那我就把这个步骤补充一下。

构建的命令是:

go build -o blockchain_go *.go

如果没有错误信息输出,且当前目录下有blockchain_go文件生成,则表示构建成功。

PS:要记住的是每次更新源代码后都要重新构建。

开始实验

所有的内容都准备好了,接下来就可以做点实验,跑跑看来观察一下所谓区块链的行为。这样哪怕看不懂代码,也可以大致了解一下都有哪些操作。

创建地址

$./blockchain_go createwallet
Your new address: 159h84bcySKEjCz9PTqVjssWaUcp1qesYG

这样你就获得了一个区块链的地址。

可以理解为这就是区块链世界的银行账号。如果要进行买卖,交易就是用的这个地址。

创建区块链

$./blockchain_go createblockchain -address 159h84bcySKEjCz9PTqVjssWaUcp1qesYG

00380b95a840e2e1164b0b4859f24993ee95bb9caed5c97f52f759511e01bf54

Done!

命令运行后打印出的一串看不懂的数字就是一个区块的标示了。

首次转账

通俗来讲,区块链就是公开的账本。那其功能之一就是转账了。那我们来转一次看看~

转账之前还得再创建一个地址,否则转给谁呢,你说是不。

$ ./blockchain_go createwallet
Your new address: 1EVnXorM3ZUrxtgavcAgu7y1U77aKo5R4J

转账

$./blockchain_go send -from 159h84bcySKEjCz9PTqVjssWaUcp1qesYG -to 1EVnXorM3ZUrxtgavcAgu7y1U77aKo5R4J -amount 3

0a213e7f892d240d2ab0a1d348e42653f92a9639a73bb636ddef9de5de2dc721

Success!

查账

$./blockchain_go getbalance -address 1EVnXorM3ZUrxtgavcAgu7y1U77aKo5R4J
Balance of '1EVnXorM3ZUrxtgavcAgu7y1U77aKo5R4J': 3

瞧,在地址“ 1EVnXorM3ZUrxtgavcAgu7y1U77aKo5R4J”下就有三块钱了~

显示区块链

$./blockchain_go printchain
============ Block 0a213e7f892d240d2ab0a1d348e42653f92a9639a73bb636ddef9de5de2dc721 ============
Prev. block: 00380b95a840e2e1164b0b4859f24993ee95bb9caed5c97f52f759511e01bf54
Created at : 2017-10-11 15:54:57 +0800 CST
PoW        : true

--- Transaction c931a82af89b35613eaf75d7615969b45dd9d977ed588a6964428543c090f7bf:
     Input 0:
       TXID:      ada9b6e85d682827b44968f396fb5878c70cd8d100af498a36fa9a7c8956651f
       Out:       0
       Signature: b4afe8ff2c7dff5a303ab17d537dc950e1d866b66e29d84ba9cc0854fc51ccf96cbaa32c7d6e4179dff068636f627da518dcccd41359d74b85f8ada45af475f9
       PubKey:    3b000f08ad53bbfd4d011939b0199bdf56043c3cca5c73181b9a08c077da863ae337445a0113e3db3311f5afefc45464223d2372d1db8b28f8d6766617ce8f15
     Output 0:
       Value:  3
       Script: 940b4a24d6bd8c474769f7e8382d572c1f20f4bb
     Output 1:
       Value:  7
       Script: 2d8552a22cec6608c383145575884e03ce6b0fe8


============ Block 00380b95a840e2e1164b0b4859f24993ee95bb9caed5c97f52f759511e01bf54 ============
Prev. block:
Created at : 2017-10-11 15:41:32 +0800 CST
PoW        : true

--- Transaction ada9b6e85d682827b44968f396fb5878c70cd8d100af498a36fa9a7c8956651f:
     Input 0:
       TXID:
       Out:       -1
       Signature:
       PubKey:    5468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73
     Output 0:
       Value:  10
       Script: 2d8552a22cec6608c383145575884e03ce6b0fe8

运行这个命令就可以显示出区块链上的区块了,并且还显示了有两次交易的信息。至于具体的含义可以参考原文,在这里我就不多做解释了。

调整PoW难度

PoW 即工作量证明是比特币中重要的一个概念。为了协调整个网络的算力来计算区块,会不断调整PoW的难度。之前只有一个理性的认识,现在我们手上有了代码就可以通过实验来获得感性认识。

在proofofwork.go文件中,有一个变量

const targetBits = 24

暂且可以理解为这个值就是难度的大小。值越大,难度越大;值越小,难度越小。可以通过减小这个值,再生成一个区块链或者转账来观察一下命令运行的时间。通过时间的长短来体会PoW的难度变化。

希望本文能帮助你在区块链的世界里玩得开心。

你可能感兴趣的