前两天在微信公众号《学习学习再学习》中看到了这么一篇文章《用 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的难度变化。
希望本文能帮助你在区块链的世界里玩得开心。