• 区块链 2.0


    以太坊概述

    1. 更改出块时间为15s,并使用一套相适应的GHOST协议(该协议非以太坊发明,只是改进)
    2. 更改mining puzzle,变成memory-hard mining puzzle,一定程度上ASIC-resistant
    3. 将来会将工作量证明Proof of Work替换成权益证明Proof of Stake,按照类似股份投票的方法决定下一区块如何产生
    4. 智能合约(Smart Contract):比特币实现货币的去中心化,智能合约实现合同的去中心化,从代码层面保证一开始就不会违约
    5. 以太坊block header中包含三个哈希值,分别对应状态树、交易树、收据树的根哈希
    6. 以太币没有矿工费定期减半的规定

    以太坊账户

    1. 不同于比特币基于交易的账本,以太坊是基于账户的
    2. 分类:
      • 外部账户(Externally Owned Account):包含账户余额(balance)及计数器(nonce)
      • 智能合约账户(Smart Contract Account):包含账户余额(balance)、计数器(nonce)、代码(code,不变)和存储(storage,数据结构为MPT)
    3. 原因:对智能合约的支持要求账户、身份的稳定性
    4. 基于账户的账本天然地对双花攻击有抵抗性,但是却多了replay attack的风险
      • 双花攻击:转账者是恶意节点,将手里的一笔钱花两次
      • 重放攻击:收款人是恶意节点,将转账者的钱转两次到自己账上
      • 重入攻击:利用智能合约中的安全漏洞,将合约中的余额多次转到黑客账户上

    状态树

    1. 目的:实现账户地址到账户状态的映射(addr为160bit,40个16进制数)
    2. 数据结构
      • 如果直接采用哈希表,那么如何签名?将整个哈希表做成merkel tree再取哈希代价太大,也不好修改
      • 如果采用merkel tree,那么叶节点必须有序,否则各个区块链节点产生的根哈希不同。即使采用sorted Merkel Tree,插入新账户时,可能插在中间,那么大半棵树就要重新生成,代价太大。
      • 前缀树(Trie):如字典单词go、god、genesis、generate
      • 压缩前缀树(PT)(键值分布稀疏时,压缩效果较好)
      • 以太坊采用的是(Modified )Merkel Patricia Trie(MPT):增加了Extension Node、Branch Node,用哈希指针代替普通PT中的指针
      • 状态树中MPT是共享的,只有实际发生变更的节点需要新建分支
      • 账户以key-value的形式存储在MPT中,key为账户hash,value以RLP(Recursive Length Prefix,feature:极简) 编码作序列化后存储
    3. 为什么状态树中不能只包含最近发生交易的账户?主要是不方便查询。e.g. A → B(10ETH),需要沿着链查找A、B账户余额。如果B为新账户,就需要一直搜索到创世纪块,效率太低

    交易树&收据树

    1. 交易树包含这段时间内发布的新交易,与比特币的Merkel Tree类似;收据树包含所有交易执行的结果,主要是为了便于查找,特别是对于智能合约。
    2. 对比:状态树包含所有账户,会大量引用之前的MPT;交易树和状态树只包含新产生的交易。
    3. 交易树和收据树都采用MPT,可能只是为了代码的统一。此外,MPT支持自顶向下查找。
    4. bloom filter
      • 支持比较高效地查找某笔交易是否在某个集合里
      • 根据收据树的log生成。通过哈希函数对收据树中每笔交易进行处理,然后将哈希表中相应位置置1(初值0)
      • 可能发生哈希碰撞,出现false positive。查询某笔交易时,hash后查询哈希表,若相应位置为0,说明该笔交易不存在;若为1,则可能存在,也可能不存在(只是跟其他交易发生了哈希碰撞)
      • 由于哈希碰撞的存在,一般不支持删除操作。除非将哈希表元素改为计数器,但这会使数据结构复杂化
      • 查找一段时间内某笔交易是否存在:先根据每个block header里的bloom filter过滤掉一定不存在该交易的区块,在从剩余block里仔细查找交易

    GHOST协议

    1. 以太坊出块时间15s,比较短。容易出现多个分叉。如果继续采用BTC中的方式,对产生分叉区块的节点不公平。
    2. 最初的GHOST协议
      • 每个区块可以包含两个上一代的叔父区块
      • 被包含的uncle block获得7/8的出块奖励(block reward),新区块每包含一个uncle block,获得出块奖励的1/32
      • 未被包含的uncle block没有奖励
      • 叔父区块上的交易作废,无法得到矿工费(gas fee)
      • 缺点:① uncle block个数大于2时,部分未能被包含 ②新节点故意不包含某个叔父区块
    3. 改进后的GHOST协议
      • 新区块可以包含之多7代以内的叔父区块,最多6代叔父。uncle reward随代数递减7/8、6/8……2/8。以此鼓励叔父区块尽早合并
      • 叔父区块分支上只有第一个区块能获得奖励,否则forking attack代价就太小了

    挖矿算法

    1. ASIC resistance —— memory hard mining puzzle

    2. ASIC芯片算力强,但在内存访问速率上和普通芯片差距不大

    3. 莱特币(LiteCoin):追求ASIC/GPU Resistance。mining puzzle采用Scrypt,通过产生一个大的哈希表,同时算法中涉及到伪随机(后一个元素根据前一个元素生成),以此增大对内存的要求。但对轻节点不友好,所以LiteCoin将内存要求设为128k。但128k内存对GPU和ASIC的限制不大,后期GPU和ASIC挖矿均出现了

    4. 以太坊挖矿算法(ethash)用一大一小两个数据集——16M Cache和 1G dataset(DAG)(每3w区块,对seed取hash生成新seed,数据集大小增大初始大小的1/128,即128k和8M,以适应内存发展)

      • cache中第一个元素由seed取hash得到;后一个元素由前一个元素取hash得到

      • dataset中第i个元素从cache中取256次元素计算得到。dataset中的元素彼此独立,可以分别根据序号 i 和 cache 计算得到

      • 对于每个nonce,根据header和nonce取hash,然后以伪随机的方法从dataset中取128个数(64次,每次2个数),最终得到一个hash。如最终的hash<=target,则满足要求

      • 因为矿工需要验证非常多nonce,如果每次都从cache生成,效率太低,所以需要保存到内存。而轻节点只需验证一个nonce,所以只需根据cache计算即可

        eth

    权益证明

    智能合约

    组成

    1. 智能合约是比特币和以太坊的最大区别
    2. 智能合约时运行在区块链上的一段代码,代码的逻辑定义了合约的内容
    3. 智能合约账户保存了智能合约当前的运行状态,包括:balance、nonce、code、storage
    4. 智能合约一般用solidity编写,语法和JavaScript类似
    5. 要运行函数能够接受外部转账,需要写出payable
    6. fallback()函数:
      • function() public [payable] { ... }
      • 匿名函数,没有参数也没有返回值
      • 两种情况会调用:
        • 直接向合约地址转账而data域为空
        • 调用的函数不存在
      • 一般payable是需要的。否则转账金额不为零时抛出异常

    调用流程

    1. 外部账户调用智能合约流程:创建一个交易,接收地址为要调用的智能合约账户地址,data域中填写要调用的函数及其参数的编码值
    2. 内部调用(一个智能合约调用另一个智能合约的函数):
      • 直接调用:直接在合约B中使用另一个合约A的成员函数。但若调用的函数在执行中抛出异常,则B也会抛出异常。可以通过通过.gas()和.value()调整提供的gas或ETH
      • 使用call()调用:在合约B中使用call(要调用的函数签名, 参数)调用函数,若调用的函数抛出异常,则call()返回false,否则为true。合约B不会抛出异常,而会正常执行。可以通过通过.gas()和.value()调整提供的gas或ETH
      • 使用delegatecall():与call()类似,但不会切换上下文(余额、存储等),只会使用到调用的函数代码。不能通过.value()调整提供的gas或ETH

    智能合约创建&运行

    1. 智能合约代码写完后,需要编译成bytecode
    2. 创建合约:外部账户发起一个转账交易到0x0地址
      • 转账金额为0,但需支付汽油费
      • 合约代码写在data域里
    3. 智能合约运行在EVM(Ethereum Virtual Machine),主要是为了增加可移植性
    4. 以太坊是一个交易驱动的状态机
      • 调用智能合约的交易发布到区块链上后,每个矿工都会执行这个交易,从当前状态确定性的转移到下一个状态
    5. 汽油费:
      • 智能合约是一个图灵完备的模型
        • 出现死循环怎么办?
      • 执行合约中的指令需要支付汽油费,汽油费由交易发起者支付。矿工一次性扣除price*gasLimit,再多退少补
      • EVM中不同指令消耗的汽油费是不一样的——简单指令便宜,复杂指令贵

    错误处理

    1. 以太坊中的交易具有原子性

    2. 智能合约中没有try-catch结构,但出现异常时,会发生回滚,恢复到交易前的状态

    3. 可以抛出错误的语句:

      • assert:条件不满足则抛出,一般用于内部错误
      • require:条件不满足则抛出,一般用于外部错误
      • revert:无条件抛出,终止运行并回滚
    4. 嵌套调用(一个合约调用另一个合约中的函数)时,如果是直接调用,则调用者和被调用的函数都会连锁式回滚;如果是间接调用,比如用call(),则只会返回false,调用者不会回滚

    5. 一个合约向另一个合约账户中转账,仍可以发生嵌套调用(fallback函数)

    6. 地址类型
      011

    7. 智能合约可以获得的调用信息02

    8. 以太坊中先运行合约再挖矿,还是先挖矿再计算合约?答案:先运行合约,否则三个根哈希值不确定

    9. 每个节点都需要独立验证合约合法性

    10. 某个节点能否不进行验证,直接接受区块?-- 不行,不独立验证的话,本地的三个根哈希值无法更新

    11. 不支持多线程,因为产生的结果可能具有不确定性,其他节点无法验证。随机数同理,只能支持伪随机数。

    12. 合约代码在发布到区块链之前必须经过仔细的测试,否则一旦上链,即使是bug也无法修改

    DAO

    1. DAO: Decentralized Autonomous Organization
    2. DAC: Decentralized Autonomous Corporation
    3. The DAO: 利于DAO理念的一个投资基金,由于受黑客重入攻击,只存活了3个月

    反思

    1. Smart contract is anything but smart.
    2. Irrevocability is a double-edged sword.
      • 不可篡改性保证了合约的公正性
      • 当区块链中存在问题时,难以修改
    3. Nothing is revocable.
      • 分叉攻击
      • 比如The DAO事件中,以太坊团队通过软件升级回退交易
    4. Is solidity is the right programming language?
    5. What does decentralization mean? 存在分叉恰恰是一种民主的体现
    6. decentralized ≠ distributed
    7. 去中心化不一定是好的。The business model is bad, then it is bad in the internet.
  • 相关阅读:
    搭建nginx反向代理用做内网域名转发
    TOMCAT下面发布项目的4种方式
    centos 安装 rabbitmq
    RabbitMQ在windows下的安装
    mysql物理备份
    Linux(CentOS)下,下载安装Nginx并配置
    whereis 命令
    windows下安装以及配置nginx
    CentOS 7安装配置Redis数据库
    CentOS6.5下安装ActiveMQ
  • 原文地址:https://www.cnblogs.com/DreamEagle/p/15900415.html
Copyright © 2020-2023  润新知