学习视频源链接:
https://www.bilibili.com/video/BV1Vt411X7JF/
本文是根据肖老师的视频进行的笔记记录
bitcoin 1.0 区块链 以太坊 2.0区块链
以太坊 设置了 memory hard mining puzzle ,这造成了asic resistance,
后续 proof of work (工作证明)将改成 proof of stake (权益证明)
Mining Puzzle (挖矿谜题)
还增加了对智能合约的支持: 智能合约 (Smart Contract)
bitcoin : decentralized currency 去中心化的货币 ------取代了政府的发币权力
ethereum : decentralized contract 去中心化的协议 ------ 取代了合同权力
btc: satoshi
eth: wei
去中心化的货币有什么好处? 跨过转账 快,手续少,交易费少
为什么有去中心化的合同?如果合同的签署方来自世界各地,用司法维护合同可用性比较困难。
1 eth 账户
bitcoin 为了维护隐私,打一枪换一个地方
Eth 使用了 account- based ledger ,对double spending attack 有天然的防范作用,也不用记录币的来源。
有人篡改账户余额怎么办? 发布交易的时候,不需要说明自己的余额,余额是状态树维护的。
但是对应double spending attack (是付款方不诚实 ------ 在bitcoin能出现, eth不能出现)
replay attack (是收款方不诚实,在bitcoin能出现,eth 上需要加一个计数器,交易次数 nonce ,记录这个账户有史以来发布过多少次数)
交易次数 nonce 受到发布者签名保护,
重放攻击 (Replay Attack)
1.1 externally owned account
类似 bitcoin : 用公私钥 控制
组成:
balance 余额
nonce 计数器(应该叫counter)
1.2 smart contract account
合约账户不能主动发起交易
组成:
code
storage
合约: 要求有比较稳定的身份。
- Eth 状态树
以太坊的区块链结构与比特币有一些不同。以太坊不是使用简单的二叉树,而是采用了一种称为"区块头"(block header)的结构来连接区块。
在以太坊中,每个区块头包含以下关键字段:
parentHash: 父区块的哈希,这是区块链的主要连接方式
ommersHash: 叔块(uncle blocks)列表的哈希
stateRoot: 状态树(state trie)的根哈希
transactionsRoot: 交易树(transaction trie)的根哈希
receiptsRoot: 收据树(receipts trie)的根哈希
以太坊的区块头哈希(也就是区块的标识符)是通过对上述区块头字段以及其他字段(如nonce, difficulty, number等)进行Keccak-256(也称为SHA-3)哈希计算得出的。
以太坊不像比特币那样使用简单的链式结构,而是使用了一种称为"Patricia Merkle Trie"的数据结构来管理状态、交易和收据。这些"树"的根哈希被包含在区块头中。
在以太坊的代码实现中,可以查看core/types/block.go文件,其中定义了区块头的结构和哈希计算方法。
addr -> state的 映射
地址是 160 bits 40个 16进制的数
区块链删除东西比较难,不合适。
数据结构: trie(branching factory) Trie 数据结构详解
branching factory 0-f
查找效率取决于key的长度
不会出现碰撞(hash肯定会有冲突,但是这个不会)
在健值稀疏时,如果可以合并key,就可以提高效率,引入了 patricia trie (tree) 路经压缩后的 trie
以太坊中的MPT (Merkle Patricia Trie)
为啥要把账户地址弄这么稀疏? 2的 160次方 。
防止碰撞
每次出现一个区块,都要新建一个mtp,但是很多都是共享的。
智能合约是图灵完备的,
Bitcoin与以太坊区块链回滚机制对比
单笔交易回滚
以太坊状态树与RLP编码详解
- 交易树 & 收据树
交易数和收据树 节点一一对应。 他们都是mpt ,支持查找操作,而且数据结构得到了统一。
mpt 也是一种merkler tree 但是
收据树为了智能合约比较复杂,可以快速查询一些结果
每个交易树和 收据树都是独立的,不会像状态树一样共享节点。
交易树/收据树 可以证明 merkle proof
布隆过滤器在以太坊中的应用
bloom filter 有可能出现 false positive ,可能出现误报,但是不可能出现漏报
bloom filter。不支持删除操作,如果支持删除的话,那个位置不能是0、1 ,需要变成计数器,但是计数器也要防止越界。
先查一下哪个块头在不在bloom filter,如果有的话,再去对交易树,到底有没有。
三棵树的根hash值都在块头里
以太坊运行过程,可以看成是交易驱动的状态机 transaction- driven state machine,这个状态机的状体就是所有账户的状态,就是状态树。交易是什么? 每次发布的区块里包含的交易。
通过执行这些交易,可以通过系统从当前状态驱动到下一个状态。
Btc 也可以认为是transaction- driven state machine ,但是状态是utxo ,发布的区块驱动现在的状态转移到下一个状态。
btc 和以太坊中的状态转移都必须是确定性的,因为所有的矿工都要执行相同的状态转移。
收据就是这个,
区块块头数据结构
这个bloom是由每个收据的bloom 合并得到的
createbllom :合并每个收据的bloom ,生成区块的bloom
logsbloom :生成每个收据的bloom,
bloom9: bloomfilter 中使用的hash 函数,
- GHOST 共识协议
出块速度快的好处是什么? 提高系统的throughput(吞吐) ,降低系统反应时间 。
bitcoin和 以太坊本质上都是应用层的共识协议,底层运行在 overlay network ,底层运行时间比较长,十几秒出一个新块,且底层运行的网络比较慢,所以分支是常态,这对共识协议有什么挑战呢?
会出现以下问题:
挖矿中心化(Mining Centralization)
中心化偏见 (Centralization Bias)
如何解决呢? 采用基于ghost 协议的机制
bitcoin :只有在最长合法链 才有初块奖励,其他的分叉的初块奖励是作废的。
ghost: 挖到矿,这个链条作废了,我们给你一定的补偿(uncle block )
uncle block 得到 7/8 *3 的初块奖励, 一个主链块 最多合并两个uncle block,他能得到2(两个) x 1/32 x 3 + 3 个初块奖励
他合并的是uncle block,挖的时候,已经知道uncle block 的存在, 然后把它们包在 block header 上 。
有没有什么缺陷?
如果矿工处于竞争关系,就不包含
仅能包含叔叔辈的
怎么办呢?
不论资排辈,不管是叔叔辈、爷爷辈、只要能合并就合并,只要给钱就合并。只在当前这个区块在七代内有共同 主线,才能算uncle 为什么这么设计? 如果不限制叔叔的备份,这个实现起来对全节点来说,维护的东西太多了。 而且,设计最多隔着七代,而且奖励对前面的逐步减少,所以鼓励出现分叉之后尽早合并 。不管你包含的是哪一个辈分的叔叔,
以太坊中的区块奖励与燃料费
gas fee (tx fee)------ 比较低 (曾经约为1%)
以太坊中没有规定定期初块奖励 减半。
以太坊中的5个以太币,变成3个亿台币,是为了挖矿难度调整,挖矿炸弹难度大幅下降,然后block 从5->3
以太坊的燃烧机制详解
需要查uncle block是不是符合挖矿难度要求的,符合就认为是合法的叔叔区块。至于这个叔叔区块里面的交易是否合法,我们是不检查的,因为可能和主链交易是冲突的。
以太坊防止分叉攻击的综合机制
只有分叉后的第一个区块才能得到uncle reward,所以降低了分叉攻击的风险。
- 挖矿算法
对于基于工作量证明的区块链系统 来说,挖矿是保证安全的:block chain is secured by mining.
bug bounty。 bitcoin 的 bug bounty 经受了考验,但是bitcoin 有个漏洞是,只有专业设备才能挖到矿,也与最开始bitcoin 论文 one cpu,one vote 背道而驰。
所以bitcoin 出现了很多加密货币,包括以太坊,一个设计原则就是 asic resistance 。
如何实现 这个设计原则呢? 要实现 memory hard mining puzzle
eg. liteCoin , puzzle 基于 scrypt 。开设很大数组,增加对内存读取,特别像普通计算机对内存的需求。
好的:mining 的时候是 memory hard
坏的: 对轻节点 验证时 也是 memory hard。。。。
导致: litecoin真正使用时, 对内存设置不能太大。。。所以实际上litcoin使用时,seed 仅有128k
但是,对冷启动的时候是很有帮助的。早期的设计理念对于聚集人气是很重要的。。。
与bitcoin 的对比:除了出块速度 两分半,是bitcoin 的四倍,
5.2 以太坊怎么设计的?
小的 16 m cache (轻节点用这个就行):从seed 节点运算,把整个数组从前往后填满整个伪随机数。
然后生成一个更大的数组。按照伪随机的原则从小的cache 读取一些元素,
大的 1gb dataset DAG (由小的生成)
以太坊如何生成 Dataset (DAG)
部分伪代码
5.3 转向 pow -> pos
从工作量证明转向权益证明
类似股份制公司。对于asic 的厂商是个严重的威胁。
转入权益证明后就不挖矿了。
以太坊上采用了预挖矿 ------ pre-mining 预留一部分给以太坊的开发者。
pre-sale : 类似风投
工作量证明导致asic 才能挖矿,这样不公平?
但是另一个角度来说,通用计算机挖矿可能导致云厂商被租用,导致大面积攻击,也有可能不公平。
6 难度调整算法。
当难度炸弹开始发挥的时候,正好是工作量证明转向权益证明的时机
权益证明不那么完美,所以工作量证明还是继续挖,(想转没法转)但
北京时间9月15日,OKLink数据显示,世界上最活跃的区块链网络以太坊在区块高度15537393触发合并机制,并产出首个PoS区块(高度为15537394),自此以太坊共识正式从PoW转为PoS机制,完成了此次"The Merge"升级。 最新行情数据显示,以太坊报价来到了1630美元,合并升级对其价格没有立刻产生影响。
比特币改进提案 (BIP: Bitcoin Improvement Proposal)
- 权益证明 proof of stake
矿工为什么要挖矿? 初块奖励,收益
为什么要给他们这些收益: 为了激励矿工,挖矿去维护区块链
采用权益证明的加密货币,会采用virtual mining
虚拟挖矿(Virtual Mining)详解
infanticiside :如果一个加密货币采用工作证明,如果恶意算力攻击,很容易对初创货币造成infanticiside
pos 必须首先搞到足够多的币,才能发动攻击。所以pos是一个闭环。
有的加密货币 pow和 pos 甚至是结合的。
casper the friendly finality gadset (ffg)
Casper FFG (Friendly Finality Gadget): 以太坊最终性机制详解
区块链中的 Epoch(纪元)详解
包含在finality的交易是不会被推翻的吗?
8 智能合约
智能合约是运行在区块链上的一段代码,代码的逻辑定义了合约的内容
智能合约账户保存了合约当前的运行状态
balance:当前余额
nonce:交易次数
code:合约代码
storage:存储,数据结构是一棵mpt
solidity 是智能合约最常用的语言,语法上与javascript很接近
拍卖的时候,也得上交锁定的保证金。
外部账户如何调用智能合约?
创建一个交易,接受地址为要调用的那个智能合约的地址,data域填写要调用的函数及其参数的编码值。
一个合约调用另一个合约
以太坊智能合约中的函数
以太坊智能合约的创建与运行
以太坊Gas费用详解
evm和 jvm类似,也是加一层虚拟机,为智能合约的运行提供一层同一环境。
evm 寻址空间: 256位
汽油费不够的话, 执行的状态会回滚,但是gas fee 是不退的。
因为担心造成 恶意攻击。
公共数据是免费的。
智能合约中的连锁回调问题
bitcoin 的每一个交易最多1m
但是以太坊的很复杂,所以根据操作复杂度
gaslimit :这个区块所有交易能消耗的上限。
每一个矿工可以对gaslimit 进行微调 1/1024
以太坊交易收据(Transaction Receipt)数据结构
所有的全节点都需要在本地执行转账交易。(分布式共识机制)
所以汽油费是怎么扣的?
三棵树在全节点在本地维护的树
状态树:每个账户的状态(包括余额) : 收到
先挖矿还是先执行? 先执行,没有办法先挖矿。
问题:如果执行完了,没挖到矿,有啥补偿?
汽油费是给挖到矿的。 所有的都是免费的,有点像陪太子读书,挖矿慢的就很吃亏。
就不会出现因为没有汽油费,而不验证的情况? ------ 危害区块链安全。(区块链安全------所有全节点独立验证。)
如果他跳过验证步骤,以后就没法挖矿了。因为不验证,本地的三棵树状态就不对了,自己算出来的根hash值别人认为是不对的。
为什么必须执行验证步骤才能更新这三棵树,因为发布出来的东西没有这三棵树的内容,真是块头里面有根hash值,只有通过验证步骤,才能更新三棵树
发布到区块链上的交易是不是全都成功进行的? 如果智能合约执行中出现了错误,要不要也发不到区块链上?
因为要扣掉汽油费,所以需要发布到区块链上,形成共识。
以太坊,就是交易驱动的状态机(共识),因为所有全节点需要到达同一个状态。
所以以太坊不支持多核,除了多线程外,所有可能有不确定性的结果的,都不支持
以太坊的智能合约,不能产生真正意义上的随机数。
多线程的问题:多个核对内存访问顺序不同,执行结果有可能不确定
地址类型:
addr.balance :这个地址的余额
addr.transfer(12345) :当前这个合约,往address上转入的钱
以太坊中的随机性问题
发送eth 的三种方法:
以太坊转账ETH的三种方法及其区别
写完一个智能合约,发布到区块链里,
智能合约的发布与调用流程
写一个solidy 的程序,然后线下宣传,然后
auctionEnd 只有某个人调用,才能执行
没办法设置为拍卖调用结束,自动调用。
但是不存在ended 并发执行,因为没有并发执行
答案:
红框中通过循环退款有问题: 调用时忘记 fullback函数了
code is law : 智能合约的规则是由代码决定的,一旦发布到区块链上就无法修改了------无人能修改规则,但是规则中有漏洞也改不了了。
智能合约如果设计不好,容易拿不出去。
智能合约锁仓是个常用操作。。。
有点类似于不可撤销信托。
需要多次测试,在专门测试网站上测试好了再来。
这个递归重复取钱会持续到什么时候? gas不够、钱包不够、调用栈溢出了。
这个如何修改呢? 先清零,在转账。
重放攻击
decentralized 不等于 distribute
大部分的分布式基本都是为了更快。但是以太坊、比特币要求的是state machine (状态机)
状态机不是为了块,而是为了容错。 最初的状态机应用是 mission critical application
9 . ETH-TheDAO
通用概念:
DAO: decentralized Autonomous Organization
DAC: decentralized Autonomous Corporation .
案例:
The DAO :运行在以太坊上的智能合约
一共存活三个月。
怎么取回收益呢?
splitDAO 拆分完后得到 childDAO,极端的就是一个人的childDAO,然后就是取回
有七天的讨论期
有28天锁定期。
但是问题在哪? splitDAO代码有问题
这个代码先赚钱,然后再把余额减去相应数量,再把调用者账户清零。
应该先把调用者账户清零,再转账
splitDAO代码漏洞分析
10 eth 反思
智能合约其实不智能,就是一个代码合同
智能合约发布后,没办法阻止被调用。
nothing is irrevoable
用脚投票------区块链用挖矿投票
分叉恰恰是去中心化的,存在分叉,恰恰是民主的体现。
decentralized 不等于 distribute
状态机的目的不是比速度快,而是为了容错。
这个不是分布式系统的常态。
不要把智能合约当成是大规模计算/大规模存储的服务,智能合约是用来编写控制逻辑的,只有那些需要在互不信任的实体之间建立信任,才需要智能合约。
- 美链 beauty chain
有可能红框部分会栈溢出,导致扣了很少的货币,但是发了正常数量的代币。
所以代币直接通货膨胀了
预防措施: safemath库
12 总结:
应用:
比特币虽然是非中心化的,但是采用比特币这个非中心化支付模式,不一定只能用在非中心化的领域。比方说亚马逊是中心化的,但是可以采用bitcoin
1 . bitcoin 不应该和已有支付方式竞争。
bitcoin : world wide currency
新的加密货币在支付效率已经大大提高了
bitcoin 1m 字节,10分钟一个块
评价支付方式效率好坏,要放到时代背景下看
物理世界中的智能合约 ATM
不是一种最完美的制度,但是是一种进步。