图片源自USTWO公司开发制作的《纪念碑谷》Monument Valley
最近一位国外大神开源了一个区块链教学项目。
这个项目基于Python,据说非常简单、易上手。
国内外相关爱好者纷纷对其进行了介绍和使用。
我也在第一时间对其进行了了解。
我的个人测评结果是:这真是——
适合入者学习使用、可运行的良心开源项目。
而且基于Python,可以说是相当优秀了!
(人生苦短,我用Python)
于是乎,行动派的我
三下五除二写了这篇详细的复现笔记以飨读者,
以期能帮助想要入门区块链开发实战的童鞋
有个初步探索和感知。
下面就跟我一起开启初探之旅吧^_^
一、项目介绍
开源地址:
https://github.com/adilmoujahid/blockchain-python-tutorial
功能概览
功能和特性介绍
项目仅以兴趣和教学为目的,实现了一个简单的区块链加密货币交易和记账功能,分为本地服务前端和本地客户端,和区块链相关的功能是用Python实现,服务端和客户端的Web交互面板是用HTML/CSS/JS(网页三剑客)实现(我们只需关注和学习Python实现的区块链代码部分即可)。
服务端功能和特性:
支持多节点添加
支持工作量证明(PoW)
支持RSA算法加密交易
查看交易记录和区块链数据
挖掘新的交易区块(获得记账权利)
不同节点的链接配置
简单的节点冲突解决
客户端功能和特性:
用公/私密钥对生成钱包
进行加密货币交易
查看交易记录和状态
二、环境配置
本项目基于Python 3.6实现。
为免去安装基础依赖库的麻烦,推荐使用Anaconda集成开发环境。
因为,Anaconda包含了Python开发和运行所需要的绝大部分科学包和依赖库。
由于我复现时使用的是苹果笔记本的MacOS操作系统,所以本教程下载的也是MacOS版本的Anaconda。如果您使用的是Windows or Linux系统,下载对应的版本安装即可。
不论何种版本系统,安装好后的命令行操作都一样。
2.1 下载
Anaconda官网下载macOS系统对应的Python 3.6版本的Anaconda 5.1,如图:
如果下载缓慢或者失败,推荐使用清华源镜像下载,如下图所示:
2.2 安装
双击刚才下载的安装包;
一路点击“下一步“”、“同意”、“继续”;
使用默认方式完成安装即可。
安装过程你会看到如下所示的界面——
(倒数第二步会让选择是否安装VSCode,其是微软推出的一款优秀的代码编辑、管理、运行软件,推荐安装(虽然本教程中木有使用到)):
2.3 查看环境是否配置成功
打开终端,输入命令 “python” 。
如果看到如下图所示输出——太棒辣!
表明运行环境安装配置成功。
(终端输入python后会进入python命令行,在>>>后输入命令 “ exit()” 回车退出即可)。
三、代码下载
浏览器进入项目地址https://github.com/adilmoujahid/blockchain-python-tutorial。
将项目完整代码下载到本地任一目录下并解压。
如下图所示:
如果想不走寻常路,下载可以另辟蹊径。
下载方法二——命令行方式进行简单快速下载。
终端通过 “cd” 命令跳转至想下载文件的位置,
然后输入命令 :
“git clone --recursive https://github.com/adilmoujahid/blockchain-python-tutorial.git”。
按下“回车”后,即可开始下载!
(通过 “ls” 命令可以查看完成下载的文件):
四、运行使用
本项目的运行模式算是属于B/S模式。
即服务器端提供服务(Server),客户端通过浏览器(Browser)进行使用。
因此我们需要先运行服务端代码将区块链功能运行起来,再运行客户端代码使用。
(本项目客户端和服务器都是运行在本地127.0.0.1网段的)。
3.1 运行服务端代码
先运行服务端代码启动区块链服务。
终端转至第三步下载文件的blockchain文件夹,
输入命令 “python blockchain.py -p 5000”,
按下“回车”后页面如下:
此时在浏览器输入服务端本地运行地址 “http://127.0.0.1:5000”,点击“回车”。
如果显示下面这个页面,说明前端启动成功,
即区块链上已成功运行一个节点。
想添加新节点,只需点终端右上方“+”号,
改变端口号后输入上述同样的命令即可。
(本教程同时开启5000和5001两个节点)
3.2 运行客户端代码
同服务端执行方式一样,可添加一个新终端页。
跳转至blockchain_client文件夹下,
输入命令:
“python blockchain_client.py -p 8080”,
点击“回车”后如下图所示:
此时在浏览器输入客户端本地运行地址 “http://127.0.0.1:8080”,点击“回车”。
界面如下图——恭喜你!客户端启动成功:
3.3 模拟交易
(1)首先在客户端钱包生成页面生成钱包(公/私密钥对)。
(2)交易页面操作:
发送至地址栏:填写刚才的公钥;
发送者私钥栏:填写私钥;
接受地址:填写接收地址(本教程首先测试了发送和接收都输入相同的地址,即自己给自己发送;后面测试了手动将接收地址改为其它地址,也可以成功交易,可查看服务端最后一张交易记录的红线标出部分);
发送数量:自己设定即可;
点击“生成交易”;
弹出“确认信息”对话框【系统自动生成了交易签名、可修改交易节点地址】;
若确认无误,点击“确认”;
弹出“交易成功”提示,点击OK完成交易。
(3)然后在查看交易页面输入交易区块链节点可以查看交易信息(当交易未被服务端确认的时候客户端暂时查看不到交易记录)
左右滑动
查看客户端使用界面>>
(4)登录服务端5000节点,点击Transactions to be added to the next block按钮,可以看到刚才的交易被成功记录(此时客户端可以查看到交易记录了)。
(5)点击Mine按钮可以模拟挖矿,每次可以挖到一个币,获得一次记账权计入相应节点的区块,并将币发送给指定接收地址(此处的值可以从blockchain.py中的第42-44行自行设置改变)。
(6)点击Transactions on the Blockchain按钮可以同步当前节点的所有区块记录。
(7)在配置页面可以添加所有节点列表并进行检索,例如我添加了两个区块链节点5000和5001,并对5001节点上的数据进行检索,可以看到我在5001节点上的交易记录(1次不同地址的点对点交易记录,2次挖矿记录)。
左右滑动查看
服务端使用界面>>
四、代码解读
4.1 区块链服务端代码解读
(1)区块链服务端代码写在blockchain.py这个模块中,其首先定义了Blockchain类(47行),具有4个属性:
transactions: 将要被添加到下一个区块的所有交易的列表
chain: 用数组定义的包含所有块的区块链实体
nodes: 包含所有节点url的集合,区块链使用这些节点取检索来自其它节点的区块链数据,如果数据未同步则更新区块链
node_id: 区别区块链不同节点的一个随机字符串
(2)Blockchain类具有如下方法:
register_node(node_url): 向节点列表中增加一个新的区块链节点
verify_transaction_signature(sender_address, signature, transaction): 检查提供的签名与公钥(即发送者的地址)的交易签名是否匹配
submit_transaction(sender_address, recipient_address, value, signature): 将签名验证通过的交易增加至交易列表
create_block(nonce, previous_hash): 向区块链中增加交易块
hash(block): 为块创建SHA-256哈希码
proof_of_work(): 提供工作量证明算法,用于寻找满足当时的挖掘条件者
valid_proof(transactions, last_hash, nonce, difficulty=MINING_DIFFICULTY): 核验哈希值是否满足挖掘条件,proof_of_work()函数中进行调用(143行)
valid_chain(chain): 验证区块链是否有效
resolve_conflicts(): 通过网络中最长的链替换冲突链来解决区块链之间的冲突
上下滑动浏览代码,点击可放大
以上将区块链的功能代码编写好后,下面开始对其进行调用实现相应功能。由于功能是以Web的方式进行交互,所以代码中使用了主流的Flask Web框架进行实现,即使用Flask对底层的核心代码进行了应用层Web化的调用和封装。
(1)首先初始化一个Python Flask app,用于创建和区块链进行交互的各种接口(222-223行)
(2)接下来初始化一个Blockchain类的实例blockchain(面向对象编程的精髓)
(3)然后定义2个Flask routes(路径),用于返回区块链服务前端面板的html页面(228-230行,对应Mine首页;232-234行,对应Configure页)
(4)接下来定义4个Flask APIs,来完成对区块链的管理和挖掘(对应区块链服务前端Mine页面的各项功能,238-292行):
'/transactions/new': 该API作为'sender_address','recipient_address','amount'和'signature'的入口,并且将签名有效的交易添加至交易列表中,这个列表将被增加至下一个区块
'/transactions/get': 该API返回将被添加至下一个区块的所有交易
'/chain': 该API返回所有区块链数据
'/mine': 该API运行工作证明算法,并将新的交易块添加到区块链中
(5)接下来的3个Flask APIs用于管理区块链节点(对应区块链服务前端Configure页面的功能,296-335行):
'/nodes/register': 该API将节点的URL列表作为输入,并将它们添加到节点列表中
'/nodes/resolve': 该API通过用网络中可用的最长链替换本地链来解决区块链节点之间的冲突
'/nodes/get': 该API用于返回节点列表
(6)最后339-347是程序的执行入口(主函数),用于接收程序的终端输入(如我们输入的命令:python blockchain.py -p 5001),并将代码(区块链)运行起来。
上下滑动浏览代码,点击可放大
4.2 区块链客户端代码解读
(1)区块链客户端代码写在blockchain_client.py这个模块中,其首先定义了Transaction类(32行),具有4个属性:sender_address, sender_private_key, recipient_address, value,对应发送者创建交易所需要的4条信息(对应上文3.3节模拟交易的第(2)条内容)。
(2)Transaction类具有如下方法:
to_dict():该方法以Python字典格式返回交易信息(不包含发送者的私钥)
sign_transaction():该方法获取交易信息(不包含发送者的私钥),并使用发送者的私钥对交易信息进行签名
客户端交易核心代码
和服务端代码一样,接下来使用Flask对客户端的功能进行Web化。
(1)首先初始化一个Python Flask app,用于创建和区块链以及客户端进行交互的各种接口(59行)
(2)然后定义3个Flask routes(路径),用于返回区块链客户端面板的html页面(61-63行,对应Wallet Generator首页;65-76行,对应Make Transaction页;69-71行,对应View Transactions页)
(3)接下来定义2个Flask APIs,来完成生成钱包和交易功能:
new_wallet():生成钱包(公/私钥对)(代码对应3.3节模拟交易第(1)条内容)
generate_transaction(): 调用Transaction类中的方法实现交易,它将sender_address,sender_private_key,recipient_address,value四个值作为输入,并返回交易信息(不包含私钥)和签名(代码对应3.3节模拟交易第(2)条内容)
客户端交易功能Web化代码
(4)最后100-108行是客户端程序的执行入口(主函数),用于接收程序的终端输入(如我们输入的命令:python blockchain_client.py -p 8080),并将代码(客户端)运行起来。
客户端程序执行入口代码
五、总结
一曰“君子性非异也,善假于物也”。
本项目能有如此漂亮的实现,
作者也是建立在其他大神代码的基础上。
感兴趣的朋友可以进一步研究学习。
【基于的代码地址分别是】
https://github.com/dvf/blockchain,
https://github.com/julienr/ipynb_playground/blob/master/bitcoin/dumbcoin/dumbcoin.ipynb。
二曰“纸上得来终觉浅,绝知此事要躬行”。
若您读了这长长的一篇后,
能对区块链编程开发多了些直观感受和理解,
那真是太好!
但是,俗话也说得好哇,
“眼过千遭不如手过一遍”。
所以,小伙伴们还是快快动手实践起来吧
文 末 福 利
注:原英文博客地址
http://adilmoujahid.com/posts/2018/03/intro-blockchain-bitcoin-python/
最后又到了一首歌的时间,
就分享一下今天吃晚饭时听到的一首歌吧,
记得第一次听到这首歌是在去西藏的路上……
文|回头看
编|小月子
审|老猫
领取专属 10元无门槛券
私享最新 技术干货