区块链应用
Wei Jieyang Lv4

crypto-currency,加密货币

比特币 BTC

前提:大部分算力掌握在诚实的矿工手里

密码学

1. crypto graphic hash function

特性:

  1. collision resistance:抗碰撞性

  2. hiding:x可以算出H(x),但H(x)不能反推出x,即这个hash函数不会泄露x

    • 需要满足,不然可以通过蛮力求解

      1. 输入空间大

      2. 均匀分布

    • digital commitment / digital equivalent of a sealed envelope:密封预测结果

  3. 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
2
3
4
$ md5 file.txt    # md5校验和
$ shasum -a 1 /tmp/hello.txt # SHA-1校验和
$ shasum -a 256 /tmp/hello.txt # SHA-256校验和
# -a --algorithm
截屏2020-12-27 上午10.44.png

BTC 数据结构

区块链仅仅是一个数据结构,BTC是使用区块链这种数据结构实现的应用

hash point

  • 无环链表都可以用 hash point 代替普通的point
  1. 区块链

IMG_0230

  • 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使用过程中用到的数据结构,在节点验证交易正确性时,使用到的一个结构而已

  1. Merkle tree
    • 与binary tree的区别
      1. 用hash point代替普通的指针
      2. 只要记录root hash,就能检测对整棵树的修改
    • block header:只保存root hash
    • block body:保存所有的交易信息tx
    • 作用:
      • 提供merkle proof

IMG_231E499E57D8-1

  • proof of membership:轻节点想知道黄色交易是否在merkle tree上,只有一个root hash(在block header里面)
  1. 轻节点向某个全节点发出证明请求,请求一个能证明黄色交易包括在merkle tree里面的一个merkle proof
  2. 全节点收到请求,会将图中红色的三个hash值发送给这个轻节点
  3. 从下往上:轻节点会算出黄色交易的hash值绿1,绿1和红1一起算出hash值绿2,绿2和红2算出绿3,绿3和红3一起算出root hash
  4. 轻节点比较这个算出来的root hashblock header的hash值

注意:我们只能验证绿色的部分,不能验证红色部分的hash值

  • 如果考虑通过调整红色的部分,使得被篡改后的绿色的部分算出来hash不变,是不实际的
  • 因为Collision resistance性质,这样的操作相当于人为的制造hash碰撞
  • proof of non-memership:轻节点想证明某个交易不存在

数字货币

  • 使用公私钥,非对成加密算法
    1. Double spending attack,双花攻击 - 花两次攻击:数字货币本质上是一个文件,带签名的数字货币可以复制
  • 每个数字货币上带编号(防范DSA,但是是中心化的)
    • bank维护一个数据库,每个编号的数字货币在谁手里
    • 每次验证数字货币的签名和编号,这个货币有没有发过,被谁花过

BTC安全性

  1. 密码学:别人没有私钥,不能伪造签名
    • 前提:系统中拥有大多数算力的矿工是好的,是遵守协议的,不会接受没有合法签名的交易
  2. 共识机制

BTC解决去中心化的数字货币发行问题

  • IMG_9CCCEC7F3445-1
    • 交易中A的公钥表明是钱是哪儿来的,但是要将A和他的公钥联系在一起,不然E可以用自己的公钥冒充A的,再用自己的私钥签名
      • coinbase tx:需要验证A->B的钱的前一个交易(金币来源)中A的公钥,即金币来源的输出脚本,和交易中提供的A的公钥,即交易的输入脚本拼在一起合成一个程序,看能不能顺利执行

数据结构

区块结构
IMG_9EF94BC347FE-1
  • 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:还没有被花掉的交易的输出集合

    IMG_1019233284AC-1
    • 包括 2个数据就能定位UTXO的输出:
      1. 产生这个输出的交易的hash 值
      2. 这个输出是交易中的第几个输出
    • 作用:检测Double Spending
      • total inputs = total outputs:i可以略大于o,中间的transaction fee可能给了拥有记账权的区块
      • transaction fee:大约只有零点零几个币

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,出块时间:服从指数分布

IMG_9A528FE35443-1
  • 无记忆性:
    • 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字节

挖矿难度

IMG_3A7CCA25FE75-1
  • difficulty_1_target:挖矿难度等于1时的目标域值
  • 1是最低难度
  • 不调整target的话,出块时间会越来越短
    • 分岔,几个用户同时出块
    • 系统不容易统一
    • 51% attack:将大部分算力用来放在攻击的回滚区块的链上

orphan block

uncle reward

难度调整

每2016个区块调整目标域值,大约为2周(2016 * 10 / 60 * 24 = 14)

  • 调整公式:IMG_E4D6502FBD91-1
    • 如果实际时间超过了2周,那么平均出块时间超过了10mins,这个时候出块难度需要调整的低一点(右边分式大于1,target变大)
  • IMG_D3AE8A16D3B4-1

设备

早期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也能参与挖矿

矿池

  • 一个全节点去驱动很多的矿机(一个矿工负责全部的工作比较累)
IMG_FFBC17D6F168-1
  • 矿主:其他全节点的指责

    • 监听网上的交易,将这些交易组织打包成候选区块
    • 同时关注是否有其他节点抢先发布了区块,如果有就需要作出调整等
  • 矿工:只负责计算hash值

  • 好处

    • 减轻了矿工的工作量

    • 解决单个矿工收入不稳定问题,以下两种方式

      1. 像大型数据中心一样,矿池下有成千上万的矿机,属于一个机构,好分配
      2. 分布式,矿机来自不用的厂商,需要通过通讯协议与矿主联系,之后一起分红

      如何解决矿工分红问题 - 工作量证明:

      • 降低挖矿难度,矿工提交 - share,almost valid block - 只能用来证明做了多少工作
  • 大型矿池的弊病:使得51%的攻击更加容易了

    • 分叉攻击:对已经经过6次确认的交易分叉,利用51%算力将交易记录回滚。
      • 矿工只能计算哈希值,并不知道区块包含哪些交易,区块链状况是什么。所以,这些“群众”是无知的,容易被利用(《乌合之众》当中提出的观点,大多数人真的就能掌握真理吗?)。
      • 此外,51%攻击只是一个概率问题,并非达到51%算力就能发动攻击,不能达到就无法发动攻击。此外,矿池本身算力也是在不断变化的。
    • 封锁交易(Boycott)
      • 假如攻击者不喜欢某个账户A,不想让A的交易上区块链,在监听到有其他人将A的交易发布到区块链上时,立刻发动分叉攻击,使A所在链无法成为”最长合法链“。这样,便实现了对A账户的封锁。
      • 像不像即当裁判又当运动员?”堂下何人状告本官“?
    • 盗币(将他人账户BTC转走)
      • 这个是不可能的,因为其并没有他人账户私钥。如果依仗算力强,强行将没有签名的转账发布到区块链,正常节点不会认为其合法,这样,即使这条链再长,其他人也不会认为其是最长合法链。
    • on demand computing -> on demand mining(潜在危害)

BTC 使用的脚本语言

  • 基于栈的编程语言:很简单,只有一个堆栈

交易结构

IMG_0280

交易的输入

IMG_0281

交易的输出

IMG_0282

交易验证

IMG_0262
  • 早期是将输入输出脚本拼接到一起执行
  • 后面处于安全考虑,输入输出两者分别执行,都为非0(True)则成功

脚本形式

注:下面的脚本中,省略了OP_前缀

  • 如CHECKSIG -> OP_CHECKSIG;DUP -> OP_DUP;
  1. P2PK ,Pay to Public Key

    • input script
      1. PUSHDATA(SIG)**:将输入里提供的签名**压入栈
    • output script
      1. PUSHDATA(PubKey)**:将输出里提供的公钥**压入栈
      2. CHECKSIG:将栈顶的两个元素弹出来,用公钥检查签名是否正确
        • 正确则返回True,验证通过,否则执行出错,交易是非法的
  2. P2PKH,Pay to Public Key Hash

    • input script
      1. PUSHDATA(SIG)**:将输入里提供的签名**压入栈
      2. PUSHDATA(PubKey)**:将公钥**压入栈
    • output script
      1. DUP:将栈顶的元素复制一遍
        • 栈顶多了一个**公钥**
      2. HASH160:将栈顶元素弹出,取hash,再将此hash值压入栈
        • 此时栈顶是**公钥的hash-1**
      3. PUSHDATA(PubKeyHash)**:将输出中提供的公钥的hash-2**值压入栈
        • 此时栈顶有两个公钥的hash
      4. EQUALVERIFY:弹出栈顶的两个元素,比较是否相等
        • 防止有人冒名顶替,用自己的公钥冒充收款人的公钥
        • 相等的话栈顶的两个**PubKeyHash**就消失了
      5. CHECKSIG:将栈顶的两个元素弹出来,用公钥检查签名是否正确
        • 正确则返回True,验证通过,否则执行出错,交易是非法的

    区别:第二种没有在输出中直接给出收款人的公钥,而是给出公钥的hash。公钥则是在输入脚本中给出的,其他的操作都是为了验证正确性。

    第二种更常用

  3. P2SH,Pay to Script Hash

    采用BIP16的方案

    输出脚本不提供收款人公钥的hash,而是收款人提供的脚本的hash

    • redeemScript:赎回脚本
    • 常见应用场景:对多重签名的支持-防止私钥的泄露

    验证分两步:

    • input script要给出一些签名(数目不定)及一段序列化的redeemScript
      1. 验证序列化的redeemScript是否与output script中的hash值匹配
      2. 将输入脚本中给出的序列化的redeemScript反序列化并执行redeemScript,验证input script中给出的签名是否正确

    此处脚本中redeemScript内容采用P2PK形式

    • 第一阶段

      • input script

        1. PUSHDATA(Sig)**:将输入的签名**压入栈

        2. PUSHDATA(serialized redeemScript)**:将赎回脚本seriRS**压入栈

      • output script

        1. HASH160:将栈顶元素**seriRS**弹出,取hash,再将此hash值压入栈
          • 此时栈顶为**RSH-1**
        2. PUSHDATA(redeemScriptHash)**:将输出脚本中给出的hash值RSH-2**压入栈
          • 栈顶为两个RSH
        3. EQUAL:比较栈顶的两个RSH是否相等
          • 相等的话栈顶的两个**RSH就消失了,栈中只剩一个Sig**
    • 第二阶段

      • 执行反序列化之后的redeemScript
        1. PUSHDATA(PubKey)**:将公钥**压入栈
        2. CHECKSIG:检查输入给出的**签名**的正确性

redeemScript

  1. P2PK形式

    • PUSHDATA(PubKey):将**公钥**压入栈
    • CHECKSIG:验证栈顶的**公钥签名**是否匹配
  2. P2PKH形式

  3. 多重签名形式 - 下面的P2SH实现多重签名

    IMG_C6B93A3357A1-1 IMG_56F89D5B4A1F-1

    • 输出脚本提供N个公钥和一个域值M,输入脚本只需要提供这N个签名中任意M个合法的签名就能通过验证
      • **CHECKMULTISIG**:验证堆栈中是否有N个签名中的M个

1、P2SH实现多重签名 - 现在普遍采用的形式

  • IMG_0272
  • 本质:将复杂度从输出脚本转移到了输入脚本 -> 赎回脚本里面
  • 赎回脚本在输入里面,由收款人提供,输出脚本只需要提供赎回脚本的hash值即可
    • 实际应用中,收款人不需要公布多重签名的公钥hash值,直接提供赎回脚本的hash值就可以了。则收款人采用什么形式的多重签名就可以隐藏起来

2、Proof of Burn

  • 特殊的输出脚本形式,是销毁比特币的方法
  • output script,被称为provably Unspendable/Prunable Outputs
    • IMG_0279
    • 假如一个交易的input指向这个output,不论这个input里的input script如何设计,执行到RETUEN命令之后会直接返回false,不会执行后面的其他指令,所以这个output无法再被花出去,其对应的UTXO也就可以被剪枝了,无需保存
  • 应用场景
    1. 一些小的币种(AltCoin,Alternative Coin)需要销毁一定数量的比特币来实现
    2. 向其中添加一些无法篡改的内容
      • example - digital commitment,证明在某个时间知道某些事情:如将知识产权取hash之后存在RETUEN之后,之后可以证明你在这个时间知道某些事

fork, 分岔

state fork

forking attack

以太坊 ETC

简介

以太坊 = 区块链技术 + 智能合约

以太坊和区块链技术一样,有Transation,Block,账户与账户之间的关系需要用Transation来执行,任何Transation都需要有通过block来产生。

使用

Metamask插件

我的助记账词:

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.