通过本文,你可以了解到:
- 区块链基础知识
- 动手写一个区块链范例
- 比特币基础知识
- 比特币POW共识算法
前言
自互联网问世以来,以中心化网络作为基石,各种新型的产业层出不穷。站在其对应面,去中心化网络应用,同样蓬勃发展,区块链技术,便是其中最耀眼的明星。
中心化网络

以我们生活中网购付款为例:客户=>支付服务商=>商家,支付服务商单方面掌握货币控制权,显然,客户和商家实际极其被动,整个支付流程也缺乏透明和公开。技术上有什么方式可以改善现状呢?答案:去中心化网络架构!
去中心化网络

还是回到网购支付范例中:交易的数据记录,在多个节点共存,可以理解到客户及商家都是独立节点,这样系统货币控制权(交易记录)就转到系统大多数人手中。
不同于中心化有“独立监管方”,在去中心化网络中,你可能有很多疑问:如何确保交易信息双方真实有效?各节点数据一致性及安全性呢?新增数据如何快速同步到每个节点?为了解决这些问题,区块链应运而生!
区块链
是一种不依赖第三方、通过自身分布式节点进行网络数据的存储、验证、传递和交流的一种技术方案
看完定义,我们先从基础切入,搭建一个小的区块链程式。

交易信息存储在区块内,每个区块包含基本信息:块索引、产生时间、数据块、当前hash,前一区块hash值。
cur_hash = hash (index + time + data + pre_hash)
注:cur_hash由当前区块信息+前一区块hash值组合而成,可以防止篡改。
我们根据上述定义和图解,实现区块链:
<?php
/**
* 区块管理
*/
class block {
public $index;
public $time;
public $data;
public $rand_string;
public $cur_hash;
public $pre_hash;
public function __construct($index, $time, $data, $rand_string, $pre_hash){
$this->index = $index;
$this->time = $time;
$this->data = $data;
$this->rand_string = $rand_string;
$this->pre_hash = $pre_hash;
// echo "索引:". $index ." 时间:". $time ." 块名". $name ." 数据:". $data ." 前一个块hash:". $pre_hash.PHP_EOL;
$hash_str = $time.$name.$data.$rand_string.$pre_hash;
$this->cur_hash = hash('sha256', $hash_str);
// echo "当前模块的hash值:".$this->cur_hash.PHP_EOL;
}
}
/**
* 挖矿
*/
function miningBlock(block $block){
$index = ++ $block->index;
$time = time();
$name = 'new block!';
$data = '奥特曼获得12.5个比特币!';
$rand_string = randomString();
$new_block = new block($index, $time, $data, $rand_string, $block->cur_hash);
return $new_block;
}
/**
* 生成随机hash
*/
function randomString($len = 32){
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$rand_string = '';
for ($i = 0; $i < $len; $i++) {
$rand_string .= $characters[rand(0, strlen($characters))];
}
return $rand_string;
}
/**
* 验证新块
*/
function verifyHash(block $new_block){
return true;
// return is_numeric(substr($new_block->cur_hash, 0, 2)) ? true : false;
}
// 生成创世块
$pre_block = $first_block = new block(0, time(), 'its a secret!', 0, 0);
$block_chain = array();
$block_chain[] = $first_block;
$key = 5;
// 开始挖矿,尝试$key次
for ($i=0; $i < $key; $i++) {
$new_block = miningBlock($pre_block);
// 简化挖矿算法,若hash前两位是数字,则加入区块链
if ($new_block && verifyHash($new_block)) {
$block_chain[] = $new_block;
$pre_block = $new_block;
}
}
// 打印当前区块
echo "挖矿".$key."次,当前区块总数:".count($block_chain).PHP_EOL;
var_dump($block_chain);
?>如果想对区块链有进一步了解,推荐这篇博文:《使用python一步步搭建自己的区块链》
接下来,我们以比特币为例,探讨区块链如何商业化落地,同时重点介绍POW共识算法。
比特币
是一种基于去中心化,采用点对点的网络与共识主动性,开放源代码,以区块链作为底层技术的加密货币目标比特币已经稳定生成62万多个区块,我们先看一下比特币长什么样:传送门

接下来,我们采用快问快答的方式,让大家对比特币有个大概认知:
问:比特币获取方式?
答:1.矿工成功挖得新区块,奖励12.5个比特币;2.矿工将区块交易信息写入新区块,收取一定交易费;3.用现实货币,按一定比例兑换比特币
问:比特币和区块链关系?
答:区块链是一种链式技术方案,比特币是使用了区块链技术方案实现的一种加密货币
问:比特币如何产生?
答:按比特币创始人中本聪设定,通过既定算法,当矿工成功挖取到符合要求的新区块,则会被赠予12.5个比特币,同样,此信息存储在新区块内,标识着此矿工新拥有12.5个比特币
比特币POW共识算法
关于新区块的生成算法,是比特币核心,我们来看下如何实现。
新区块生成规则:
首先,得到目标值 target = targetmax / difficulty
targetmax:固定值
difficulty:浮动值,新区块生产难度值,两周会变动一次
其次,加入条件:新区块hash < target
随着难度值增高,target目标值越小,那么生成新区块的条件越苛刻,获取到满足要求的Nonce越难
最后,猜数字Nonce值,以满足hash(pre_hash + 1MB交易稽核 + Nonce) < target
好了,今天的分享就到这里,下一篇,会为大家介绍如何进行区块链应用开发。
参考资料:
《区块链入门教程》阮一峰