<?php
/**
* 区块链相关算法
*/
class Block
{
public $timestamp; //时间
public $index; //索引
public $data; //数据
public $prevHash; //上一个哈希值
public $hash; //当前哈希值
public function __construct($index, $timestamp, $data, $prevHash = '')
{
$this->index = $index;
$this->timestamp = $timestamp;
$this->data = $data;
$this->prevHash = $prevHash;
$this->hash = $this->calculateHash();
}
/**
* 加密算法
* @return string
*/
public function calculateHash()
{
return hash('sha256', $this->index . $this->prevHash . $this->timestamp . json_encode($this->data));
}
}
/**
* 区块链
* Class BlockChain
*/
class BlockChain
{
public $chain = []; // Block[]
public function __construct()
{
$this->chain = [$this->createGenesisBlock()];
}
/**
* 创世区块
* @return Block
*/
public function createGenesisBlock()
{
return new Block(0, '2017-01-23', 'forecho', '0');
}
/**
* 获取最新的区块
* @return Block|mixed
*/
public function getLatestBlock()
{
return $this->chain[count($this->chain) - 1];
}
/**
* 添加区块
* @param Block $newBlock
*/
public function addBlock(Block $newBlock)
{
$newBlock->prevHash = $this->getLatestBlock()->hash;
$newBlock->hash = $newBlock->calculateHash();
array_push($this->chain, $newBlock);
}
/**
* 验证区块链
* @return bool
*/
public function isChainValid()
{
for ($i = 1; $i < count($this->chain); $i++) {
$currentBlock = $this->chain[$i];
$prevBlock = $this->chain[$i - 1];
if ($currentBlock->hash !== $currentBlock->calculateHash()) {
return false;
}
if ($currentBlock->prevHash !== $prevBlock->hash) {
return false;
}
}
return true;
}
}
// test
$blockChain = new BlockChain();
$blockChain->addBlock(new Block(1, '2017-02-23', ['amount' => 1]));
$blockChain->addBlock(new Block(2, '2017-03-23', ['amount' => 3]));
$blockChain->addBlock(new Block(3, '2017-04-23', ['amount' => 20]));
print_r($blockChain);
echo "区块链验证通过吗?" . ($blockChain->isChainValid() ? '通过' : '失败') . PHP_EOL;
$blockChain->chain[1]->data = ['amount' => 2];
$blockChain->chain[1]->hash = $blockChain->chain[1]->calculateHash();
echo "区块链验证通过吗?" . ($blockChain->isChainValid() ? '通过' : '失败') . PHP_EOL;