设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 数据 手机 公司
当前位置: 首页 > 运营中心 > 建站资源 > 经验 > 正文

PHP也能实现区块链?基础结构篇

发布时间:2018-08-17 17:36 所属栏目:19 来源:列旭松
导读:技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战 引言 什么是区块链?官方的解释是:区块链是一个分布式记账系统,是藉用密码学串接并保护其内容的串连交易记录(又称区块)。每一个区块包含了前一个区块的加密散列、对应的时间戳
技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战

PHP也能实现区块链?基础结构篇

引言

什么是区块链?官方的解释是:区块链是一个分布式记账系统,是藉用密码学串接并保护其内容的串连交易记录(又称区块)。每一个区块包含了前一个区块的加密散列、对应的时间戳记以及交易数据(通常用默克尔树算法计算的散列值表示),这样的设计使得区块内容具有难以被窜改的特性。用区块链所串接的分布式账本能让两方有效率地纪录交易,且此交易可永久被查验。

但这个解释对于初学者来说太抽象了,所以接下来我们将会使用PHP来实现一个简易的区块链来加深对区块链的理解。

区块

大家应该玩过成语接龙,规则是这样:我先说一个成语“人上人海”,下一个玩家需要使用我说的成语的最后一个字作为下一个成语的开头,就是说需要使用“海”这个字作为新成语的开头,这时就可以接一个“海阔天空”。

而区块链的形式有点像成语接龙,就是下一个区块必须使用上一个区块的Hash值作为凭据来生成下一个区块。如下图:

PHP也能实现区块链?基础结构篇

这样做的好处是:从任意一个区块开始都可以通过前一个区块的Hash值可以不断的追溯整条区块链,直到创世区块(也就是区块链的第一个区块)。如果有人恶意攻击,也必须更改整条区块链的数据。但是计算Hash值是一个耗时的操作,所以要更改整条区块链的数据基本是不可能达到,这就保证了区块链的安全性。

下面我们使用PHP代码来定义区块:

  1. <php  
  2. class Block {  
  3.     public $prevHash;  
  4.     public $hash;  
  5.     public $timeStamp;  
  6.     public $data;  

prevHash、hash和timeStamp这几个字段在区块链中被称为区块头,区块的Hash值使用SHA-256算法计算。计算方法如下:

  1. <php  
  2. class Block {  
  3.     ...  
  4.     public function setBlockHash() {  
  5.         $data = serialize($this);  
  6.         $this->hash = hash('sha256', $data);  
  7.     }  
  8. }  

首先我们使用serialize()函数把整个区块序列化,然后使用hash()函数计算区块的Hash值,并赋值给hash字段。

区块对象的构造函数如下:

  1. <php  
  2. class Block {  
  3.     ...  
  4.     public function __construct($prevHash, $data) {  
  5.         $this->prevHash = $prevHash;  
  6.         $this->timeStamp = time();  
  7.         $this->data = $data;  
  8.         $this->setBlockHash();  
  9.     }  
  10. }  

另外我们提供一个获取区块Hash值的方法:

  1. <?php  
  2. class Block  
  3. {  
  4.     ...  
  5.     public function getBlockHash()  
  6.     {  
  7.         return $this->hash;  
  8.     }  

区块链

前面说了,区块链就是按照一定的规则连接起来的区块,连接的规则就是下一个区块的区块头中必须包含前一个区块的Hash值。我们编写一个区块链对象来保存整条区块链,代码如下:

  1. <?php  
  2. include('block.php');  
  3. class Blockchain  
  4. {  
  5.     public $blocks = [];  
  6. }  

区块链对象内部使用了一个数组来保存所有的区块,现阶段我们还没有使用到数据库来保存区块链,所以现在只需要把区块链保存在内存即可。

向区块链添加一个新的区块代码如下:

  1. <?php  
  2. include('block.php'); 
  3. class Blockchain 
  4. {  
  5.     ...  
  6.     public function addBlock($data)  
  7.     {  
  8.         $prevBlock = $this->blocks[count($this->blocks)-1];  
  9.         $this->blocks[] = new Block($prevBlock->getBlockHash(), $data);  
  10.     } 
  11. }  

因为生成新区块必须包含前一个区块的Hash值,所以在添加新区块时需要获取区块链中最后一个区块作为新区块的前一个区块,然后把前一个区块的Hash包含到新区块的区块头中。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读