PHP也能实现区块链?

2023-10-27

引言

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


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


区块

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


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


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

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

class Block {
    public $prevHash;
    public $hash;
    public $timeStamp;
    public $data;
}
 
  • prevHash:前一个区块的Hash值
  • hash:当前区块的Hash值

  • timeStamp:区块生成的时间戳

  • data:区块保存的数据


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

<php
class Block {
    ...
    public function setBlockHash() {
        $data = serialize($this);
        $this->hash = hash('sha256', $data);
    }
}

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


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

<php
class Block {
    ...
    public function __construct($prevHash, $data) {
        $this->prevHash = $prevHash;
        $this->timeStamp = time();
        $this->data = $data;
        $this->setBlockHash();
    }
}

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

<?php

class Block
{
    ...
    public function getBlockHash()
    {
        return $this->hash;
    }
}

区块链

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

<?php

include('block.php');

class Blockchain
{
    public $blocks = [];
}

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


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

<?php

include('block.php');

class Blockchain
{
    ...
    public function addBlock($data)
    {
        $prevBlock = $this->blocks[count($this->blocks)-1];
        $this->blocks[] = new Block($prevBlock->getBlockHash(), $data);
    }
}

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


可能聪明的读者会发现,在区块链刚创建时并没有任何区块,那么添加新区块时拿哪个区块作为前一个区块呢?答案就是创世区块。创世区块不用包含前一个区块的Hash值,而且随着区块链的创建被创建,代码如下:


<?php

include('block.php');

class Blockchain
{
    ...
    public function __construct()
    {
        $this->blocks[] = new Block('', 'Genesis Block');
    }
}

创世区块并不需要包含前一个区块的Hash值,所以在创建创世区块时把前一个区块的Hash值设置为空。


OK!我们的简易区块链已经完成了,现在来测试一下我们的代码吧:

<?php

include('blockchain.php');

$bc = new Blockchain();

$bc->addBlock('This is block1');
$bc->addBlock('This is block2');

foreach ($bc->blocks as $block) {
    printf("PrevHash: %s\n", $block->prevHash);
    printf("Hash: %s\n", $block->hash);
    printf("Data: %s\n", $block->data);
    printf("\n");
}

我们来运行一下测试代码,运行结果如下:

很好,结果符合我们的预期。


总结

本文只是实现了一个最简易的区块链,离完整的区块链还有非常远的距离。在我们现在的实现中存在很多不足,如:添加一个区块的成本很低,没有实现分布式,不能保存到本地磁盘(重启机器数据就会丢失)。

阅读原文

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP也能实现区块链? 的相关文章

  • https 重定向 laravel .htaccess 之后删除 /public

    我有一个 Laravel 页面部署在共享主机中 当我强制 http 请求重定向到 https 时 url 包含 public 我的根 htaccess 是 RewriteEngine on RewriteCond REQUEST URI p
  • 控制器 HMVC 内的 CodeIgniter 负载控制器

    我在用着http github com philsturgeon codeigniter template http github com philsturgeon codeigniter template 对于模板 我尝试将其他控制器视图
  • 为什么 count 比 $count 差

    我只是在查看不同问题的答案以了解更多信息 我看到一个answer https stackoverflow com a 4891402 429850这表明在 php 中编写这样的做法是不好的做法 for i 0 i
  • PHP 7.2 计数错误

    警告 count 参数必须是数组或对象 实现 Countable in 我在以下行中收到上述错误 if 0 gt count this gt xprop 有人可以帮助我理解这一点吗 我对 PHP 还很陌生 问题显然是 this gt xpr
  • MySQL LAST_INSERT_ID() 和 FOUND_ROWS()

    当 PHP 脚本每秒有数百个查询时会发生什么 它会影响这些函数吗 是否保证它们会返回当前脚本中最后一个插入语句中最后插入的 id 它会返回当前脚本中最后一次选择的行数吗 如果同时从另一个脚本进行新的插入或选择 在 FOUND ROWS 的情
  • 我可以在 php 中的 SESSION 数组上使用 array_push 吗?

    我有一个想要在多个页面上使用的数组 因此我将其设为 SESSION 数组 我想添加一系列名称 然后在另一个页面上 我希望能够使用 foreach 循环来回显该数组中的所有名称 这是会议 SESSION names 我想使用 array pu
  • 在 JAX-WS 中使用安全性的最佳实践是什么

    这是场景 我有一些需要保护的 Web 服务 JAX WS 目前 为了身份验证需求 我提供了额外的 SecurityWService 它为授权用户提供了一些需要在请求其他服务时描述的 userid 和 sessionid 使用一些java安全
  • 使用 .htaccess 进行 PHP 设置时出现 500 内部服务器错误

    当我使用时 htaccess对于以下 PHP 设置 我得到500 Internal Server Error访问网站时 中的代码 htaccess file php flag display errors off php flag log
  • Apache LOG:子进程 pid xxxx 退出信号分段错误 (11)

    Apache PHP Mysql Linux 注意 子进程 pid 23145 退出信号分段错误 11 tmp 中可能存在 coredump 但 tmp下没有找到任何东西 我怎样才能找到错误 PHP 代码中函数的无限循环导致了此错误
  • RuntimeException - 会话存储未根据请求设置 - Laravel Socialite - Facebook

    我在用着Laravel 5 7 and Laravel Socialite 3 1 我想使用登录Facebook我刚刚为此项目配置了应用程序 这些是我为此配置的主要文件 env FACEBOOK CLIENT ID FACEBOOK CLI
  • 如何处理PDO异常[重复]

    这个问题在这里已经有答案了 我正在尝试与PDOphp 上的类 但我在找到处理错误的正确方法时遇到了一些麻烦 我编写了以下代码
  • Symfony/Doctrine 重新排列数据库列

    当我使用doctrine schema update命令行生成表时 Doctrine 或Symfony 似乎想要添加一个命令来重新排列我的列 将键放在它出现的前面 我想知道是否 更希望在哪里 我可以禁用环境的这个 功能 所以当我去生成我的表
  • SQL 查询结果为字符串(或变量)

    是否可以将SQL查询结果输出到一个字符串或变量中 我的php和mysql不好 假设我有数据库 agents 其中包含列 agent id agent fname agent lname agent dept 使用此查询 sql SELECT
  • 重用 PDO 语句 var 会使进程崩溃

    我重用一个变量来存储两个不同的 PDO mysql 语句 stmt dbh gt prepare SELECT stmt gt execute stmt dbh gt prepare UPDATE crash here Error in o
  • POSTed 数组保留其值

    今天 我注意到我的一个 WordPress 安装的行为方式非常奇怪 每当我从仪表板更新帖子时 它的一些额外输入都会保留它们已有的值 所有这些都是多维数组 例如 post php post 123 action 编辑
  • 验证 LDAPS 连接的自签名证书

    我想从 Linux Linux 3 2 0 4 amd64 1 SMP Debian 3 2 51 1 x86 64 GNU Linux 客户端到 Windows 2012 服务器建立安全的 ldap 连接 ldaps 以更改活动中的用户密
  • Laravel 5 命名约定

    我对 Laravel 约定有点困惑 因为我是这个框架的新手 我正在关注 Jeffrey Way 他使用的 Laracasts 视频Plural对于控制器名称 E g 页面控制器 卡片控制器 帖子控制器 但如果我参考官方文档Laravel g
  • 致命错误 - 未找到“Mongo”类

    我正在尝试执行此操作 但我收到以下错误 致命错误 在 C wamp www 中找不到类 Mongo Info PHP 5 38 MongoDB mongodb win32 i386 2 0 2 MongoDB PHP 驱动程序 mongo
  • WordPress 子主题包括包含文件

    我在一家WordPress使用 AMPPS 作为本地主机在我的本地计算机上进行设置 使用 Delta 主题 我创建了一个子主题 delta2 child 初始设置效果很好 但是 我需要更改包含文件夹中名为 home slider php 的
  • 从 $i 获取值,顺序被打乱

    for i 0 i lt count name i some output ommited td td

随机推荐

  • python打开网页被禁止_Python爬虫被禁?看看是不是这几个问题

    Python爬虫在网上完成网站的信息采集时 常常出现无缘无故的ip被禁的情况 正爬取呢就没法继续了 造成日常业务也没办法正常进行了 整个人都不好了呢 一部分人完全不清楚被禁的原因 这么简单的就给禁掉了 究竟是哪个地方不对呢 首先 和大家介绍
  • VS2013 curl源码编译(二)之zlib 1.2.11编译

    已编译好的资源 https download csdn net download key xiaodj 10825531 转载处 https blog csdn net jaggerjack330 article details 82721
  • Python Basics 笔记

    9 14 问题 gt gt gt s Python is Fun gt gt gt s 1 5 从1到第四 ytho gt gt gt s 5 从0到第四 Pytho gt gt gt s 1 从1到最后 ython is Fun gt g
  • 《计算机视觉中的多视图几何》笔记(0)

    为什么要做这个专栏 计算机视觉的一大研究目标是使计算机具有通过2D图像认知3D环境信息的能力 近年来 随着SLAM SfM MVS NeRF等技术的爆火和相关产业的蓬勃发展 越来越多的人加入到三维重建的领域当中 然而 如何入门3D视觉是一件
  • Java中关于char类型的变量为什么可以赋值为整型数字

    文章出处 链接 1 JAVA中 char占2字节 16位 可在存放汉字 2 char赋值 char a a 任意单个字符 加单引号 char a 中 任意单个中文字 加单引号 char a 111 整数 0 65535 十进制 八进制 十六
  • 5. Linux-riscv内存管理21-24问

    文章目录 2 5 在中断上下文中能不能调用包含GFP KERNEL分配掩码的内存分配函数 2 5 1 zone水位 2 5 2 GFP ATOMIC 2 5 3 在使用GPF KERNEL情况下 什么时候才睡眠 2 5 在中断上下文中能不能
  • 教你如何用两个栈实现一个队列

    一 实现思路 1 首先准备两个栈 栈A与栈B 2 栈A专门用来完成入队列操作 栈B专门用来出队列与取队首元素操作 3 每次入队列操作时 首先得判断B栈是否为空 不空则将B栈元素全都依次入A栈 最后继续入新元素 即将要入栈元素添加到栈A 4
  • c语言选择性编译

    在C语言中 可以使用条件编译指令来选择性地编译代码 条件编译是通过预处理器指令来控制代码的编译过程 根据指定的条件来决定是否编译其中的代码 条件编译指令有中预处理器指令 如果某个宏通过 define定义过了 则编译 ifdef内部的代码段
  • Android备忘录模式实现及源代码解析

    Android备忘录模式实现及源代码解析 备忘录模式是一种行为设计模式 它允许在不破坏封装性的前提下捕获对象的内部状态 并在需要时恢复 在Android开发中 备忘录模式可以用于保存和恢复应用程序的状态或数据 本文将介绍如何在Android
  • Docker 中 mysql问题解决

    1 Docker 中mysql问题 1 1 docker 中 安装mysql之后表明大小写不敏感 参考文章 mysql表名大小不敏感 1 1 1 进入mysql docker exec it dokcer中mysql容器名称 bash 下面
  • idea连接mysql设置时区

    当连接mysql时出现以下问题 那么到Advanced中设置时区为 Asia Shanghai 连接成功
  • 图像识别(四)

    大家好啊 我是董董灿 导读 图像识别 一 从像素说起 图像识别 二 图像的色彩空间 图像识别 三 初识卷积 上一篇文章 初识卷积 聊到了卷积这一算法 通俗点讲 卷积就是模仿的人眼识图的过程 以 感受野 的视角去扫描图片 从而获取不同区域的图
  • ThinkCMF后台页面模板demo

    index列表页面模板
  • 高效经验分享:怎么制作企业微信小程序

    随着移动互联网的发展 微信已经成为了人们生活中必不可少的社交媒体平台 同时也逐渐成为了企业推广的重要渠道之一 企业微信小程序是在微信平台上的一种轻量级应用程序 不仅可以方便用户在微信中进行业务操作 还可以提供更加精细化的服务和用户体验 那么
  • 过滤器配置问题(/和/*的区别)

    表单form jsp
  • 语义分割研究现状

    以语义分割热门的数据集Cityscapes的精度作为参考 比较当前语义分割网络效果 可以通过ICNet中的这张图来说明目前大多数方法的精度以及速度 目前MIOU超过80的有PSPNet ResNet38 PSPNet DUC 以及DANet
  • E: Couldn't create temporary file to work with /var/lib/apt/lists/ports.ubuntu.com_ubuntu-ports_dist

    E Couldn t create temporary file to work with var lib apt lists ports ubuntu com ubuntu ports dists trusty Release mkste
  • 解决Echarts与R的可视化中,横坐标显示不全的问题

    解决Echarts与R的可视化中 横坐标显示不全的问题 在做可视化的过程中 最烦的就是图做出来了 坐标显示不全的问题 接下来介绍两个解决问题的方法 在做可视化的过程中 最烦的就是图做出来了 坐标显示不全的问题 接下来介绍两个解决问题的方法
  • 数据可视化清新版【chart.js】学习笔记9.0—气泡图(Bubble Chart)

    Bubble Chart 气泡图 气泡图用于同时显示三维数据 气泡的位置由前两个维度以及相应的水平和垂直轴线确定 第三个维度由单个气泡的大小来表示 官方文档 https www chartjs org docs latest charts
  • PHP也能实现区块链?

    引言 什么是区块链 官方的解释是 区块链是一个分布式记账系统 是藉用密码学串接并保护其内容的串连交易记录 又称区块 每一个区块包含了前一个区块的加密散列 对应的时间戳记以及交易数据 通常用默克尔树算法计算的散列值表示 这样的设计使得区块内容