Py学习  »  Python

从零开始用 Python 打造自己的区块链

GitChat技术杂谈 • 5 年前 • 597 次点击  


本文来自作者 Frank  GitChat 上分享 「从零开始用 Python 打造自己的区块链」

编辑 | 毛利

前言

2018 年 4 月以来,随着加密货币价格的回升,各种关于区块链的话题甚嚣尘上,各大媒体对其商业性质、技术原理、发展前景各个方面,都有各种非常深入的探讨。

同时,新的项目、概念也层出不穷,让人眼花缭乱。笔者认为,“区块链” 本质上还是一种软件算计 / 架构上的创新。

只有自己搭建环境,编写代码,实现从建立账本到完成交易的全过程,才能真正体会区块链的精髓。

比特币近十年来的价格逐波上升

本场 Chat 的目的是,就是帮助广大的区块链爱好者或者开发人员,从零开始打造属于您自己的区块链应用。

力求用最简单的语言,介绍这个最热门的技术,没有任何基础的读者也能按图索骥,一窥究竟,消除各种专家为其增添的很多迷思。

本文首先将介绍一些区块链的背景知识,而后将循序渐进地介绍在本地开发区块链应用所需要的模块和算法,做出一个简单的区块链交易程序。

在此过程中,会穿插很多关于相关名字、术语、算法的解释。相关源代码都保存在笔者的 GitHub 项目中(https://github.com/marmul2/blockchain),欢迎读者直接使用或者提交修改申请(pull request)。

GitHub 是一个面向开源及个人软件项目的托管平台,因为只支持 git 作为唯一的版本管理格式,故名 GitHub。

因为这里聚集了超过 350 万开发者,其中又以男性程序员为主,所以被戏称为 “全球最大同性交友网站”。

它不光支持代码的发布、管理,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱、代码片段分享等功能。

任何用户都可以在其上保存和发布自己的个人项目,很多知名的开源项目如 Ruby on Rails、jQuery、python 等都托管在该平台上。

1. 区块链简介

一位名为 “中本聪” (Satoshi Nakamoto) 的人于 2008 年 11 月 1 日,在 metzdowd.com网站的密码学邮件列表中,发表了一篇名为《比特币:一种点对点式的电子现金系统》(Bitcoin: A Peer to Peer Electronic Cash System) 的论文,首次提出了 “区块链”(Blockchain)的概念。

白皮书发布之后不久,中本聪于 2009 年 1 月 3 日,开发出首个实现了比特币算法的客户端程序,并进行了首次 “采矿”,获得了第一批 50 个比特币。

这标志着比特币的正式诞生。中本聪出于知识分享和推广的理念,把比特币程序的代码全部开源,与世界各地的软件开发人员共同分享。

中本聪的原始论文

经过这十年的发展,区块链已经发展成为全球最具影响力的创新技术之一。

从金融行业、制造产品到教育机构的各行各业,都可能会被这项技术全面改造。它的三大最主要的特点是:

  • 去中心化交易

区块链的本质是一种分散在所有用户电脑上(即所谓的 “分布式”)的计算机账本,每个分散的账本会记录区块链上进行的所有交易活动的信息。所以,它不需要一个集中的机构、网站、公司来管理这些信息。

法国大作家大仲马在 1884 这年出版的小说《三个火枪手》中有这么一句著名的话,“人人为我,我为人人”(All for one, one for all)。用这句话来形容区块链的去中心化特征非常贴切。

  • 信息不可篡改,一旦写入无法改变

作为一个记录交易的账本,人们最不希望的是它被坏人恶意篡改。任何一个用户,都可以通过交易编号,访问区块链上发生的所有交易记录和注释。

由于中本聪巧妙的算法设计,配合密码限制和共识机制,如果要修改区块链中的某一个数据,就必须更改其后发生的所有数据记录,计算量无可想象,非常庞大,几乎不可能实现。

实际上,比特币诞生到现在已经接近 10 年,每天都有无数的黑客绞尽脑汁攻击这个系统,但是从来没有发生过一起交易记录被篡改的事件,这足以证明了它的安全性。

  • 完全匿名

在互联网诞生初期,有句话说:“在互联网上,没人知道你是一只狗。” 这强调的是在互联网上的匿名访问性。

在区块链世界里,所有的账户(或者说 “钱包”)都是通过一个密码来访问。如果你失去了密码,也就失去了账户里面的所有货币。

在现实生活中,如果你忘记了密码或者丢失了银行卡,你可以去银行柜台申请补办,手续很简单。

但是在 “去中心化” 的区块链世界里,没有这样的 “银行柜台”,谁也不知道你是谁,你也无法向别人证明你是某个钱包的主人。

当然,与大部分技术一样,区块链也是一个 “双刃剑”,有它的不足之处:

  • 过度消耗能源

想要生成一个新的区块,必须要大量服务器资源进行大量无谓的尝试性计算进行 “挖矿”,严重耗费电能(后文将详细介绍 “挖矿” 的过程)。

  • 信息的网络延迟

以比特币为例,任何一笔交易数据都需要同步到其他所有节点,同步过程中难免会受到网络传输延迟的影响,带来较长的耗时。

区块链应用的实际开发,可以分为以下几步。下面我们将针对每个步骤详细介绍。

除了主要介绍环境配置的第二节和介绍交易步骤的第七节以外,其他步骤都分为概念介绍、代码实现、深入讲解这三个部分。

所有代码均已放在我的 GitHub 项目之中,您可以直接下载使用。如果对具体的代码实现不感兴趣,您也可以直接只关注每节中的概念介绍和深入讲解这两个部分。

如果您对具体的算法也不感兴趣,没关系,您可以直接跳过这些部分,进入第七节,逐步尝试自己完成 “虚拟交易”。

2. 环境配置:建立 “交易所”

为了便于初学者学习,笔者会尽可能详细地记录开发环境配置的每一个步骤,如果您已经熟悉 Python 环境和相关模块的使用,您可以选择跳过这一部分。

1. 首先,您需要一台安装了 Win7 或者 Win10 系统的电脑,可以是台式机或者是笔记本电脑。

当然,不一定非要用 Windows 系统来开发区块链应用,Linux 或者 Mac 系统也是很好的选择,这里我们为了照顾大部分读者,只介绍 Windows 系统下的操作。

2. 访问 www.python.org,下载并安装 Python 3.6.5 或者将来的更高版本。

下载Python

3. 安装完毕 Python 之后,从 Windows 的开始菜单输入 “cmd”:

在命令行窗口输入以下指令,安装 Flask 和 requests 库。Flask 库将用于在本地构建一个 Web 服务器,把 Python 的功能映射到一定的端口,便于我们稍后通过针对不同的地址终端(endpoint)发送 HTTP 请求,执行各项交易,从而构成我们自己的 “虚拟交易所” ;requests 库则用于自动发送 HTTP 请求到服务器。

c:\>easy_install pip
c:\>pip install Flask==0.12.2 requests==2.18.4

4. 访问 https://www.getpostman.com/apps, 下载并安装 Postman,它可以把我们定制的交易内容,发送到我们的 “虚拟交易所”。

Postman的开始界面

5. 现在,打开电脑在带的写字板编辑器,保存这样一个文件到 D:\hello.py:

from flask import Flask app = Flask(__name__)@app.route('/')def hello_world():    return '您好,欢迎来到我的虚拟货币交易所!'

这里实际上用的 Flask 模块的路由功能,具体语法信息请参阅 Flask 介绍页面(http://flask.pocoo.org/docs/0.12/quickstart/#a-minimal-application)

6. 回到命令行控制界面,输入下列指令:

c:\>set FLASK_APP=D:\hello.py c:\>python -m flask run

你可以看到屏幕显示 “Running on https://127.0.0.1:5000/”。 这时,打开你的浏览器,访问 https://127.0.0.1:5000/, 你可以看到这样的显示结果:

交易所开始运行

这就意味着,我们的运行环境已经搭建成功,您的 “虚拟交易所” 已经准备好接受交易了!

3. 构建区块链:把 “区块” ,“链” 到一起

3.1 概念介绍

“区块链”(Blockchina)可以理解为把一个个符合特定格式的区块(Block),按照一定的方法 “链”(chain)到一起。

这里先预习几个需要涉及的概念:

“类” (class):类是面向对象程序设计中的概念,是面向对象编程的基础。

类是对现实生活中一类具有共同特征的事物的抽象,譬如区块链这个概念,就是一类具有共同特征的事物,我们可以用一个类来代表它。

类可以描述一个对象(在本文中即某个区块链)能够做什么,以及做的方法(method)。

哈希值(Hash):所谓 “哈希值” 就是计算机可以对任意内容,计算出一个长度相同的特征值。

区块链的哈希值长度是 256 位,这也就是说,不管原始内容是什么,最后都会计算出一个 256 位的二进制数字。

而且可以保证,只要原始内容不同,对应的哈希一定是不同的。举例来说,字符串 123 的哈希值是 a8fdc205a9f19cc1c7507a60c4f01b13d11d7fd0(十六进制),转成二进制就是 256 位,而且只有 123 能得到这个哈希。

(理论上,其他字符串也有可能得到这个哈希,但是概率极低,可以近似认为不可能发生。) 由此可以得到两个重要的结论:

  • 结论 1:每个区块的哈希都是不一样的,可以通过哈希标识一个区块。

  • 结论 2:如果区块的内容变了,它的哈希一定会改变。

3.2 代码实现

首先,我们要用一个构造函数来创建一个区块链类 ,其中包括两个表:一个用于存储区块,一个用于记录交易。另外,我们还要定义一个方法,用于生成区块的哈希值。

此外,我们还为这个类定义了一个属性 last_block, 这样可以通过调用该类获得区块链中最后一个区块的信息。下面是这个类的初步结构:

class Blockchain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []    def new_block(self):
        # 创建一个新的区块
        pass

    def new_transaction(self):
        # 把新的交易添加到交易列表中
        pass

    @staticmethod
    def hash(block):
        # 生成一个区块的哈希值
        pass    

    @property
    def last_block(self):


    

        # 返回链中的最后一个区块
        pass

这个类负责管理整个区块链,包括存储交易信息,把新的区块添加到整个区块链之中。

下面,我们再来看看一个典型的区块是什么样的,以及它们是怎么构成一条区块链的。按照中本聪的原始定义,下面是一个典型的区块:

block = {    'index': len(self.chain) + 1,    # 区块编号,即区块链之前长度+1
    'timestamp': time(),    # 区块生成时间的UNIX时间戳
    'previous_hash': previous_hash or   self.hash(self.chain[-1]),    #上一个区块的哈希值,另外需要考虑第一个区块的情况
   'proof':proof,    # 工作量证明(PoW),稍后会详细介绍
    'transactions': [
        {        'sender': sender_hash,        #付款人钱包地址
        'recipient': recipient_hash,        #收款人钱包地址
        'amount': tranactions_ammount,        #交易金额
        }
   ],    # 区块中的交易信息
 }

3.3 深入讲解

由上面的定义可以看出,一个区块包括下面几项内容:

  • 区块索引 / 编号

  • 区块产生时间

  • 上一个区块的哈希值

  • 工作量证明(PoW)

  • 交易信息

这揭示了区块链的核心理念:每个区块中包含了上一个区块的哈希值或者说信息。这一点对区块链有重大意义:如果有人修改了一个区块,该区块的哈希值就变了。

为了让后面的区块还能连到它,就必须依次修改后面所有的区块,否则被改掉的区块就脱离区块链了。

由于哈希值的计算非常耗时(后面将解释原因),短时间内修改多个区块几乎不可能发生,除非有人真的掌握了全球网络中 51% 以上的计算能力。

正是通过这种联动机制,区块链保证了自身的可靠性,数据一旦写入,就无法被篡改。这就像历史一样,发生了就是发生了,从此再无法改变。每个区块都连着上一个区块,这也是 “区块链” 这个名字的由来。

4. 记录交易: 怎么给区块添加交易记录?

4.1 概念介绍

在建立起区块链之后,接下来我们看看怎么为其添加交易信息。所谓 “交易”(Transaction)的过程,实际上就是给区块链加一笔数据更新的记录,其中包含了付款人的钱包地址、收款人的钱包地址、交易金额。如果把区块链作为一个状态机,则每次交易就是试图改变一次状态,而每次生成的区块,就是参与者对于区块中交易导致状态改变的结果进行确认。

4.2 代码实现

具体的添加过程,是通过 new_transaction 这个方法来实现的。下面是对这个方法的定义实例。

......

5. “挖矿” 解密

6. 在网络中传播区块链:共识算法

7. 执行交易

后记

本 Chat 中所有的代码都放置在我的 GitHub 项目 “Frank—Blockchain” 上,请自由索取或者提交修改。

或者您也可以分叉(fork)一个自己的分支,创建您自己的区块链项目。开句玩笑话,这就像是在麻将的基本原则基础上,开辟出各种分支:四川麻将、上海麻将等等。

希望本 Chat 能帮助您了解并实践区块链的基本概念和实现方法。请注意,这里提到的只是区块链最核心的部分,还有很多很多其他的技术细节和算法,譬如非对称加密、点对点网络等,我将会在以后的其他 Chat 中详细说明。

如果有任何其他的问题,欢迎到我的读者圈中继续提问。

扫描下方二维码

【阅读完整原文】

并在读者圈与作者交流


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/BVq2JJ3pKo
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/12320
 
597 次点击