jjzjj

61行代码构建最简单区块链

小草cys 2024-02-08 原文

首先,我导入了 hashlibdatetime,让我们分别计算哈希和时间戳块。

导入是将代码从一个模块传输到另一个模块的修改。如果没有 datetime 导入,我的区块链将无法处理时间戳,或者在没有 hashlib 导入的情况下无法创建哈希。

区块链包含两个类:Block类和Blockchain类。添加到区块链的每个块都使用Block类进行相同的建模。

块类

该块必须包含以下属性:

  • 区块的编号,设置为 0,因为它是链中的第一个区块,称为创世区块
  • 数据,设置为无
  • 接下来,设置为无。这充当了指向下一个块的指针,继续链接的趋势。
  • 哈希,设置为无。块的散列是至关重要的,因为它是使区块链如此安全和不可变的密码学的一部分。
  • nonce,设置为 0。 nonce 是一个随机整数,一遍又一遍地迭代,直到找到“Golden Nonce”。在工作量证明中,矿工们首先竞争找到正确的哈希值。随机数更改多次,直到它有助于生成正确的哈希。这样就完成了区块的验证,区块就可以加入链中了。
  • 前一个哈希,设置为 0x0。存储前一个块的散列使区块链不可变,因为更改一个块的散列会影响所有后续块。
  • 时间时间戳,描述交易发生的时间,用于同步网络中的所有块。

Block类,它确定添加到链中的每个块的标准

当我们创建一个块时,我们存储它的数据。构造函数init初始化类的属性。自我数据表示将包含在对象(块)中的内容。

哈希

下一步是添加哈希函数,计算区块的哈希值。

noncedata前一个 hashtimestamp块号放入一个字符串并通过 SHA-256 函数运行。SHA-256 是一种常用于区块链的加密哈希算法。“ h ”是使用 SHA-256 的变量。因为我在代码开头导入了hashlib,所以可以使用SHA-256。散列函数中的所有组件将创建块的散列,在创建新块时将其添加到散列字段中。

图片中的最后一行描述了将在输出中显示的内容或打印的内容。在这种情况下,输出将显示块的哈希块号

区块链类

下一步是创建代码的第二个类:Blockchain类。区块链类包括:

  • 难度,设置为20。通过增加难度,我们有效地减小了目标范围。减小目标范围会使挖掘块变得更加困难,这在处理具有许多节点的网络时非常有用以找到可接受的哈希值。

  • 最大随机数,设置为 2 的 32 次方,即 32 位数字中可以存储的最大数。随机数必须小于要接受的目标数
  • 目标数,设置为 2 的 256 次方减去难度。在这种情况下,难度为 20。

区块链中的第一个块是创世块,如第 34 行所示。现在,我完全陷入了下一行代码:dummy = head = block。任何链表的开头都称为head。由于我们的链表的头部是创世块,我们在代码中将其写为head = block。然而,仅此一点还不够具体——在 Python 中,对象是通过引用传递的。Headblock会指向同一个东西。必须在head变量(在本例中为dummy )之前写入一个随机变量,以告诉计算机head与block指向的对象不同。

添加块

我们将继续认为区块链是add函数的链表,用于将块添加到链中。

区块链在哈希的帮助下形成一个链表。哈希将块联系在一起,使其不可变。前一个哈希(第 39 行)必须设置为等于当前位于列表顶部的块。然后,将新块设置为等于当前块加一,如第三行代码所示。

最后两行有助于形成区块链的形状。如“self.block.next = block”所示,每个块都有一个指向下一个块的指针,因此下一个指针被设置为块。这会将块添加到列表的末尾。下一行“self.block = self.block.next”将指针向前移动以继续将块添加到列表末尾的趋势。

矿业

接下来我添加了一个挖矿功能。我使用了工作量证明共识机制,比如比特币。为了将块添加到链中,节点会尝试不同的随机数,直到找到小于目标范围的哈希值。

第 46 行开始一个循环。它首先设置一些猜测准则(范围),从 0 到最大随机数。它在第 47 行继续检查当前块的哈希是否小于或等于目标。哈希必须在 Python 中转换为整数,因此是int。如果哈希值低于目标值,该过程将继续,并且可以添加块(第 48 行)。接下来,打印块,最后,我们暂停挖矿。但是,如果哈希不小于目标数,我们将随机数加 1 并重试。

整理起来

我们以从第 56 行开始的循环结束我们的代码。它计算 10 个随机块。你可以玩弄这些数字,但它总是会停在你插入的任何整数处。

第 60 行提示打印 10 个块。一旦你完成了这条线,你就正式完成了!运行几次以检查错误并欣赏您的作品。仅用 61 行代码,您就创建了一个可以生成块、计算哈希并将所有内容放在一起的区块链!

整体代码如下

import datetime
import hashlib

class Block:
    blockNo = 0
    data = None
    next = None
    hash = None
    nonce = 0
    previous_hash = 0x0
    timestamp = datetime.datetime.now()

    def __init__(self, data):
        self.data = data

    def hash(self):
        h = hashlib.sha256()
        h.update(
        str(self.nonce).encode('utf-8') +
        str(self.data).encode('utf-8') +
        str(self.previous_hash).encode('utf-8') +
        str(self.timestamp).encode('utf-8') +
        str(self.blockNo).encode('utf-8')
        )
        return h.hexdigest()

    def __str__(self):
        return "Block Hash: " + str(self.hash()) + "\nBlockNo: " + str(self.blockNo) + "\nBlock Data: " + str(self.data) + "\nHashes: " + str(self.nonce) + "\n--------------"

class Blockchain:

    diff = 20
    maxNonce = 2**32
    target = 2 ** (256-diff)

    block = Block("Genesis")
    dummy = head = block

    def add(self, block):

        block.previous_hash = self.block.hash()
        block.blockNo = self.block.blockNo + 1

        self.block.next = block
        self.block = self.block.next

    def mine(self, block):
        for n in range(self.maxNonce):
            if int(block.hash(), 16) <= self.target:
                self.add(block)
                print(block)
                break
            else:
                block.nonce += 1

blockchain = Blockchain()

for n in range(10):
    blockchain.mine(Block("Block " + str(n+1)))

while blockchain.head != None:
    print(blockchain.head)
    blockchain.head = blockchain.head.next

有关61行代码构建最简单区块链的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  4. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  5. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  6. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  7. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  8. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  9. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  10. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

随机推荐