用php来实现一个区块链例子

用php来实现一个区块链例子

用php来实现一个<a href='/tag/blockchain.html'>区块链</a>例子

区块链的技术最近被国家提到战略高度,那么什么是区块链呢?为啥要用区块链呢?怎么开发区块链?带着这些问题,我们一步一步来揭晓答案。

一、什么是区块链

我们先说一个例子,传统的线上交易都是通过银行系统来实现,A公司汇款给B公司1万元,那么A公司在银行的存款余额就减去1万,B公司的银行存款就会增加1万,所有的交易都是通过银行进行,因为我们相信银行,相信银行的系统,那么有没有一种可能,我们不需要银行,A与B之间可以直接交易呢?那有的朋友直接说“可以交易,现金交易呗”,没错,是可以,但是如果采用电子形式的交易呢,A与B如果缺乏信任,那么在武第三方银行的情况下还无法直接交易,那么如果有一种技术来保证双方的电子账本不可伪造、篡改、可追溯等要求,是不是就能实现直接交易了,A在自己的账本上记一笔账减少1万元,B在自己的账本上加一条增加一万元,而且账本信息无法修改,这个有点类似于大学时期的食堂刷卡机,每个卡上都有余额,在进行交易的时候扣除金额,并且记录账本,而且这个账本是公开防修改的,也就是你是改不了余额的。这种不可伪造、篡改、可追溯的技术就叫做区块链技术。

用php来实现一个<a href='/tag/blockchain.html'>区块链</a>例子

可以理解为一个分布式的账本,一个人的账本丢了,还可以通过其他的人找回自己的账本,无需依赖中心,也就是去中心化。

二、区块链的优势

区块链的主要优势就是不可伪造、篡改、可追溯,这些特性决定了他的使用场景。

用php来实现一个<a href='/tag/blockchain.html'>区块链</a>例子

想想看,未来的身份证会加入区块链技术,身份证是区块链钱包、里面记录了你的个人信息、账户余额、交易流水、信用信息、无需联网就能实现交易、区块链技术将彻底改变现在的生活,去政府部门办事,无需开各种证明、你的身份证里记录了你的一切,身份证丢了也没事,其他人的也记录你的信息,是该不掉了,这将极大的提高工作效率,降低成本,这也是为什么政府在大力推进区块链的原因,区块链技术将彻底更变我们的生活,让生活更便捷,获取你认为现在的支付宝微信很便捷,但是一旦区块链钱包出来后,他会更便捷,因为他不需要联网,对不对点直接交易。

三、php中如何开发一个区块链

1 区块头

用php来实现一个<a href='/tag/blockchain.html'>区块链</a>例子

区块头主要包含的三组元数据分别是:(1)用于连接前面的区块、索引自父区块哈希值的数据;(2)挖矿难度、时间戳、Nonce(随机数,用于工作量证明算法的计数器,也可理解为记录解密该区块相关数学题的答案的值);(3)能够总结并快速归纳校验区块中所有交易数据的Merkle(默克尔)树根数据。当然区块头不仅仅包含这些元数据,还有其他比如:版本号、难度值等(以上这些生涩的名称不懂没关系,后面几篇文章都会分析这些技术)。

从这个结构来看,区块链的大部分功能都由区块头实现。

2 区块主体

区块主体所记录的交易信息是区块所承载的任务数据,具体包括交易双方的私钥、交易的数量、电子货币的数字签名等。

3 链

比特币系统大约每10分钟会创建一个区块,这个区块包含了这段时间里全网范围内发生的所有交易。每一个区块都保存了上一个区块的哈希值,使得每个区块都能找到其前一个区块,这样就将这些区块连接起来,形成了一个链式的结构。

4 区块的形成过程

在当前区块加入区块链后,所有矿工就立即开始下一个区块的生成工作:(1)把在本地内存中的交易信息记录到区块主体中;(2)在区块主体中生成此区块中所有交易信息的Merkle树,把Merkle树根的值保存在区块头中;(3)把上一个刚刚生成的区块的区块头的数据通过SHA256算法生成一个哈希值填入到当前区块的父哈希值中;(4)把当前时间保存在时间戳字段中;(5)难度值字段会根据之前一段时间区块的平均生成时间进行调整,以应对整个网络不断变化的整体计算总量,如果计算总量增长了,则系统会调高数学题的难度值,使得预期完成下一个区块的时间依然在一定时间内。

ok,我们来用php实现一下

先建一个block类

<?php
class Block
{
    public $nonce;

    public function __construct($index, $timestamp, $data, $previousHash = null)
    {
        $this->index = $index;
        $this->timestamp = $timestamp;
        $this->data = $data;
        $this->previousHash = $previousHash;
        $this->hash = $this->calculateHash();
        $this->nonce = 0;
    }

    public function calculateHash()
    {
        return hash("sha256", $this->index.$this->previousHash.$this->timestamp.((string)$this->data).$this->nonce);
    }
}

然后建一个块类

<?php
require_once("block.php");

/**
 * A simple blockchain class with proof-of-work (mining).
 */
class BlockChain
{
    /**
     * Instantiates a new Blockchain.
     */
    public function __construct()
    {
        $this->chain = [$this->createGenesisBlock()];
        $this->difficulty = 4;
    }

    /**
     *创建区块
     */
    private function createGenesisBlock()
    {
        return new Block(0, strtotime("2017-01-01"), "Genesis Block");
    }

    /**
     *获取最后的区块
     */
    public function getLastBlock()
    {
        return $this->chain[count($this->chain)-1];
    }

    /**
     * Pushes a new block onto the chain.
     */
    public function push($block)
    {
        $block->previousHash = $this->getLastBlock()->hash;
        $this->mine($block);
        array_push($this->chain, $block);
    }

    /**
     * 挖矿
     */
    public function mine($block)
    {
        while (substr($block->hash, 0, $this->difficulty) !== str_repeat("0", $this->difficulty)) {
            $block->nonce++;
            $block->hash = $block->calculateHash();
        }

        echo "Block mined: ".$block->hash."\n";
    }

    /**
     *验证是否有效
     */
    public function isValid()
    {
        for ($i = 1; $i < count($this->chain); $i++) {
            $currentBlock = $this->chain[$i];
            $previousBlock = $this->chain[$i-1];

            if ($currentBlock->hash != $currentBlock->calculateHash()) {
                return false;
            }

            if ($currentBlock->previousHash != $previousBlock->hash) {
                return false;
            }
        }

        return true;
    }
}

好了,我们来往链上写入

<?php
require_once('../blockchain.php');

/*
创立一个简单的区块链
*/

$testCoin = new BlockChain();

echo "挖出 block 1...\n";
$testCoin->push(new Block(1, strtotime("now"), "amount: 4"));

echo "挖出 block 2...\n";
$testCoin->push(new Block(2, strtotime("now"), "amount: 10"));

echo json_encode($testCoin, JSON_PRETTY_PRINT);
?>

项目webide地址:http://studio.bfw.wiki/Studio/Open.html?projectid=15766625657015350054


{{collectdata}}

网友评论0