PHP编写区块链怎么获利,PHP从零实现区块链(一)基本原型

前言

学习区块链有些时间了,根据大佬的文章用Go也实现了一遍,但作用一名web码农,平时用的最多的还是PHP,所以打算用PHP再搞一搞,当是复习了。本教程基于LaravelZero(因为构建命令行省事儿)简单构建一个属于你的区块链,如果你有一些区块链的前置知识那就最好不过啦。

参考文章:

初始化

根据 LaravelZero 文档,先创建一个项目,确保能顺利跑起来。

在app目录下创建 Services 文件夹,咱们的代码都写在这里面。

区块链是什么

简单来说,区块链是一个提供了拜占庭容错、并保证了最终一致性的分布式数据库;从数据结构上看,它是基于时间序列的链式数据块结构;从节点拓扑上看,它所有的节点互为冗余备份;从操作上看,它提供了基于密码学的公私钥管理体系来管理账户。

组成区块链的核心技术主要有:

P2P 网络协议

分布式一致性算法

加密签名算法

账户与存储模型

在本文中,我们将利用数组来存储区块,来实现区块链的基本原型。

区块

在区块链中,真正存储有效信息的是区块(block)。

那就创建一个区块,在 App/Services 目录新建一个 Block.php。

namespace App\Services;

use Carbon\Carbon;

class Block

{

/**

* 当前时间戳,也就是区块创建的时间

* @var int $timestamp

*/

public $timestamp;

/**

* 区块存储的信息,也就是交易

* @var string $data

*/

public $data;

/**

* 前一个块的哈希,即父哈希

* @var string $prevBlockHash

*/

public $prevBlockHash;

/**

* 当前块的哈希

* @var string $hash

*/

public $hash;

}

在比特币中,区块的结构主要有如下信息:

Field

Purpose

Size(Bytes)

Block Size

区块大小

4

Block Header

区块头

80

Transaction Counter

交易计数器

1~9

Transactions

交易

-

区块头的主要结构:

字段

描述

大小

Version

Block version number

4

hashPrevBlock

256-bit hash of the previous block header

32

hashMerkleRoot

256-bit hash based on all of the transactions in the block

32

Time

Current timestamp as seconds since 1970-01-01T00:00 UTC

4

Bits

Current target in compact format

4

Nonce

32-bit number (starts at 0)

4

其中交易(Transactions)也就是我们创建的 data 字段;而其他字段(prevBlockHash,timestamp)在比特币中由专门的数据结构,即区块头存储;另外为了方便,我们还加上了当前块的 hash 字段,在比特币中是没有直接存储当前块的哈希的。

为了方便,我们就不单独实现区块头了,而是所有数据都放在一起,这样我们就创建了一个简单的区块。

下面我们来完善区块的创建:

Block.php

public function __construct(string $data, string $prevBlockHash)

{

$this->prevBlockHash = $prevBlockHash;

$this->data = $data;

$this->timestamp = time();

$this->hash = $this->setHash();

}

public function setHash(): string

{

return hash('sha256', implode('', [$this->timestamp, $this->prevBlockHash, $this->data]));

}

区块链

本质上,区块链就是一个有着特定结构的数据库,是一个有序,每一个块都连接到前一个块的链表。也就是说,区块按照插入的顺序进行存储,每个块都与前一个块相连。这样的结构,能够让我们快速地获取链上的最新块,并且高效地通过哈希来检索一个块。

有了区块,下面让我们来实现区块链。在基本原型阶段,我们用数组来存放区块结构。新建一个文件 BlockChain.php

namespace App\Services;

class BlockChain

{

/**

* @var Block[] $blocks

*/

public $blocks;

public function __construct(Block $block)

{

$this->blocks[] = $block;

}

// 加入一个块到区块链中

public function addBlock(string $data)

{

$prevBlock = $this->blocks[count($this->blocks) - 1];

$newBlock = new Block($data, $prevBlock->hash);

$this->blocks[] = $newBlock;

}

}

addBlock() 方法使我们有了向链中添加区块的能力,但是还没完,在添加区块以前,区块链中应该存在一个创世区块。

// 初始化创世区块

public static function NewGenesisBlock()

{

$block = new Block('Genesis Block', '');

return new BlockChain($block);

}

大功告成,下面让我们来测试一下!

$bc = BlockChain::NewGenesisBlock();

$bc->addBlock('i am 2 block');

$bc->addBlock('i am 3 block');

dd($bc->blocks);

结果如下:

array:3 [

0 => App\Services\Block {#155

+timestamp: 1587700797

+data: "Genesis Block"

+prevBlockHash: ""

+hash: "e0ecf169c2ea5143743438fd91778ca6cdff1c870120c784f836650cfaaaff38"

}

1 => App\Services\Block {#153

+timestamp: 1587700797

+data: "i am 2 block"

+prevBlockHash: "e0ecf169c2ea5143743438fd91778ca6cdff1c870120c784f836650cfaaaff38"

+hash: "c33a37e9708a2871c6b03fd2f6468081edb4e96d911c7227ad84271d9c4f8b6d"

}

2 => App\Services\Block {#160

+timestamp: 1587700797

+data: "i am 3 block"

+prevBlockHash: "c33a37e9708a2871c6b03fd2f6468081edb4e96d911c7227ad84271d9c4f8b6d"

+hash: "de300a998179bfeeb3ea60be3f49e205f8552b8ab9d506a76d847f0ba9d93646"

}

]

NICE!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值