北京大学肖臻老师《区块链技术与应用》公开课笔记(十六):ETH数据结构:状态树
在以太坊中,有三棵树的说法,分别是状态树、收据树和交易树。了解了这三棵树,就弄清楚了以太坊的基础数据结构设计。
前一篇文章中有提过,以太坊采用基于账户的模式,系统中显式记录每个账户的余额。而以太坊这样一个大型分布式系统中,是采用的什么样的数据结构来实现对这些数据的管理的。
引入首先账户信息应该是账户地址—-账户信息这样kye—-value键值对的形式存储的。在以太坊中,账户地址为160字节,表示为40个16进制数。状态包含了余额(balance)、交易次数(nonce),合约账户中还包含了code(代码)、存储(stroge)。
使用hash表存储既然是K-V键值对,我们能不能用hash表来实现?
系统中的全节点维护一个hash表,每当系统中有新节点插入或者旧节点状态改变,直接修改hash表的值,如果不考虑hash碰撞,那么查询、插入、修改都是常数级别的时间复杂度。其他节点如果想知道某个账户的账户余额,为了保证全节点发布信息的不可篡改,需要将储存账户信息的hash表组成一个merkle tree,然后把根hash发布到区块中,轻节点要验证某个账户的余额,向全节点要一个Merkle pr ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十五):ETH账户
BTC系统是基于交易的账本,系统中并未显示记录账户有多少钱,只能通过UTXO进行推算,A转给B钱的时候,还需要说明币的来源。这与我们实际情况有很大出入,实际中只需要存钱说明来源,花钱直接从账户里扣即可。此外,账户中的钱在花的时候,必须一次性全部花出去,因为没有输入大于输出的钱全给了矿工当小费。
如图1,B收到A的10个BTC,他想要给C3个BTC,那么他就必须要把多的7个比特币转给自己的另一个账户B‘上
以太坊系统则采用了基于账户的模型(account-based ledger),与现实中银行账户相似。系统中显示记录每个账户以太币的数量,转账是否合法只需要查看转账者账户中以太币是否足够即可,不需要说明币的来源,也不必每次都花完。同时,这也也天然地防范了双花攻击(花两次扣两次即可,你总的货币量是固定的)。
重放攻击这种模式虽然天然防范了双花攻击,但是存在重放攻击的缺陷。A向B转账,过一段时间,B将A的交易重新发布,从而导致A账户被扣钱两次。比特币系统能天然防范重放攻击:大多数节点收到了第一次A->B的订单后,回从UTXO里删除那条转给A的记录,那么B过一段时间重放A->B的 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十四):ETH概述
BTC和ETH为最主要的两种加密货币,BTC称为区块链1.0,以太坊称为区块链2.0。之前文章中提出了比特币设计中存在某些不足,以太坊便对其进行了改进。例如:出块时间(十多秒)、基于GHOST协议的共识机制、mining puzzle(比特币的mining puzzle是计算密集型的,比拼的是计算hash的算力,这导致了挖矿设备的专业化,现在都是ASIC芯片挖,违背了设计初衷,所以ETH才用的是 memory hard mining puzzle,在一定程度上限制了ASIC的使用)、用权益证明(proof of stake)取代工作量证明(proof of work)
此外,以太坊增加了对智能合约(smart contract)的支持。
智能合约BTC本身是一个去中心化的货币,在比特币取得成功之后,很多人就开始思考:除了货币可以去中心化,还有什么可以去中心化?以太坊的一个特性就是增加了对去中心化的合约的支持。
现实生活中,我们的货币是由一个中心化机构发行的,出现了纠纷会有司法机构根据法律(合约)进行仲裁。比特币的出现取代了中心化的机构,而以太坊的出现实际上取代了司法机构。
如果说比特币 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十三):BTC思考
哈希指针BTC系统中很多地方使用到了哈希指针。指针保存的本地内存地址,只有在本地计算机上才具有意义,如果发送给其他计算机就没有意义了。那么在区块发布时候,哈希指针如何通过网络进行传播?
所谓哈希指针,只是系统中一种形象化的方法。实际应用时候,只有哈希而没有指针。回顾之前提过的Block header数据结构:如图该处便为前一个区块的哈希值。
因此可见,在block header中只有hash值,没有指针。那么如何查找到前一个区块的内容?全节点一般将区块存储于一个key-value数据库中,key为哈希,value为区块内容。只要掌握到最后一个区块的哈希值即可依据哈希值一直往前找到区块链所有内容。有些节点只保存区块链部分信息,如果需要用到前面的区块,可以问其他节点要。哈希指针性质保证了整个区块链内容是不可篡改的。
区块恋有情侣一起买BTC,将私钥从中截断,每人保留其中一部分。如果未来两人依旧感情很好,就可以将钱取出;如果分手,这部分钱就会永久锁死,谁也无法取出,通过区块链的不可篡改性作为两人的爱情见证。这样做有什么问题?
如果按照这种方法,将私钥分为N份。但这样会有一系列问题。一. 如 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十二):BTC匿名性
一般来说,匿名性多与隐私保护相关。但实际上,比特币中的匿名并非真正的匿名,而是假的匿名,注册账户可以用一个化名,不要求实名。实际上,比特币与纸币相比,纸币的匿名性更好,因为纸币并没有对个人信息的标记。也正是因为其匿名性,很多非法交易采用现金交易。但现金存在保管、运输等各个方面的不便。
早期银行也不强制要求实名,只要有一个化名即可,早期银行与比特币系统相比,匿名性甚至更好,因为银行的交易数据等并不公开,而比特币系统中的数据是完全公开的。
BTC系统中什么情况会破坏其匿名性?个人的多个账户可能被关联用户可以在每次交易时使用不同的地址账户来避免被查到真实信息,但这些地址账户可以被关联起来
表面上看,每次交易可以更换公私钥对,从而每次都是新的账户,具有很强的匿名性。但实际上,这些账户在一定情况下,是可以被关联起来的。
我们知道一个订单可以有多个输入和多个输出,如下图,那么addr1和addr2很可能是同一个人所持有的账户,因为该人同时拥有这两个私钥的地址。(一个账户中的钱可能不够支付)。同时输出地址也能和输入地址有联系,比如下图的例子,我们不难推断出addr3可能是商家地址,addr4可能是付 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十一):BTC回顾问答
一些问题及其解答转账交易时候,如果接收者不在线(没有连在比特币网络上)怎么办?转账交易只需要在区块链上记录,将某账户比特币转到另一账户,而接收方是否在线并无影响。
假设某全节点收到某个转账交易,会不会有可能转账交易中收款人地址该全节点从未听过。可能,因为比特币账户只需要本地产生即可。只有该账户第一次收到钱时,其他节点在验证订单合法性时才能知道该节点的存在。
如果账户私钥丢失怎么办?没有办法。因为比特币是去中心化货币,没有第三方中心机构可以重置密码,所以账户上的钱也就变成了死钱,转不出去。
通过加密货币交易所(中心化机构),一般是这个机构来集中保存用户私钥,然后给用户类似账号密码的东西,然后交易一般还需要提供身份证明,如果忘记了私钥,可以向交易所询问。但目前这类货币的交易所,尚且处于缺少监管的状态,并不一定具有可信力。而且,其本身仅起到“中介”作用,与该提问的回答“私钥丢失无法追回里面的比特币”并不冲突。
在历史上,有很多次交易所被黑客攻击偷走大量加密货币的事情,其中最著名的为Mt. GOX(中文译为:门头沟)事件。该交易所曾经为全球最大比特币交易所,交易量占到全球比特币交易量的70%左 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(十):BTC分叉
本节介绍比特币系统中的分叉(fork)
分叉指的是,原来的系统中为一条链,但分成了两条链。分叉形成的原因可能有多种,例如:挖矿时两个节点差不多同时挖出矿,都会发布区块(对比特币系统当前状态产生分歧导致的分叉——state fork);分叉攻击,同样也会导致分叉(forking attack,人为故意造成);比特币协议改变,在分布式系统中不能保证所有节点同时升级软件,假设存在少数节点未升级,导致出现分叉(protocal fork);
根据对比特币协议修改的不同,可以将分叉分为硬分叉和软分叉。本篇便专门介绍比特币系统中的分叉。
硬分叉(hard fork)
什么情况会出现硬分叉?对比特币协议增加新协议,扩展新功能,只是拓展,未更新的节点认为更新了之后节点发布的区块为非法区块。未升级软件的旧节点会不认可这些修改,会认为这些特性是非法的。这也就是对比特币协议内容产生分歧,从而导致分叉。硬分叉的一个典型例子,就是对比特币区块大小的修改(之前有提到过,BTC区块大小限制1MB,但是否合适存在争议)。
在BTC系统中,区块大小最大为1MB,可以包含的交易最大数量为4000笔左右(每个交易大概 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(⑨):BTC脚本
之前文中有提及,比特币交易验证其合法性依赖于脚本进行,本篇便专门写比特币系统中的脚本语言。
交易实例我们来看一个交易实例
可以看到收到了23个确认,所以回滚概率很小。
比特币系统中使用的脚本语言非常简单,唯一可以访问的内存空间只有栈,所以也被称为“基于栈的语言”
宏观结构交易结构
vin结构
Vout的内容
验证交易合法性的实际过程
B转给C的交易的比特币来源是A转给B,所以C要拿到B->C的输入脚本(input script)和A->B的输出脚本(output script),来验证交易的合法性,在早期直接将两个脚本按照如图顺序(input script在前,output script在后) 拼接后执行,后来考虑到安全性问题,两个脚本改为分别执行:先执行input script,若无出错,再执行output script。
如果脚本可以顺利执行,最终栈顶结果为true,则验证通过,交易合法;如果执行过程中出现任何错误,则交易非法。
如果一个交易有多个输入脚本,则每个输入脚本都要和对应的输出脚本匹配执行,全部验证通过才能说明该交易合法。
输入输出脚本的几种形式P2P ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(八):BTC挖矿篇
在之前的文章,已经基本上介绍完了比特币系统的原理。本篇,将对之前内容简单总结并说明目前挖矿出现的趋势。
全节点和轻节点之前提到,由于硬件限制,BTC系统中分为轻节点和全节点,下表阐述了全节点和轻节点的区别
全节点
轻节点
一直在线
不是一直在线
在本地硬盘上维护完整区块链信息
不保存整个区块链,只需要保存每隔区块块头
在内存中维护UTXO集合,以便于快速检验交易合法性
不保存全部交易,只保存和自己有关的交易
监听比特币网络中交易内容,验证每个交易合法性
无法验证大多数交易合法性,只能检验和自己相关的交易合法性
决定哪些交易会打包到区块中
无法检测网上发布的区块正确性
监听其他矿工挖出的区块,验证其合法性
可以验证挖矿难度
挖矿: 1. 决定沿着哪条链挖下去。 2. 当出现等长分叉,选择哪一个分叉
只能检测哪个是最长链,不知道哪个是最长合法链
在比特币网络中,大多数节点都是轻节点。如果只是想进行转账操作,不需要挖矿,就无需运行一个全节点。在挖矿过程中,如果监听到别人已经挖出区块延申了最长合法链,此时应该立刻放弃当前区块,在本地重新组装一个指 ...
北京大学肖臻老师《区块链技术与应用》公开课笔记(七):BTC挖矿难度调整
之前有提到过,在比特币系统中,区块链的出块时间保持在平均10min左右。毫无疑问的是,伴随着参与挖矿的人增多,系统总算力不断增强,挖矿的难度绝对不能一成不变。实际上,在比特币系统开发过程中,中本聪便考虑到了这个问题,并设计了一个相应的难度调整算法。这一篇,便了解一下比特币系统中的挖矿难度调整算法。
为什么要调整挖矿难度之前已经提过,挖矿本质上就是不断调整block header中的nonce值,使整个block header的哈希值小于等于给定的目标阈值。即:H(block header)<=target.(target便是目标阈值,target越小,目标难度就越大)对于挖矿难度的调整,可以视为调整目标空间在整个输出空间中所占比例大小。
比特币系统采用的哈希算法为SHA-256,所以整个输出空间大小为2^256,调整目标空间所占比例,简单的说需要目标值前需要多少个0。如下图,挖矿难度和target是成反比的,挖矿难度最小等于1
如果不调整挖矿难度会怎么样?系统总算力越来越强,若挖矿难度保持不变,则出块时间会越来越短。
出块时间越来越短是好事吗?出块时间缩短,那么交易可以很快便被 ...