文档章节

通过构建区块链来学习区块链-1-Transaction|Block|POW

Riverzhou
 Riverzhou
发布于 09/15 15:10
字数 2032
阅读 18
收藏 0
def

原文链接:https://medium.com/@vanflymen/learn-blockchains-by-building-one-117428612f46

  • 交易Transaction
  • 区块Block
  • 工作量证明

你来这里是因为,和我一样,你对加密货币的崛起感到兴奋。你想知道区块链是如何工作的——它们背后的基本技术。

但理解区块链并不容易——至少对我来说不是。我艰难地浏览了密集的视频,学习了很多的教程,并处理了由于例子太少而产生的放大的挫折感。

我喜欢边做边学。如果您也这样做,在本指南的最后,您将拥有一个功能良好的区块链,并对它们的工作原理有一个坚实的了解。

在你开始之前…

请记住,区块链是一个不可变的、连续的记录链,称为块。它们可以包含事务、文件或任何您喜欢的数据。但重要的是它们是用散列连接在一起的。

如果你不确定哈希是什么,这里有一个解释

  • 这本指南是针对谁的? 您应该能够轻松地阅读和编写一些基本的Python,并对HTTP请求的工作原理有一些了解,因为我们将通过HTTP与我们的区块链通信。

  • 我需要什么? 确保安装了Python 3.6+(以及pip)。你还需要安装Flask和wonderful Requests 库:

pip install Flask==0.12.2 requests==2.18.4

您还需要一个HTTP客户机,比如Postman 或cURL;但什么都行。

  • 最终代码在哪里? 这里提供了源代码

###步骤1:构建一个区块链

打开您最喜欢的文本编辑器或IDE,我个人喜欢PyCharm。创建一个名为blockchain.py的新文件。我们只使用一个文件,但是如果您丢失了,您可以随时查阅源代码。

代表一个区块链

我们将创建一个区块链类,该类的构造函数创建一个初始空列表(用于存储我们的区块链),另一个用于存储事务。这是我们班的蓝图:

class Blockchain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        
    def new_block(self):
        # Creates a new Block and adds it to the chain
        pass
    
    def new_transaction(self):
        # Adds a new transaction to the list of transactions
        pass
    
    [@staticmethod](https://my.oschina.net/staticmethod)
    def hash(block):
        # Hashes a Block
        pass

    [@property](https://my.oschina.net/property)
    def last_block(self):
        # Returns the last Block in the chain
        pass

我们的区块链类负责管理链。它将存储事务,并具有一些用于向链添加新块的辅助方法。让我们开始充实一些方法。

Block是什么样子的?

每个块都有以下内容:

  1. 一个索引
  2. 一个时间戳(Unix时间)
  3. 一个事务列表
  4. 一个证明(稍后将详细介绍)
  5. 前一个块的散列

下面是单个块的例子:

block = {
    'index': 1,
    'timestamp': 1506057125.900785,
    'transactions': [
        {
            'sender': "8527147fe1f5426f9dd545de4b27ee00",
            'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
            'amount': 5,
        }
    ],
    'proof': 324984774000,
    'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824”
}

此时,链的概念应该很明显——每个新块都包含前一个块的散列(Hash)。这是至关重要的,因为它使区块链具有不变性:如果攻击者破坏了链中较早的一个区块,那么所有后续的区块都将包含不正确的散列(Hash)。

这说得通吗?如果没有,花点时间让它沉下去——这是区块链背后的核心理念。

将事务添加到块中

我们需要一种向块添加事务的方法。我们的new_transaction()方法对此负责,它非常简单:

class Blockchain(object):
    ...
    
    def new_transaction(self, sender, recipient, amount):
        """
        Creates a new transaction to go into the next mined Block

        :param sender: <str> Address of the Sender
        :param recipient: <str> Address of the Recipient
        :param amount: <int> Amount
        :return: <int> The index of the Block that will hold this transaction
        """

        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1

new_transaction()将一个事务添加到列表后,它返回将事务添加到下一个要挖掘的块的索引。这将在稍后对提交事务的用户有用。

创建新的Block

当我们的区块链被实例化时,我们需要用一个genesis块来播种它——一个没有前处理的块。我们还需要向genesis块添加一个“证明”,这是挖掘(或工作证明)的结果。稍后我们将更多地讨论采矿。

除了在构造函数中创建genesis块,我们还将充实new_block()、new_transaction()和hash()的方法:

import hashlib
import json
from time import time


class Blockchain(object):
    def __init__(self):
        self.current_transactions = []
        self.chain = []

        # Create the genesis block
        self.new_block(previous_hash=1, proof=100)

    def new_block(self, proof, previous_hash=None):
        """
        Create a new Block in the Blockchain

        :param proof: <int> The proof given by the Proof of Work algorithm
        :param previous_hash: (Optional) <str> Hash of previous Block
        :return: <dict> New Block
        """

        block = {
            'index': len(self.chain) + 1,
            'timestamp': time(),
            'transactions': self.current_transactions,
            'proof': proof,
            'previous_hash': previous_hash or self.hash(self.chain[-1]),
        }

        # Reset the current list of transactions
        self.current_transactions = []

        self.chain.append(block)
        return block

    def new_transaction(self, sender, recipient, amount):
        """
        Creates a new transaction to go into the next mined Block

        :param sender: <str> Address of the Sender
        :param recipient: <str> Address of the Recipient
        :param amount: <int> Amount
        :return: <int> The index of the Block that will hold this transaction
        """
        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })

        return self.last_block['index'] + 1

    [@property](https://my.oschina.net/property)
    def last_block(self):
        return self.chain[-1]

    @staticmethod
    def hash(block):
        """
        Creates a SHA-256 hash of a Block

        :param block: <dict> Block
        :return: <str>
        """

        # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

上面的内容应该是直接了当的—我添加了一些注释和文档字符串来帮助保持清晰。我们几乎完成了对区块链的表示。但此时,您一定想知道如何创建、锻造或挖掘新的块。

工作证明

工作算法(PoW)的一个证明是如何在区块链上创建或挖掘新的块。PoW的目标是发现一个可以解决问题的数。这个数字一定很难找到,但是很容易被网络上的任何人验证——从计算的角度来说。这是工作证明背后的核心思想。

我们将看一个非常简单的例子来帮助理解这一点。

让我们决定某个整数x乘以另一个y的散列必须以0结尾。哈希(x * y) = ac23dc…0。对于这个简化的例子,我们令x = 5。用Python实现:

from hashlib import sha256
x = 5
y = 0  # We don't know what y should be yet...
while sha256(f'{x*y}'.encode()).hexdigest()[-1] != "0":
    y += 1
print(f'The solution is y = {y}’)

解是y = 21。因为,生成的散列以0结尾:

hash(5 * 21) = 1253e9373e…5e3600155e860

在比特币中,工作证明算法被称为Hashcash。它和上面的基本例子没有太大的不同。它是矿工们为了创建一个新的块而竞相求解的算法。通常,难度由字符串中搜索的字符数量决定。然后,这些矿商会因为他们的解决方案而获得一笔交易中的硬币作为回报。

网络能够很容易地验证他们的解决方案。

实现基本的工作证明

让我们为区块链实现一个类似的算法。我们的规则将类似于上面的例子:

找到一个数字p,当它与前一个块的解进行散列时,会产生一个前导4个0的散列。

import hashlib
import json

from time import time
from uuid import uuid4


class Blockchain(object):
    ...
        
    def proof_of_work(self, last_proof):
        """
        Simple Proof of Work Algorithm:
         - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
         - p is the previous proof, and p' is the new proof

        :param last_proof: <int>
        :return: <int>
        """

        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1

        return proof

    @staticmethod
    def valid_proof(last_proof, proof):
        """
        Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?

        :param last_proof: <int> Previous Proof
        :param proof: <int> Current Proof
        :return: <bool> True if correct, False if not.
        """

        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == “0000"

为了调整算法的难度,可以修改前导零的个数。但是4就足够了。您将发现,添加一个前导零会大大缩短找到解决方案所需的时间。

我们的类几乎完成了,我们已经准备好开始使用HTTP请求与它进行交互。

本文由Rebase社区的River翻译并整理;有问题请加微信syuukawa,备注:区块链

© 著作权归作者所有

Riverzhou
粉丝 0
博文 19
码字总数 16342
作品 0
私信 提问
区块链是什么?彻底理解只要50行ruby代码!

区块链是什么?作为一个Ruby开发者,理解区块链的最好办法,就是亲自动手实现一个。只需要50行Ruby代码你就能彻底理解区块链技术的核心原理! 如果你希望马上开始学习以太坊区块链应用开发,...

汇智网教程
2018/05/06
18
0
Why do new blockchain projects prefer PoS over PoW?

If you have been following the trend of blockchain technology, you will notice that most of the new public blockchain projects are using PoS as their consensus mechanism: Cosmos......

Vivien_like
2018/09/03
0
0
如何用JavaScript写一个区块链?

Part1实现一个基本的区块链 1.区块链 区块链是由一个个任何人都可以访问的区块构成的公共数据库。这好像没什么特别的,不过它们有一个有趣的属性:它们是不可变的。一旦一个区块被添加到区块...

骚年锦时
05/23
4
0
用 Python 从零开始创建区块链

本文主要内容翻译自 Learn Blockchains by Building One 本文原始链接 , 转载请注明出处。 作者认为最快的学习区块链的方式是自己创建一个,本文就跟随作者用 Python 来创建一个区块链。 对...

独钓渔
05/03
25
0
用Python从零开始创建区块链1

作者认为最快的学习区块链的方式是自己创建一个,本文就跟随作者用Python来创建一个区块链。 对数字货币的崛起感到新奇的我们,并且想知道其背后的技术——区块链是怎样实现的。 但是完全搞懂...

雪花又一年
2018/04/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

python学习10.04:Python list列表使用技巧及注意事项

前面章节介绍了很多关于 list 列表的操作函数,细心的读者可能会发现,有很多操作函数的功能非常相似。例如,增加元素功能的函数有 append() 和 extend(),删除元素功能的有 clear()、 remo...

太空堡垒185
22分钟前
4
0
新手插画学习的方法?教你如何自学?

插画学习的方法?教你如何自学? 从小喜欢画一些漫画头像随笔画,但是其实没有基础。个人偏好小清新手绘风的插画(如下图),每每看到都希望自己能画出这样的作品。 我其实很想说画这种美术功...

huihuajiaocheng
28分钟前
4
0
面试题

1、实现clone();

gtandsn
39分钟前
5
0
CentOS 7 部署 tesseract-ocr

官方地址 github yum-config-manager --add-repo https://download.opensuse.org/repositories/home:/Alexander_Pozdnyakov/CentOS_7/ 若提示 yum-config-manager: command not found 执行以......

阿白
39分钟前
3
0
JAVA比较器中comparator的使用

一个专用的比较器Comparator Comparator是一个专用的比较器,当一个不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。Comparator体现了一种策略模式...

daxiongdi
40分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部