2018-04-01 区块链实践01:实现最简区块链

引用“50行python代码的区块链SnakeCoin”,Gerald NashJul 16, 2017 原文见底
一年前的老文章。比起大量的概念炒作文章,这短短的五十行代码更贴切地展示了区块链的核心概念。

轻定义
区块链在更通用的术语中,是指一个公共数据库。在这个数据库中,新数据存储在一个名为 Block 的容器中,并将其添加到一个不可变链中。
数据也可以是任何类型。对于比特币和其他加密货币,这些数据是一组交易。

  1. 定义一个 Block区块 class
    每个块都存储五个数据:一个时间戳time stamp,一个索引 index(不必要),数据data(可以是任何内容),前一个block的hash值和自己的hash值。自己的hash值是通过对 Block 的索引、时间戳、数据做哈希加密得到的。
    本例中由hashlib包完成:产生一个sha256()初始值,然后产生一个超长的字符串(index+timestamp+data+prev_hash),最后用这个字符串来更新初始值。
    比特币也是如此,
# Python 2
import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()

  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) + 
               str(self.timestamp) + 
               str(self.data) + 
               str(self.previous_hash))
    return sha.hexdigest()
# Python 3: need encode for sha.update
import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()

  def hash_block(self):
    sha = hasher.sha256()
    sha.update((str(self.index) + 
               str(self.timestamp) + 
               str(self.data) + 
               str(self.previous_hash)).encode())
    return sha.hexdigest()

注意!由于区块链的第一个区块没有“前一个区块”。所以创世块(genesis block)是一个特殊的块。在很多情况下,它是手动添加的,或者有独特的逻辑允许添加。


创世记——米开朗基罗
  1. 生成创世块的方法
    这里使用手动方法生成第一个区块。
    其索引index为0,时间戳为方法被使用时的时间,包含的数据为字符串“Genesis Block”(可以为任何内容,比如“Hello World :D”),前一个区块的hash值为“0”(可以为任何内容,比如“3.1415926”)。
import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", "0")

有了这段代码,我们就得到创世块了。其后的每一个block都可以通过之前的定义取得。

  1. 区块链中生成后续的块
    将链中的前一个 Block 作为参数,创建一个新Block的数据(新的 Block 的 hash 值依赖于前一个 Block 的哈希值),然后生成并返回新块。
def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data, this_hash)

last_block意指链尾块。取得其数据后,新的block数据依赖其index
和Hash。

#觉得很奇怪,应该把数据当做参数输入才对吧。不然数据越来越多。
def next_block(last_block, new_data):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = str(new_data)
  return Block(this_index, this_timestamp, this_data, last_block.hash)
  1. 创建我们的区块链
# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash)
# 所有网站贴的结果图都一样,没意思不贴了。

本例子中,区块链本身就是一个简单的 Python 列表(单向链表?)。
列表的第一个元素是创世块(genesis block)。 接着添加后续的块。例子中添加了 20 个新的块。 用 for 循环实现。

这里只是实现了区块链最最基础部分的代码, 如果想让 SnakeCoin 运作起来 ,我们必须添加更多的功能,如服务器层,以跟踪多台机器上链的变化,并提供工作证明算法,以限制在限定时间内允许添加 Block 的数量。

(作为偷懒,暂时跳过第二部分,有兴趣回头看吧)

原文:(Gerald NashJul 16, 2017)
第一部分:https://medium.com/crypto-currently/lets-build-the-tiniest-blockchain-e70965a248b
第二部分:https://medium.com/crypto-currently/lets-make-the-tiniest-blockchain-bigger-ac360a328f4d
参考翻译:
https://www.jianshu.com/p/c805e4b955ca (部分翻译不充分)
http://www.gongxiangcj.com/posts/39301

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 下班后和敖先生一起去体育场打了一场羽毛球,看着他玩了一下篮球投篮。上一次打篮球把脚崴了,现在还心有余悸,索性便看着...
    潇十然阅读 647评论 0 3
  • 草莓妈妈每次对草莓说爱你之后都会亲亲草莓的脸蛋或者脑门,之前草莓总是口头回答说爱妈妈,但是不会有肢体动作。 照例,...
    王半天阅读 509评论 0 50
  • 头七那天晚上,她穿上了那身压在箱底多年的戏服。 翻箱倒柜,又找出了个落满尘污的妆盒。 “我的戏班不缺戏子。” 漫天...
    白衣夜锦阅读 423评论 0 2