PHP从零实现区块链(网页版二)工作量证明

这篇具有很好参考价值的文章主要介绍了PHP从零实现区块链(网页版二)工作量证明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

源码地址:PHP从零实现区块链(二)工作量证明 - 简书

注:本例只是从网页版实现一下原理,源码非本人所写,只是将原帖的源码更改了一下,变成网页版

因为运行环境问题,本例暂时从windows转到ubuntu下,因为后面例子使用了gmp库的gmp_pow和gmp_cmp函数,而php在windows下暂时没有找到使用gmp的解决方案。

所以直接用ubuntu系统来运行本例,支持的比较友好。(后面看情况是否转回windows)

关于怎么在ubuntu下搭建php运行环境,可以参考我这篇文章:

ubuntu下安装php运行环境-CSDN博客

好了,接下来都是在ubuntu下操作。

因为要使用gmp_pow和gmp_cmp函数,我们需要安装gmp库。

打开终端输入如下命令安装:

udo apt-get install php-gmp

然后将gmp和php关联一下,如下命令:

sudo phpenmod gmp

但是显示文件模块不在php 8.1下。我一看是下了8.2相关的。

所以我们得加上版本号(你们看情况选择自己的版本号 php -v可查看你当前的php版本)

1.   sudo apt-get install php8.1-gmp

OK,然后运行

2.  sudo phpenmod gmp

接着再重启一下apache

3. sudo /etc/init.d/apache2 restart

好,正常的话,上面三步就能搞定了。

接着我们来个例子调用一下gmp_pow函数测试一下,求2的10次方,如下:

<?php

$pow1 = gmp_pow("2", 10); 

echo $pow1;

?>

结果:

PHP从零实现区块链(网页版二)工作量证明,# php从零实现区块链(网页版),php,开发语言

OK,接下来我们正式来研究这个例子.

首先我们新增ProofOfWork.php文件,代码如下:

<?php

define('targetBits',24);
class ProofOfWork
{
  
    /**
     * @var Block $block
     */
    public $block;

    /**
     * 目标值(计算结果要小于这个目标值才有效)
     * @var GMP $target
     */
    public $target;

    public function __construct(Block $block)
    {
       // $targetBits = config('blockchain.targetBits');

        $this->target = gmp_pow('2', (256 - targetBits));

        $this->block = $block;
    }
    public function prepareData(int $nonce): string
    {
        return implode('', [
            $this->block->timestamp,
            $this->block->prevBlockHash,
            $this->block->data,
            $nonce
        ]);
    }

    public function run(): array
    {
        $nonce = 0;
        $hash = '';
        while (true) {
            $data = $this->prepareData($nonce);
            $hash = hash('sha256', $data);
            if (gmp_cmp('0x' . $hash, $this->target) == -1) {
                break;
            }
            $nonce++;
        }
        return [$nonce, $hash];
    }
}

在里面,我做了一些更改,(config()因为要安装laravel框架来使用,这里我暂时先用常量代替。在下一章中再介绍安装。)

用下面两句代替config():

define('targetBits',24);

$this->target = gmp_pow('2', (256 - targetBits));

ProofOfWork 类解释:

block在得到前三个变量数据后,就把block通过ProofOfWork的构造函数传进去。

然后在ProofOfWork里的run()函数产生一个变动的数字nonce。再调用prepareData函数,把这个nonce和block的三个数据合在一起得到data返回去。

run()得到data后,就对data进行哈希运算,然后把哈希值和提前设定的哈希值比较,

如果小于设定的哈希值,那么就符合要求了。如果不符合,则nonce+1,把新数字放进去再进行哈希运算,如此循环,直到得到符合要求的哈希值,然后就把符合要求的nonce和哈希值传回去。

接下来就是block.php,我们要更改block类的构造函数。换proofOfwork来得到哈希值。

完整代码如下:

<?php
require_once 'ProofOfWork.php';
class Block
{
    /**
     * 当前时间戳,也就是区块创建的时间
     * @var int $timestamp
     */
    public $timestamp;

    /**
     * 区块存储的信息,也就是交易
     * @var string $data
     */
    public $data;

    /**
     * 前一个块的哈希,即父哈希
     * @var string $prevBlockHash
     */
    public $prevBlockHash;



    /**
     * 当前块的哈希 
     * @var string $hash
     */
    public $hash;
    public $nonce;

    public function __construct(string $data, string $prevBlockHash)
    {
        $this->prevBlockHash = $prevBlockHash;
        $this->data = $data;
        $this->timestamp = time();

        $pow = new ProofOfWork($this);
        list($nonce, $hash) = $pow->run();

        $this->nonce = $nonce;
        $this->hash = $hash;
    }

    public function setHash(): string
    {
        return hash('sha256', implode('', [$this->timestamp, $this->prevBlockHash, $this->data]));
    }
}

开头引用一下require_once 'ProofOfWork.php';

解释:这里添加了block的三个数据后,跟原先相比,要添加哈希值,不是采用setHash直接添加了。而是调用$pow->run找到符合要求的哈希值后,才进行添加。

OK,接着修改一下app.php如下:

<?php
require_once 'BlockChain.php';
$time1 = time();
$bc = BlockChain::NewGenesisBlock();
$bc->addBlock('i am 2 block');
$bc->addBlock('i am 3 block');
$time2 = time();

$spend = $time2 - $time1;
foreach ($bc->blocks as $block){
    print_r($block);
    echo('<hr>');
 }
echo('花费时间(s):'.$spend);

 接下来运行一下,但是很久没响应,然后报这个错 :

PHP从零实现区块链(网页版二)工作量证明,# php从零实现区块链(网页版),php,开发语言

原是程序执行超时了,因为一直在进行哈希运算寻找符合要求的哈希值,然后一直没找到。

这个我们可以去把超时时间设置的大一点即可。

不过我们也可以把难度调小一些, 就是将define('targetBits',24);改为define('targetBits',16);

意思,只是找前4位为0的哈希值就行了,不用前6位为0。

更改后OK,运行如下:

PHP从零实现区块链(网页版二)工作量证明,# php从零实现区块链(网页版),php,开发语言

可以看到哈希值前4位都为0,说明程序运行正常。

接着我们改一下超时时间,将难度重新调为24,找一 下前6位为0的哈希值。 

将php.ini下两句都改成300,最大时间5分钟。

max_execution_time=300

max_input_time=300

改完后重启一下apache。接着再次打开app.php,找到了需要的哈希值:

PHP从零实现区块链(网页版二)工作量证明,# php从零实现区块链(网页版),php,开发语言

总算找到了,花费3分多钟,这个有点看运气,我测试了几次,有时候20秒也找到了。 

PS:再讲一下这个$this->target = gmp_pow('2', (256 - targetBits));难度控制逻辑吧。

这里写的有点乱,凑合看一下吧。

首先这算的是一个求2的平方,我们来看看,2的二进制,是怎么表示的:

0010

好,这样一个二进制数字,它的平方是什么?两个0010相加,就是0100。

然后又是乘2平方,1000。

什么意思呢,就是2的n次方,他的二进制就是正好有一个1,然后其它全是0。

不是1011,也不是0101。每多一次就是把1往前进一位。

那么可以想到,2的256次方肯定是100000000...这样开始的。

那么2的248,肯定也是跟2的256相比,它的前八位肯定是0。

二进制前八位是0,我们知道八位一个字节,一个字节的范围0到256

一个字节的16进制表示,就是“00”到“FF”。

那么二进制前八位是00,那么换成十六进制两位肯定也是00了。

那么难度24,设定的目标值,就是2的232次方,他的二进制前三个字节是全是0,

那么意思就是16进制的前6位都是0。

而哈希值我们知道是16进制64个字符的,那么两个字符一个字节,就是32个字节。

八位一个字节,就是32*8,256位二进制。

而2的256次方,正好也要256位二进制表示。就是10000000000.....开头。

那么得到的哈希值,如果要小于2的256次方,是不是有很多?太容易找到了。

因为2的256次方差不多已经是最大哈希值了,所以我设定减24,那么符合2的232次方的范围变小了。这个值也难找一些。

所以targetBits难度值每加1,那么二进制里的1就会右移一位,变小。

大概就是这样。文章来源地址https://www.toymoban.com/news/detail-777717.html

到了这里,关于PHP从零实现区块链(网页版二)工作量证明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机竞赛python区块链实现 - proof of work工作量证明共识算法

    🔥 优质竞赛项目系列,今天要分享的是 python区块链实现 - proof of work工作量证明共识算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 学长以比特币的结构向大家详解区块链的组成部分 previous hash

    2024年02月05日
    浏览(50)
  • 互联网加竞赛 python区块链实现 - proof of work工作量证明共识算法

    🔥 优质竞赛项目系列,今天要分享的是 python区块链实现 - proof of work工作量证明共识算法 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 学长以比特币的结构向大家详解区块链的组成部分 previous hash

    2024年02月04日
    浏览(41)
  • 区块链项目 - 2 工作量证明

    我们在区块中添加一个属性Nonce来表示区块的生成难度,它是区块生成的一个重要条件,Nonce值越高,代表生成区块的难度越大,通过这种难度从而避免区块随意生成,工作量证明则是要完成这一系列难度区块生产所需要的工作量 /Users/xxx/go/src/publicChain/part5-Basic-Prototype/BLC/Bl

    2024年02月03日
    浏览(47)
  • 简易区块链的搭建(2)——工作量证明

    1. big.Int 的一些常见方法和属性: SetInt64(x int64) :将一个 int64 类型的整数赋值给 big.Int 。 SetString(s string, base int) :将一个字符串表示的整数按照指定的进制转换为 big.Int 。 Add(x, y *big.Int) *big.Int :将两个 big.Int 相加,并返回结果。 Sub(x, y *big.Int) *big.Int :将一个 big.Int 减去另

    2024年04月25日
    浏览(46)
  • 动手学区块链学习笔记(二):区块链以及工作量证明算法

    紧接上文,在介绍完区块链中的加密解密以及公钥私钥等算法后,本篇开始正式进入区块链概念与一个简单区块链系统的实现过程介绍。 什么是区块链? 区块链,就是一个又一个区块组成的链条。每一个区块中保存了一定的信息,它们按照各自产生的时间顺序连接成链条。

    2024年01月17日
    浏览(50)
  • 区块链基础知识7-比特币挖矿原理/工作量证明

    在前面《区块链基础知识6-区块链记账原理》我们了解到记账是把交易记录、交易时间、账本序号、上一个Hash值等信息计算Hash打包的过程。 我们知道所有的计算和存贮是需要消耗计算机资源的,既然要付出成本,那节点为什么还要参与记账呢?在中本聪(比特币之父)的设

    2024年04月28日
    浏览(47)
  • 区块链中怎么惩罚虚假信息的矿工,工作量证明POW,共识算法

    目录 区块链中怎么惩罚虚假信息的矿工 工作量证明POW 什么是工作量证明? 现在出现了另一个问题:如果其他人偷看了小明的答案并且抢答了怎么办?  为什么区块可以安全广播? 共识算法 小结 1. 共识机制惩罚:矿工通过提交多个区块的作弊行为,扣除该矿工的所有抵押币

    2024年02月11日
    浏览(37)
  • java SSM教师工作量管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

    一、源码特点     java SSM 教师工作量管理系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,spring+springMVC+mybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq

    2024年02月04日
    浏览(52)
  • 基于SpringBoot+Vue+uniapp微信小程序的教师工作量管理系统的详细设计和实现

    🌞 博主介绍 :✌全网粉丝15W+,CSDN特邀作者、211毕业、高级全栈开发程序员、大厂多年工作经验、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导✌🌞 👇🏻 精彩专栏

    2024年03月13日
    浏览(52)
  • sass变量+函数,简化代码工作量

    2024年02月08日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包