
crypto-currency,加密货币
比特币 BTC
前提:大部分算力掌握在诚实的矿工手里
密码学
1. crypto graphic hash function
特性:
collision resistance:抗碰撞性
hiding:x可以算出H(x),但H(x)不能反推出x,即这个hash函数不会泄露x
需要满足,不然可以通过蛮力求解
输入空间大
均匀分布
digital commitment / digital equivalent of a sealed envelope:密封预测结果
puzzle friendly:H(x)是事先不可预测的
H(block header) <= target 目标域值(nBits:目标域值编码)
proof of work POW,工作证明
difficult to solve, but easy to verify
2. 签名
账户 - public key, private key
- 来源于非对称加密:asymmetric encryption algorithm
- 最早期是对称加密,symmetric encryption algorithm,但这样密钥分发是一个问题,所以有了公私钥
a good source of randomness:使得生成的公钥相同的几率微乎其微
SHA-256(Secure Hash Algorithm)
- 原理简介
- 和md5加密的效果一样,但是SHA-256更加的安全
- 都只能算是签名,加密算法是既能加密也能解密的算法,而签名就仅仅是起到校验和的作用
Mac, Linux hash命令
1 | md5 file.txt # md5校验和 |

BTC 数据结构
区块链仅仅是一个数据结构,BTC是使用区块链这种数据结构实现的应用
hash point
- 无环链表都可以用 hash point 代替普通的point
- 区块链
block chain is a linked list using hash pointers:用hash point 代替普通的指针
genesis block:创世区块 most recent blcok:最近产生的区块
H( ):hash point
tamper-evident log:最后一个hash值就能检查整个链表是否被修改过
Merkle tree 不是区块链的信息存储结构,而是BTC使用过程中用到的数据结构,在节点验证交易正确性时,使用到的一个结构而已
- Merkle tree
- 与binary tree的区别
- 用hash point代替普通的指针
- 只要记录
root hash
,就能检测对整棵树的修改
- block header:只保存
root hash
, - block body:保存所有的交易信息
tx
等 - 作用:
- 提供
merkle proof
- 提供
- 与binary tree的区别
- proof of membership:轻节点想知道黄色交易是否在
merkle tree
上,只有一个root hash
(在block header
里面)
- 轻节点向某个全节点发出证明请求,请求一个能证明黄色交易包括在
merkle tree
里面的一个merkle proof
- 全节点收到请求,会将图中红色的三个
hash值
发送给这个轻节点- 从下往上:轻节点会算出黄色交易的hash值绿1,绿1和红1一起算出hash值绿2,绿2和红2算出绿3,绿3和红3一起算出
root hash
- 轻节点比较这个算出来的
root hash
和block header
的hash值注意:我们只能验证绿色的部分,不能验证红色部分的hash值
- 如果考虑通过调整红色的部分,使得被篡改后的绿色的部分算出来hash不变,是不实际的
- 因为
Collision resistance
性质,这样的操作相当于人为的制造hash碰撞
- proof of non-memership:轻节点想证明某个交易不存在
数字货币
- 使用公私钥,非对成加密算法
- Double spending attack,双花攻击 - 花两次攻击:数字货币本质上是一个文件,带签名的数字货币可以复制
- 每个数字货币上带编号(防范DSA,但是是中心化的)
- bank维护一个数据库,每个编号的数字货币在谁手里
- 每次验证数字货币的签名和编号,这个货币有没有发过,被谁花过
BTC安全性
- 密码学:别人没有私钥,不能伪造签名
- 前提:系统中拥有大多数算力的矿工是好的,是遵守协议的,不会接受没有合法签名的交易
- 共识机制:
BTC解决去中心化的数字货币发行问题
- 交易中A的公钥表明是钱是哪儿来的,但是要将A和他的公钥联系在一起,不然E可以用自己的公钥冒充A的,再用自己的私钥签名
- coinbase tx:需要验证A->B的钱的前一个交易(金币来源)中A的公钥,即金币来源的输出脚本,和交易中提供的A的公钥,即交易的输入脚本拼在一起合成一个程序,看能不能顺利执行
- 交易中A的公钥表明是钱是哪儿来的,但是要将A和他的公钥联系在一起,不然E可以用自己的公钥冒充A的,再用自己的私钥签名
数据结构
区块结构

- Block Header
- 区块信息:
- version:比特币版本
- 时间戳等
- hash of previous block header:指向前一个区块的指针(只算header的hash)
- 创世区块的
previous hash
为0
- 创世区块的
- merkle root hash:整棵merkle tree的根hash值
- 保证了
transaction list
是无法被篡改的
- 保证了
- nonce:随机数,256bits
- target:挖矿难度目标域值
- 区块信息:
- Block Body
- transaction list
- 只存交易信息
节点
- full node(fully validating node,全节点):
- light node(light weight node,轻节点):
- 一般无法验证交易的合法性,只是利用区块链的信息做一个查询
Consensus in BitCoin,比特币共识
distributed consensus,分布式共识
- impossibility result:
- FLP:在一个异步的系统里(asynchronous),网络时延没有上线,哪怕系统中只要有一个用户是faulty的,都没有办法达成共识
- CAP Theorem:以下三个性质中,最多满足两种
- 一致性Consistency、可用性Availability、分区容错性Partition tolerance
membership
hyperledger
联盟链 - fabric
sybil attacl,女巫攻击:找一个超级计算机,不停的产生用户节点,当总数超过一半时,就得到了这个链的控制权
- coinbase transaction:
- coinbase域:可以在里面写东西,永久保存,但只有获得记账权的节点才能使用
- 通过算例投票 puzzle friendly
- hash rate
- nonce
mining - 挖矿:比特币争夺记账权
- digital gold
- miner
BTC系统实现
transaction-based ledger,基于交易的账本模式
- 每个交易需要说清楚,币是从哪儿来的,它没有账户的概念
全节点维护一个数据结构:
UTXO,unspent Transaction Output:还没有被花掉的交易的输出集合
- 包括 2个数据就能定位UTXO的输出:
- 产生这个输出的交易的hash 值
- 这个输出是交易中的第几个输出
- 作用:检测Double Spending
- total inputs = total outputs:i可以略大于o,中间的
transaction fee
可能给了拥有记账权的区块 - transaction fee:大约只有零点零几个币
- total inputs = total outputs:i可以略大于o,中间的
- 包括 2个数据就能定位UTXO的输出:
account-based ledger,基于账户的模式
- 系统需要显示的记录每个账户有多少个币,如以太坊ß
Bernoulli trial
a random experiment with binary outcome
每次求解nonce可以看作是Bernoulli trial
Bernoulli process:a sequence of independent Bernoulli
- 大量实践的Bernoulli trial就组成了
- 性质:
- memoryless,无记忆的:实验结果和之前的实验结果是没有关系的
Poisson process:
exponential distribution,出块时间:服从指数分布

- 无记忆性:
- memory less:将来挖多少时间与之前已经挖了多少时间没有关系,即使等了10mins,下一挖到矿的时间仍然指数分布,平均是10mins
- process free:过去的process是没用的,对挖矿公平性的保证
出块奖励
geometric series 几何级数
- BTC总数:21万 * 50 + 21万 * 25 + 21万 * 12.5 + ····
- = 21万 * 50 *(1 + 1/2 + 1/4 + ····)[等比求和,逐年减半]
- = 2100万 [过去到未来的BTC总数]
Bitcoin is secured by mining
分岔攻击
回滚交易 - Double Spending Attack
- 多等几个区块/确认 confirmation
irrevocable ledger,不可篡改的账本
- 不可篡改是该旅行的保证
zero confirmation
- 交易刚发出去,没有写进区块
selfish mining
- 我先不发布,等到挖到足够多的区块了,再一起发布,盖过其他的 - 分岔攻击
- 自己挖到两个的时候,不发布,等别人挖到一个,再一起发布,别人的那个就白发了
- 风险:
- 不一定抢的赢别人
BTC网络
BTC所有节点平等,没有super/master node
协议:
- application layer:BitCoin Block chain
- network layer:P2P Overlay Network
设计原则:simple简单,robot鲁棒,but not efficient不是高效
消息节点:flooding方式
邻居节点:选取是随机的,不考虑底层的拓扑结构
- 增强了鲁棒性,但是牺牲了效率
每个节点维护一个等待上链的消息集合
- 冲突交易
best effort,
区块链是一种数据结构,而节点是在基于网络应用时,每一个连入区块的设备,比如手机就是轻节点,而矿池(后面有讲)就是一个全节点,保存所有的信息 - 现在BTC大约有100多G
全节点:保存所有的信息
- 一直在线
- 在本地硬盘上维护完整的区块链信息
- 在内存里维护UTXO集合,以便快速检验交易的正确性
- 监听比特币网络上的交易信息,验证每个交易的合法性
- 决定哪些交易会被打包到区块里
- 监听别的矿工挖出来的区块,验证其合法性
- 挖矿:
- 决定沿着那条链挖下去
- 缺省情况下选择最长的链
- 当出现等长的分岔的时候,选择哪一个分岔
- 缺省情况下选择第一个发现的
- 决定沿着那条链挖下去
轻节点:只保存block header(如手机上)
- 不是一直在线
- 不用保存整个区块链,只要保存每个区块的块头
- 不用保存全部交易,只保存与自己相关的交易
- 无法检测大多数交易的合法性,只能检验与自己相关的那些交易的合法性
- 无法检测网上发布的区块的正确性
- 因为无法知道区块里的交易是不是合法的
- 可以验证挖矿的难度
- 挖矿时计算hash值只需要用到块头的信息
- 只能检测那个是最长的链,不知道哪个是最长的合法链
- 只能知道这个链上的区块挖矿难度时符合要求的,但是无法验证每个区块里交易的合法性
挖矿
H(block header) <= target
- target越小,难度越大
- 需要调整target值,使得出块时间保持稳定(BTC大约为10mins)
hash算法:SHA-256
- 取值空间:2^256
- block header里面存nBits,只有4字节
- target有256位,32字节
挖矿难度

- difficulty_1_target:挖矿难度等于1时的目标域值
- 1是最低难度
- 不调整target的话,出块时间会越来越短
- 分岔,几个用户同时出块
- 系统不容易统一
- 51% attack:将大部分算力用来放在攻击的回滚区块的链上
orphan block
uncle reward
难度调整
每2016个区块调整目标域值,大约为2周(2016 * 10 / 60 * 24 = 14)
- 调整公式:
- 如果实际时间超过了2周,那么平均出块时间超过了10mins,这个时候出块难度需要调整的低一点(右边分式大于1,target变大)
设备
早期1代 - CPU:
- 随着挖矿难度增加,性价比极低
- 计算机中大部分内存都是闲置的,挖矿只用到了其中很少一部分内存
- 大部分不见也是闲置的,挖矿中hash值的计算只用到了通用计算机cpu中很少一部分指令
- 硬盘和其他资源也是闲置的
GPU主要用于大规模的并行计算,如深度学习
2代 - GPU:
- 效率得到了很大的提高
- 但gpu主要是为了并行计算设计的,其中仍然有很多部件是闲置的,所以也不划算
- 如用于浮点数运算的部件
- 对于现在的挖矿的难度,GPU的算力已经不够了
ASIC:Application Specific Integrated Circuit
现在 - ASIC芯片
- 专门为了BTC挖矿计算hash值所设计的,生产周期长(不能做全节点其他工作)
- 为某种加密货币设计的芯片,只能挖着一种货币(除非两种货币用同一个mining puzzle)
- merge mining:一个新的货币发行时,为了解决冷启动问题,吸引更多的用户,故意用一个已有的mining puzzle
- Alternative mining puzzle
- 有的货币会设计这种puzzle,达到下面的效果
- ASIC resistance:抗ASIC芯片化,为了让通用CPU也能参与挖矿
矿池
- 一个全节点去驱动很多的矿机(一个矿工负责全部的工作比较累)

矿主:其他全节点的指责
- 监听网上的交易,将这些交易组织打包成候选区块
- 同时关注是否有其他节点抢先发布了区块,如果有就需要作出调整等
矿工:只负责计算hash值
好处:
减轻了矿工的工作量
解决单个矿工收入不稳定问题,以下两种方式
- 像大型数据中心一样,矿池下有成千上万的矿机,属于一个机构,好分配
- 分布式,矿机来自不用的厂商,需要通过通讯协议与矿主联系,之后一起分红
如何解决矿工分红问题 - 工作量证明:
- 降低挖矿难度,矿工提交 - share,almost valid block - 只能用来证明做了多少工作
大型矿池的弊病:使得51%的攻击更加容易了
- 分叉攻击:对已经经过6次确认的交易分叉,利用51%算力将交易记录回滚。
- 矿工只能计算哈希值,并不知道区块包含哪些交易,区块链状况是什么。所以,这些“群众”是无知的,容易被利用(《乌合之众》当中提出的观点,大多数人真的就能掌握真理吗?)。
- 此外,51%攻击只是一个概率问题,并非达到51%算力就能发动攻击,不能达到就无法发动攻击。此外,矿池本身算力也是在不断变化的。
- 封锁交易(Boycott):
- 假如攻击者不喜欢某个账户A,不想让A的交易上区块链,在监听到有其他人将A的交易发布到区块链上时,立刻发动分叉攻击,使A所在链无法成为”最长合法链“。这样,便实现了对A账户的封锁。
- 像不像即当裁判又当运动员?”堂下何人状告本官“?
- 盗币(将他人账户BTC转走)
- 这个是不可能的,因为其并没有他人账户私钥。如果依仗算力强,强行将没有签名的转账发布到区块链,正常节点不会认为其合法,这样,即使这条链再长,其他人也不会认为其是最长合法链。
- on demand computing -> on demand mining(潜在危害)
- 分叉攻击:对已经经过6次确认的交易分叉,利用51%算力将交易记录回滚。
BTC 使用的脚本语言
- 基于栈的编程语言:很简单,只有一个堆栈
交易结构

交易的输入

交易的输出

交易验证

- 早期是将输入输出脚本拼接到一起执行
- 后面处于安全考虑,输入输出两者分别执行,都为非0(True)则成功
脚本形式
注:下面的脚本中,省略了
OP_
前缀
- 如CHECKSIG -> OP_CHECKSIG;DUP -> OP_DUP;
P2PK ,Pay to Public Key
- input script
- PUSHDATA(SIG)**:将输入里提供的
签名
**压入栈
- PUSHDATA(SIG)**:将输入里提供的
- output script
- PUSHDATA(PubKey)**:将输出里提供的
公钥
**压入栈 - CHECKSIG:将栈顶的两个元素弹出来,用公钥检查签名是否正确
- 正确则返回True,验证通过,否则执行出错,交易是非法的
- PUSHDATA(PubKey)**:将输出里提供的
- input script
P2PKH,Pay to Public Key Hash
- input script
- PUSHDATA(SIG)**:将输入里提供的
签名
**压入栈 - PUSHDATA(PubKey)**:将
公钥
**压入栈
- PUSHDATA(SIG)**:将输入里提供的
- output script
- DUP:将栈顶的元素复制一遍
- 栈顶多了一个**
公钥
**
- 栈顶多了一个**
- HASH160:将栈顶元素弹出,取hash,再将此hash值压入栈
- 此时栈顶是**
公钥的hash-1
**
- 此时栈顶是**
- PUSHDATA(PubKeyHash)**:将输出中提供的
公钥的hash-2
**值压入栈- 此时栈顶有两个公钥的hash
- EQUALVERIFY:弹出栈顶的两个元素,比较是否相等
- 防止有人冒名顶替,用自己的公钥冒充收款人的公钥
- 相等的话栈顶的两个**
PubKeyHash
**就消失了
- CHECKSIG:将栈顶的两个元素弹出来,用公钥检查签名是否正确
- 正确则返回True,验证通过,否则执行出错,交易是非法的
- DUP:将栈顶的元素复制一遍
区别:第二种没有在输出中直接给出收款人的公钥,而是给出公钥的hash。公钥则是在输入脚本中给出的,其他的操作都是为了验证正确性。
第二种更常用
- input script
P2SH,Pay to Script Hash
采用BIP16的方案
输出脚本不提供收款人公钥的hash,而是收款人提供的脚本的hash
- redeemScript:赎回脚本
- 常见应用场景:对多重签名的支持-防止私钥的泄露
验证分两步:
- input script要给出一些签名(数目不定)及一段序列化的redeemScript
- 验证序列化的redeemScript是否与output script中的hash值匹配
- 将输入脚本中给出的序列化的redeemScript反序列化并执行redeemScript,验证input script中给出的签名是否正确
此处脚本中redeemScript内容采用P2PK形式
第一阶段
input script
PUSHDATA(Sig)**:将输入的
签名
**压入栈PUSHDATA(serialized redeemScript)**:将赎回脚本
seriRS
**压入栈
output script
- HASH160:将栈顶元素**
seriRS
**弹出,取hash,再将此hash值压入栈- 此时栈顶为**
RSH-1
**
- 此时栈顶为**
- PUSHDATA(redeemScriptHash)**:将输出脚本中给出的hash值
RSH-2
**压入栈- 栈顶为两个RSH
- EQUAL:比较栈顶的两个RSH是否相等
- 相等的话栈顶的两个**
RSH
就消失了,栈中只剩一个Sig
**
- 相等的话栈顶的两个**
- HASH160:将栈顶元素**
第二阶段
- 执行反序列化之后的redeemScript
- PUSHDATA(PubKey)**:将
公钥
**压入栈 - CHECKSIG:检查输入给出的**
签名
**的正确性
- PUSHDATA(PubKey)**:将
- 执行反序列化之后的redeemScript
redeemScript
P2PK形式
- PUSHDATA(PubKey):将**
公钥
**压入栈 - CHECKSIG:验证栈顶的**
公钥
和签名
**是否匹配
- PUSHDATA(PubKey):将**
P2PKH形式
多重签名形式 - 下面的P2SH实现多重签名
- 输出脚本提供N个公钥和一个域值M,输入脚本只需要提供这N个签名中任意M个合法的签名就能通过验证
- **
CHECKMULTISIG
**:验证堆栈中是否有N个签名中的M个
- **
- 输出脚本提供N个公钥和一个域值M,输入脚本只需要提供这N个签名中任意M个合法的签名就能通过验证
1、P2SH实现多重签名 - 现在普遍采用的形式
- 本质:将复杂度从输出脚本转移到了输入脚本 -> 赎回脚本里面
- 赎回脚本在输入里面,由收款人提供,输出脚本只需要提供赎回脚本的hash值即可
- 实际应用中,收款人不需要公布多重签名的公钥hash值,直接提供赎回脚本的hash值就可以了。则收款人采用什么形式的多重签名就可以隐藏起来
2、Proof of Burn
- 特殊的输出脚本形式,是销毁比特币的方法
- output script,被称为
provably Unspendable/Prunable Outputs
- 假如一个交易的input指向这个output,不论这个input里的input script如何设计,执行到
RETUEN
命令之后会直接返回false,不会执行后面的其他指令,所以这个output无法再被花出去,其对应的UTXO也就可以被剪枝了,无需保存
- 应用场景
- 一些小的币种(AltCoin,Alternative Coin)需要销毁一定数量的比特币来实现
- 向其中添加一些无法篡改的内容
- example - digital commitment,证明在某个时间知道某些事情:如将知识产权取hash之后存在
RETUEN
之后,之后可以证明你在这个时间知道某些事
- example - digital commitment,证明在某个时间知道某些事情:如将知识产权取hash之后存在
fork, 分岔
state fork
forking attack
以太坊 ETC
简介
以太坊 = 区块链技术 + 智能合约
以太坊和区块链技术一样,有Transation,Block,账户与账户之间的关系需要用Transation来执行,任何Transation都需要有通过block来产生。
使用
我的助记账词:
1 | /Users/weijieyang/Documents/Wum00v.txt |
开发Dapp:
web3j - 可以自动生成智能合约包装器代码,以便在不离开JVM的情况下部署智能合约并与之交互。
- java、js环境下,可以用来连接以太坊网络和应用
以太网的代理商,可以不用直接访问以太网,而是通过代理商来访问
infur(推荐):是一个 Web3 供应商,也是MetaMask背后的以太坊供应商。
etherscan :(外网)
Consensus Algorithm
通过挖矿得到区块,算法分为一下两种
1、Ethash:及PoW,找nonce以生成区块
2、Clique:及PoA,投票选出权威节点Authority,由权威节点来验证区块的正确性
Fabric
Conflux
Conflux共识机制是在比特币源代码基础上实现的。
Conflux的框架和比特币的矿机类似
- GossipNetwork:实现P2P网络交互
- 节点:维护TxPool,生成区块(Block Generator),以及维护区块状态
GHost协议
epoch
- Post title:区块链应用
- Post author:Wei Jieyang
- Create time:2021-03-04 14:48:09
- Post link:https://jieyang-wei.github.io/2021/03/04/区块链应用/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.