区块链是什么?作为一个Ruby开发者,理解区块链的最好办法,就是亲自动手实现一个。只需要50行Ruby代码你就能彻底理解区块链的核心原理!

区块链 = 区块组成的链表?

blockchain.ruby

class Block

  attr_reader :timestamp
  attr_reader :data
  attr_reader :previous_hash
  attr_reader :hash

  def initialize(data, previous_hash)
    @timestamp     = Time.now
    @data          = data
    @previous_hash = previous_hash
    @hash          = calc_hash
  end

  def self.first( data="Genesis" )    # create genesis (big bang! first) block
    ## note: uses all zero for previous_hash ("0")
    Block.new( data, "0000000000000000000000000000000000000000000000000000000000000000" )
  end

  def self.next( previous, data="Transaction Data..." )
    Block.new( data, previous.hash )
  end

private

  def calc_hash
    sha = Digest::SHA256.new
    sha.update( @timestamp.to_s + @previous_hash + @data )
    sha.hexdigest
  end

end  # class Block

#####
## let's get started
##   build a blockchain a block at a time

b0 = Block.first( "Genesis" )
b1 = Block.next( b0, "Transaction Data..." )
b2 = Block.next( b1, "Transaction Data......" )
b3 = Block.next( b2, "More Transaction Data..." )

blockchain = [b0, b1, b2, b3]

pp blockchain

执行上面程序:

~$ ruby blockchain.rb

将会输出类似下面的结果:

[#<Block:0x1eed2a0
  @timestamp     = 1637-09-15 20:52:38,
  @data          = "Genesis",
  @previous_hash = "0000000000000000000000000000000000000000000000000000000000000000",
  @hash          = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b">,
 #<Block:0x1eec9a0
  @timestamp     = 1637-09-15 21:02:38,
  @data          = "Transaction Data...",
  @previous_hash = "edbd4e11e69bc399a9ccd8faaea44fb27410fe8e3023bb9462450a0a9c4caa1b",
  @hash          = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743">,
 #<Block:0x1eec838
  @timestamp     = 1637-09-15 21:12:38,
  @data          = "Transaction Data......",
  @previous_hash = "eb8ecbf6d5870763ae246e37539d82e37052cb32f88bb8c59971f9978e437743",
  @hash          = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4">,
 #<Block:0x1eec6d0
  @timestamp     = 1637-09-15 21:22:38,
  @data          = "More Transaction Data...",
  @previous_hash = "be50017ee4bbcb33844b3dc2b7c4e476d46569b5df5762d14ceba9355f0a85f4",
  @hash          = "5ee2981606328abfe0c3b1171440f0df746c1e1f8b3b56c351727f7da7ae5d8d">]

你先等等,难道区块链就是链表吗?

当然不是。我们使用链表的目的是获得指向前一个块的引用:在区块链中,每个块都必须有一个标识符,而这个标识符还必须依赖于前一个块的标识符,这意味着如果你要替换区块链中的一个块,就必须重算后面所有块的标识符。在上面的实现中,你可以看到我们调用calc_hash方法计算块的标识符时,需要传入前一个块的签名,就是这个意思。

那工作量证明算法呢?

现在让我们添加工作量证明算法的实现。在经典的区块链中,你必须通过计算得到00开头的哈希作为块的标识符,前缀的0越多,计算量就越大,也就越困难。出于简单考虑,让我们将难度设定为两个前缀0,也就是说,2^16 = 256种可能。

blockchain_with_proof_of_work.rb:

def compute_hash_with_proof_of_work( difficulty="00" )
  nonce = 0
  loop do
    hash = calc_hash_with_nonce( nonce )
    if hash.start_with?( difficulty )
      return [nonce,hash]     ## bingo! proof of work if hash starts with leading zeros (00)
    else
      nonce += 1              ## keep trying (and trying and trying)
    end
  end
end

def calc_hash_with_nonce( nonce=0 )
  sha = Digest::SHA256.new
  sha.update( nonce.to_s + @timestamp.to_s + @previous_hash + @data )
  sha.hexdigest
end

现在我们运行这个增加了POW机制的区块链程序:

~$ ruby blockchain_with_proof_of_work.rb

输出结果如下:

[#<Block:0x1e204f0
  @timestamp     = 1637-09-20 20:13:38,
  @data          = "Genesis",
  @previous_hash = "0000000000000000000000000000000000000000000000000000000000000000",
  @nonce         = 242,
  @hash          = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf">,
 #<Block:0x1e56e20
  @timestamp     = 1637-09-20 20:23:38,
  @data          = "Transaction Data...",
  @previous_hash = "00b8e77e27378f9aa0afbcea3a2882bb62f6663771dee053364beb1887e18bcf",
  @nonce         = 46,
  @hash          = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af">,
 #<Block:0x1e2bd58
  @timestamp     = 1637-09-20 20:33:38,
  @data          = "Transaction Data......",
  @previous_hash = "00aae8d2e9387e13c71b33f8cd205d336ac250d2828011f5970062912985a9af",
  @nonce         = 350,
  @hash          = "00ea45e0f4683c3bec4364f349ee2b6816be0c9fd95cfd5ffcc6ed572c62f190">,
 #<Block:0x1fa8338
  @timestamp     = 1637-09-20 20:43:38,
  @data          = "More Transaction Data...",
  @previous_hash = "00ea45e0f4683c3bec4364f349ee2b6816be0c9fd95cfd5ffcc6ed572c62f190",
  @nonce         = 59,
  @hash          = "00436f0fca677652963e904ce4c624606a255946b921132d5b1f70f7d86c4ab8">]

你看到和前一个版本的差别的吗?现在所有的hash都是00开头的,nonce则是获得这个符合条件

的哈希时所采用的随机幸运数字。

50行ruby代码开发一个区块链的更多相关文章

  1. 40多行python代码开发一个区块链。

    40多行python代码开发一个区块链?可信吗?我们将通过Python 2动手开发实现一个迷你区块链来帮你真正理解区块链技术的核心原理.python开发区块链的源代码保存在Github. 尽管有人认为 ...

  2. 50行Python代码构建小型区块链

    本文介绍了如何使用python构建一个小型的区块链技术,使用Python2实现,代码不到50行. Although some think blockchain is a solution waitin ...

  3. 300行Kotlin代码实现的区块链

    使用Kotlin实现的区块链基本逻辑! 源码地址 GitHub仓库 启动方式 启动参数添加 -Dserver.port=8080,启动不同的端口,模拟不同的节点. 假设目前启动了8080和8081两个 ...

  4. 只用120行Java代码写一个自己的区块链

    区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大家都非常想了解这一切是如何工作的.这篇文章就是帮助你使用 Java 语言来实现一个简单的区块链,用不到 120 行代码来揭示区 ...

  5. 只用200行Go代码写一个自己的区块链!

    Coral Health · 大约23小时之前 · 220 次点击 · 预计阅读时间 7 分钟 · 不到1分钟之前 开始浏览 区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大 ...

  6. 只用200行Go代码写一个自己的区块链!(转)

    区块链是目前最热门的话题,广大读者都听说过比特币,或许还有智能合约,相信大家都非常想了解这一切是如何工作的.这篇文章就是帮助你使用 Go 语言来实现一个简单的区块链,用不到 200 行代码来揭示区块链 ...

  7. [区块链\理解BTCD源码]GO语言实现一个区块链原型

    摘要 本文构建了一个使用工作量证明机制(POW)的类BTC的区块链.将区块链持久化到一个Bolt数据库中,然后会提供一个简单的命令行接口,用来完成一些与区块链的交互操作.这篇文章目的是希望帮助大家理解 ...

  8. 用JavaScript写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  9. 怎么用JavaScript写一个区块链?

    几乎所有语言都可以编写区块链开发程序.那么如何用JavaScript写一个区块链?以下我将要用JavaScript来创建1个简单的区块链来演示它们的内部到底是怎样工作的.我将会称作SavjeeCoin ...

随机推荐

  1. android 优化之布局优化

    布局优化的思路很简单,尽量减少布局文件的层级,看过系统源码的都知道,Android view绘制都是逐层绘制的,所以布局的层级少了,decodeview的时候绘制工作自然就少了. 那么如何进行布局的优 ...

  2. Universal-Image-Loader完全解析--从源代码分析Universal-Image-Loader中的线程池

    一般来讲一个网络访问就需要App创建一个线程来执行,但是这也导致了当网络访问比较多的情况下,线程的数目可能积聚增多,虽然Android系统理论上说可以创建无数个线程,但是某一时间段,线程数的急剧增加可 ...

  3. 数据结构基础(3) --Permutation & 插入排序

    Permutation(排列组合) 排列问题: 设R = {r1, r2, ... , rn}是要进行排列的n个元素, Ri = R-{ri}; 集合X中元素的全排列记为Permutation(X), ...

  4. 【一天一道LeetCode】#328 Odd Even Linked List

    一天一道LeetCode系列 (一)题目 Given a singly linked list, group all odd nodes together followed by the even n ...

  5. ubuntu下eclipse新建项目没有java project的解决办法

    装好了eclipse之后却发现新建项目没有java project的选项,大致搜索了一下,并没有发现很好的解决方案(大都是让你重新安装什么的),于是开始瞎鼓捣,并且找到了一个方案: 在终端切换到roo ...

  6. TCP的核心系列 — ACK的处理(二)

    本文主要内容:tcp_ack()中的一些细节,如发送窗口的更新.持续定时器等. 内核版本:3.2.12 Author:zhangskd @ csdn 发送窗口的更新 什么时候需要更新发送窗口呢? (1 ...

  7. C语言实现快速翻转数组的顺序

    #include <stdio.h> void Reverse(int *p , int size) { int i , tmp; for(i = 0 ; i < size/2 ; ...

  8. Python和shell中Base64编码使用那些事

    做开发第一个接触的编码方式就是Base64,当时是用url来传输一些参数,传输的两端会用Base64来编码和解码,保证数据不被url转义破坏. 下面是 维基百科 Base64 中的介绍,其实自己实现起 ...

  9. HBase replication使用

    hbase-0.90.0的一个重要改进是引入了replication机制,使它的数据完整性得到了进一步的保障.虽然这一功能还不太完善,但是今后必然会变得更加重要. hbase的replication机 ...

  10. LeetCode(43)-Contains Duplicate II

    题目: Given an array of integers and an integer k, find out whether there are two distinct indices i a ...