区块链导航系列-比特币
磨链(mochain)区块链技术社区整理(投河自尽的鱼、Ashton、CHONG)
区块链导航也是一个入门区块链的入门学习路线。下图是一个区块链相关内容的整理分享,内容还是比较繁琐,当然在学习区块链的过程中并不需要那么复杂。钻研琢磨某些方面可能对这个学习过程更为深刻。
(所有内容不需要科学上网,当然通过科学上网能获取更多信息,这里暂时只收录了不通过科学上网能获取的内容)
磨链社区-区块链导航目录:

比特币内容
这里先从比特币说起。大致做了图示:

比特币起源于中本聪的一篇论文,一般称为创世论文:
创世论文获取
Bitcoin:A Peer-to-Peer Electronic Cash System
bitcoin代码获取
比特币是代码开源在github上,比特币采用C++编写,具体地址如下:
bitcoin社区
bitcoin-wallet
bitcoin交易查询
BIP(比特币改进协议)
比特币中相关学习资料
在学习比特币过程中,《精通比特币》无疑是最好的一本入门书籍。下列了中英文两个版本地址。
《Mastering Bitcoin》
《精通比特币》第二版(中文)
那么网络上一些比特币学习资料和相关网络分享如下:
比特币学习目录
比特币简介
比特币白皮书解读
比特币密钥与地址
比特币钱包
比特币交易
比特币网络
比特币区块链结构
比特币的挖矿与共识
比特币安全
比特币环境部署
比特币应用开发
常见问题内容
什么是比特币?
比特币(英语:Bitcoin,简写:BTC,货币符号:฿),是一种用开源的 P2P 技术的软件而产生的电子货币。虚拟货币“比特币”的概念最初由中本聪(Satoshi Nakamoto,可能化名)在 2009 年提出。现在比特币也指根据中本聪的思路设计发布的开源软件以及建构其上的整个 P2P 网络。
与大多数现行货币不同的是,比特币货币系统是独立存在的,其运行不依赖于中央银行、政府、大型企业的支持或者信用担保。比特币使用遍布整个 P2P 网络节点的分布式数据库来管理货币的发行、交易和账户余额信息。中本聪采用密码学的原理,确保各个比特币节点按照既定的协议达成共识,从而确保货币流通各个环节的安全性。例如,比特币只能被它的真实拥有者使用,而且仅仅能使用一次,支付完成之后原主人即失去对该份额比特币的所有权。比特币货币总量按照设计预定的速率逐步增加,增加速度逐步放缓,并最终在 2140 年达到2100 万个的极限。P2P 的分布式特性与去中心化的设计结构,确保了理论上任何机构都不可能操控比特币的货币总量,或者制造通货膨胀。在全球范围内,比特币可以通过多个线上的交易所和服务商进行兑换交易,也可以在线下找到兑换点,兑换为现钞或金币。
比特币的发行
平均大概每十分钟发行一次。
新比特币在每个网络节点在解决了一定的数学计算(比如,创建新的 block)后生成。这个生成过程被认为是难以重现和 proof of work 的。解决问题后得到的回报是 automatically adjusted,因此在比特币网络的头 4 年,将会产生总额为 10,500,000 BTC 的比特币。这个数量每隔 4 年就自动减半,也就是说在第 4 至第 8 年会产生 5,250,000 BTC,第 8 至 12 年则只有 2,625,000 BTC,如此类推。到最后,总共产生的比特币数量为接近21,000,000 BTC。
另外,伴随着网络一同建立的还有一个系统。平均每隔 10 分钟,该系统就尝试去收集网络上产生的 block 里面的新比特币。创建新比特币的难度系数是随着参与尝试产生新比特币的人数而变化的。整个网络一致认可基于产生最前面的 2016 个 block 所花的时间实现这些行为。因此,难度系数与产生这些最早的 block 所花的时间内投入到产生这些新的比特币的平均计算资源有关。某个人“发现”一个 block 的可能性是他所用的计算资源和所有同时在网络上生成 block 的计算资源的比值。
比特币和之前的网络中虚拟币的区别
两者完全不同,主要区别有以下几点。第一,之前的虚拟币是由发行公司控制,他想发行多少都行,没人能够制约他,而比特币的发行速度是恒定的,任何人无法改变。第二,发行公司的服务器如果被入侵,那么你的虚拟币就会被更改,但比特币网络节点不可能同时被入侵。第三,发行公司可以任意更改虚拟币规则,但比特币的规则无法改变。
BIP是什么?
比特币改进协议(Bitcoin improvement proposals 简称BIP)是为比特币社区提供规范,完善比特币及其运行进程和外部环境特性的设计指导文件。 依据 BIP0001协议即比特币改进协议的目的与指南,比特币改进协议有以下三种类型:
标准协议(Standard BIP)
描述任何影响大多或全部比特币应用的变化,比如网络协议、交易有效性规则的变化,或者任何影响使用比特币交互操作性的变化或补充。
信息补充协议(Informational BIP)
描述比特币的设计事项而不是为其提供新特性,或者为比特币社区提供一般性的指南或信息。信息补充型协议 不一定需要比特币社区达成共识或推荐,因此用户和开发人员可以选择忽略或者接受信息补充型协议的建议。
开发指导协议(Process BIP)
描述比特币进程,或者提议更改进程或事项。Process BIP与Standard BIP 相似,但是也可以应用于除比特币协议以外的领域。在普遍达成共识的情况下,它可以向比特币以外的代码库提出改进建议。与Informational BIP不同,Process BIP 是强制性的,用户必须遵守。例如针对决策进程的过程、指南、改变,在比特币开发过程中使用的工具、环境的改变。任何meta-BIP也应被认为是 Process BIP。 比特币改进协议在 GitHub 中更新版本。
bitcoin交易简介
bitcoin交易是bitcoin系统中最重要的部分,中本聪巧妙的设计了UTXO这种结构,来进行交易和验证。使得系统中bitcoin得以传播和验证,并最终把交易记录到区块链上。
bitcoin交易的本质是一个数据结构,记录并很好的验证了bitcoin中每个节点之间的价值转换关系。且整个bitcoin交易记录在区块链上公开,保证不可篡改。大致介绍下bitcoin的交易过程。参考《精通比特币》第二版
首先说下UTXO:
UTXO:Unspent Transaction Output,未消费的交易输出(一个数据结构,包含了交易数据和执行脚本)。这个理解为现在的银行支票比较合适。但是和现在传统的银行,信用卡,一些第三方支付机构不一样,这些都是通过账户来控制。但是在bitcoin中没有账户的一个概念。传统中心化机构对账户进行验证,通过中心化关系数据库,查询余额,确保账户有足够支出。bitcoin中没有一个中心化的机构来提供验证查询服务。
理解UTXO:在bitcoin中记录的一笔笔的交易记录,那么也就是一个资金的流向,那么记录了一个bitcoin从产生到最新的一个流转状态。
说明其他几个概念:
bitcoin交易中基础构建单元就是交易输出。
UTXO最小单位是“聪”。
钱包中所谓的bitcoin余额是指UTXO可用的总和。这些分散在区块中,钱包知识扫描区块链并汇总该钱包密钥掌握下的UTXO计算余额。
UTXO的集合称为UTXO集,交易代表的是UTXO集的状态变换。
每一笔的交易都会创造输出,并被记录。
交易输出
交易的输出创造一定数量的用于支付的bitcoin,也就是UTXO,这些创建后的UTXO在整个网络中被识别。
交易的输出包括两个部分:
bitcoin数量
确定花费输出所需的条件:加密难题(cryptographic puzzle)= 锁定脚本(locking script)或者脚本公钥(scriptPubKey)
在JSON编码中,输出vout数组,如下:
"vout": [
{
"value": 0.01500000,
"scriptPubKey": "OP_DUP OP_HASH160 ab68025513c3dbd2f7b92a94e0581f5d50f654e7 OP_EQUALVERIFY
OP_CHECKSIG"
},
{
"value": 0.08450000,
"scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG",
}
]
可以发现,交易中两个输出,一笔0.015、一笔0.0845.每一个输出都由一个值和一个加密难度来定义。value和scriptPubKey
交易输入
交易输入将UTXO标记为将被消费,并通过解锁脚本提供所有权的证明。
钱包控制UTXO中需要执行请求的付款,这个时候使用多少UTXO根据需求来确定,那么每一个付款的UTXO,钱包都会创建一个指向UTXO的输入,并使用解锁脚本。
交易输入包含三部分:
指向UTXO的指针。通过指向UTXO被记录在区块链中的交易的hash值和序列号来实现。
解锁脚本,钱包构建用于满足设定在UTXO的支出条件,一般来说解锁脚本就是证明bitcoin所有权的数字签名和公钥。
序列号。
输出vout数组,如下:
"vin": [
{
"txid": "7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18",
"vout": 0,
"scriptSig" : "3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813[ALL] 0484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adf",
"sequence": 4294967295
}
]
可以发现,交易中一个输入,但是包含了4个要素(但是没有交易的金额):
一个交易的ID号,引用了包含正在使用的UTXO交易。
vout,一个输出的索引,用于标识来自该交易是哪一个UTXO被引用。这个第一个是0.
scriptSig,解锁脚本,满足UTXO上的解锁条件。
sequence,序列号。
那么理解到这个交易的ID是:
7957a35fe64f80d234d76d83a2a8f1a0d8149a41d81de548f0a65a8a999f6f18
交易说明
交易说明
首先你看上面交易的输出和输入,你只能在输出看到金额,在输入中没有相关的金额信息和UTXO信息。那么首先检索引用的UTXO,检查锁定脚本,钱包来构建解锁脚本。
检索整个交易,具体就是检索引用的UTXO,同时由于没有金额,那么还需要计算交易支付的费用。
通过检索UTXO信息,那么得到具体UTXO中相关内容:
"vout": [
{
"value": 0.10000000,
"scriptPubKey": "OP_DUP OP_HASH160 7f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8 OP_EQUALVERIFY OP_CHECKSIG"
}
]
那么在这里就可以看到这个UTXO是0.1,然后有一个OP_DUP OP_HASH160...的锁定脚本
交易脚本
上文中一直在说到的锁定脚本和解锁脚本,用于bitcoin交易验证。
锁定脚本
锁定脚本在交易输出中的一个花费条件,作用就是后来需要来使用这笔输出必须满足的条件。在bitcoin中脚本公钥(scriptPubKey)、锁定脚本(locking script)、见证脚本(witness script)这些其实指的都是这个概念。一般锁定脚本含有公钥或者地址。
解锁脚本
解锁脚本满足锁定脚本在交易输出上所设定的条件。一般含有由钱包私钥生成的数字签名。在bitcoin中常见为ScriptSig。
在bitcoin全网中,每一个节点通过同时来执行锁定和解锁脚本来验证一笔交易。交易输入中的解锁脚本,应用之前存在的UTXO,验证将复制解锁脚本和引用的UTXO,并复制引用的这个UTXO的锁定脚本。然后执行解锁和锁定脚本。那么符合要求就验证通过。全部输入都是独立验证。
脚本执行堆栈,堆栈一种数据结构,两个操作push和pop,那么在堆栈顶添加,也在堆栈顶删除,操作就在堆栈的顶端,所以就理解为“后进先出”
bitcoin中解锁和锁定脚本随着堆栈的传递依次分别执行。
首先堆栈执行解锁脚本,解锁脚本执行过程中未报错,那么复制到主堆栈。
执行锁定脚本,和之前复制到主堆栈的解锁脚本结果进行比较。结果为“true”。那么说明解锁脚本满足锁定脚本的条件。获得UTXO的有效授权。
如果上一步中,执行结果不是“true”,那么交易输入无效。
脚本执行过程
bitcoin网络中大多数交易都是P2PKH模式(付款到公钥hash)。交易输出有一个锁定脚本,那么它是将交易输入锁定为一个公钥hash值,理解为是bitcoin中的地址。那么解锁脚本提供一个公钥和对应的私钥创建的数字签名(钱包创建)来解锁。
使用Alice、Bob、Carol、Dave支付的案例,来说明下脚本的执行过程。
一系列交易(如下表):
交易具体内容说明
1.Alice-Bob一个输入交易(a)、一个输出交易(b)a是之前的一个输出对应的输入交易。
2.Bob-Carol一个输入交易(c)、一个输出交易(d)c是对应1交易中的b输出交易
3.Carol-Dave一个输入交易(e)、一个输出交易(f)e是对应2交易中d输出交易
三个交易说明:
三个交易都是单输入单输出。
输出交易和输入交易对应相应的脚本。
每一个输入都对应其前一个输出。
一对输出和输入脚本:(上表交易2为例)
输出(锁定)脚本
OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG
输入(解锁)脚本
脚本组合后
OP_DUP OP_HASH160
OP_EQUALVERIFY OP_CHECKSIG
脚本执行后,显示结果为“true”说明交易通过。
具体执行过程:
bitcoin中的堆栈有一个主堆栈和副堆栈。我们主要看主堆栈的一个执行过程。
一个输入脚本(主要是相关脚本指令和接收方的公钥hash),脚本从左到右执行,那么最先入堆栈的是签名,随即公钥。
一个输出脚本(主要是签名sig和公钥pubkey),从左到右执行。
执行过程(如下表):
步骤具体内容说明
1.1执行输入脚本sig入堆栈
1.2执行输入脚本pubkey入堆栈
2.1执行输出脚本-复制pubkeyOP_DUP,复制堆栈内的pubkey
2.2计算堆栈顶元素hash值执行OP_HASH160,堆栈顶是pubkey,执行后得到pubkeyhash
2.3输出脚本中的sig入堆栈sig入堆栈,区分目前堆栈顶的pubkeyhash,标记为pubkeyhash'
3.1执行检查OP_EQUALVERIFY检查两个pubkeyhash时候相等。相等继续执行,不相等则终止操作,返回结果失败。
3.2签名校验OP_CHECKSIG检查两个签名的校验,相等返回成功,不相等返回失败
比特币的共识机制
POW机制简介
POW(Proof of Work),工作量证明机制。我们最直观的理解就是,一份证明,这个证明确认你做了一定的工作量,类似于现代生活中一些检测考试,通过检测考试你就取得了一份证明,只不过这个证明是一个工作量的证明。
工作量证明一开始是以工作量证明系统提出,这个概念来自Cynthia Dwork 和Moni Naor 1993年在学术论文中,是一种拒绝服务攻击和滥用服务的对策,要求发起者需要消耗一定量的计算机资源来进行计算。那么POW这个词汇在1999年 Markus Jakobsson 和Ari Juels的文章中正式提出。
提到工作量证明,一般都会说到hash现金,亚当·贝克(Adam Back)在1997年发明的,用于抵抗邮件的拒绝服务攻击及垃圾邮件网关滥用。在比特币之前,哈希现金被用于垃圾邮件的过滤。哈希现金也被哈尔·芬尼以可重复使用的工作量证明(RPOW)的形式用于一种比特币之前的加密货币实验中。另外,戴伟的B-money、尼克·萨博的比特金(Bit-Gold)这些比特币的先行者,都是在哈希现金的框架下进行挖矿的。
工作证明原理
首先工作量证明需要客户端做一个有难度的工作且得出一个结果,这个结果公布后,验证的一方需要很快能进行验证。这是不对等的。比如我们在一个字符串后加一个随机数(nonce),对这个字符串进行SHA256计算,然后得到的结果用16进制来表示,我们要求这个计算后的16进制表示的初始几位为:0000,那么才能算通过了验证。这种规则就需要计算机去不断的尝试,当然你可以记得其中一些,但是这个概率毕竟是很小的。正常情况下需要不断的输出计算尝试,直到出现正确的要求结果。
数学期望值,计算过程中会统计实际的计算次数,平均后得到的计算的次数,这个数学期望就是要求的“工作量”,当然这是一个符合数学统计学中的概率事件。
bitcoin中的POW共识机制
bitcoin的出现让人们开始了解到POW共识机制,在bitcoin中,把挖矿生成一个新的区块并把交易数据写入区块看做是一道 工作量证明的数学难题,那么这道题目中有四个重点:
1.工作量证明函数:bitcoin中使用的就是SHA256算法,这个算法是输出256位的hash函数(本文不对hash函数和SHA265函数做具体说明)。目前还未出现针对SHA256算法的有效攻击方法,当然通过算法算法漏洞攻击这里不展开讨论。
2.区块头:bitcoin中的一个区块由区块头和区块中包含的交易列表组成(大小为1M),这里简述下区块头的组成:
区块头大小为80字节。
4字节的版本号。
32字节的上一个区块的散列值。
32字节的Merkle Root Hash,体现区块头和区块中的交易的关系,区块中包含的交易列表,通过Merkle Tree算法生成Merkle Root Hash。
4字节的当前的难度值。
4字节的随机数(nonce)。
3.难度值:difficulty,这是一个指标,不恒定。它最为关键的作用就是决定了bitcoin网络中,矿工需要经过多少次hash运算才能获得记账权生成区块,进而获得区块奖励(12.5bitcoin)。bitcoin中区块产生的平均速率是10分钟一个,每经过2016个区块后,节点按照公式:新难度值 = 旧难度值 * ( 过去2016个区块花费时长 / 20160 分钟 )调整难度值。控制区块的平均产生时间,如果产生区块速率比10分钟快,那么增加难度值,比10分钟慢就降低难度。
4.目标值:target,目标值公式:目标值 = 最大目标值 / 难度值
最大目标值是一个恒定值:
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF。目标值的大小和难度值是一个反比的关系。在bitcoin中矿工计算出来的区块的hash值必须小于这个目标值。换个说法方便理解:工作量证明过程中不断尝试变换nonce进行SHA256的计算,那么尝试的目的是为了找到一个指定前面有一定数量000的值,这个时候前面要求的0越多,那么表示你的难度越大。
(为什么0越多难度越大?你尝试下用不断扔一对骰子以得到小于一个特定点数的游戏。第一局,目标是12。只要你不扔出两个6, 你就会赢。然后下一局目标为11。玩家只能扔10或更小的点数才能赢,假如目标降低为了2,那就难度可想而知。)
工作量证明过程
整个工作量证明过程其实不复杂。
生成币基交易coinbase。
打包交易,组成一个交易列表。
通过Merkle Tree算法生成Merkle Root Hash。
组装区块头。
区块头作为工作量证明的输入,不断变换nonce值,通过公式:SHA256(SHA256(Block_Header))双重SHA256计算。结果不断和当前网络的目标值进行比对,一旦发现小于了目标值(target),那么工作量证明完成。
广播区块到网络中,网络中节点验证。
验证后等待后续区块生成确认(一般6个)。
比特币全球挖矿电力分布图


比特币环境安装
学习区块链的一般都从比特币开始,之前没有搭建过比特币的环境,今天就测试了下。比较简单,有耐心的同学大概1-2小时就能完成(我只测试了linux上,据说windows很坑)
比特币的基本环境安装,笔者使用vmware workstations+ubuntu16.04
首先安装ubuntu16.04操作系统。
安装完成后更新:
Ubuntu更新:(这一步有时候比较慢,耐心)
更新完成后安装bitcoin安装必要的软件包:
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev
sudo apt-get install libboost-all-dev
sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler
sudo apt-get install libqrencode-dev
sudo apt-get install libminiupnpc-dev
Sudo apt-get install libevent-dev (这个有些教程没有写,但是编译时候会报错,建议早点安装上去)
打包完成后,选择一个目录下载源码:git clone https://github.com/bitcoin/bitcoin.git
如果发现命令不可用(apt-get install git 可以提前安装好 git很常用)
下载完成后下载Berkley DB 4.8
wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz'
tar -xzvf db-4.8.30.NC.tar.gz
cd db-4.8.30.NC/build_unix/
../dist/configure --enable-cxx --disable-shared --with-pic --prefix=/bitcoin/db4/
make install
Compile Bitcoin with Berkley DB 4.8
cd ~/bitcoin/
./autogen.sh
./configure LDFLAGS="-L/bitcoin/db4/lib/" CPPFLAGS="-I/bitcoin/db4/include/"
make -s -j5(这一步也很慢、耐心)
完成后:
Run Bitcoin Daemon/QT/Client
./src/bitcoind
./src/qt/bitcoin-qt
./src/bitcoin-cli
之前代码编译完成后,可以选择NetBeansIDE 或者VIM
这里用VIM:
首先下载依赖:
sudo apt-get install python vim exuberant-ctags git
sudo pip install dbgp pep8 flake8 pyflakes isort
下载vimrv:
Wget https://raw.githubusercontent.com/tao12345666333/vim/master/vimrc -O $HOME/.vimrc
打开安装插件:
vim -E -u $HOME/.vimrc +qall
vim编辑参考:https://github.com/tao12345666333/vim/blob/master/README-zh.md
网友评论