以太坊白皮书学习记录

以太币白皮书中文文档

比特币的核心概念

作为状态转换系统的比特币

  1. 转换函数

    1
    APPLY(S,TX) ­> S' or ERROR
    • 转换函数解析:
      1. 交易的每个输入:
        • 如果引用的UTXO不存在于现在的状态中(S),返回错误提示
        • 如果签名与UTXO所有者的签名不一致,返回错误提示
      2. 如果所有的UTXO输入面值总额小于所有的UTXO输出面值总额,返回错误提示
      3. 返回新状态S’,新状态S’中移除了所有的输入UTXO,增加了所有的输出UTXO
  2. 状态结构(UTXO:未花费的交易输出,unspent transaction outputs),包含一个面值和所有者(由20个字节的本质上是密码学公钥的地址所定义[1])。一笔交易包括一个或多个输入和一个或多个输出。每个输入包含一个对现有UTXO的引用和由与所有者地址相对应的私钥创建的密码学签名。每个输出包含一个新的加入到状态中的UTXO。

挖矿

  1. 区块
    1. 网络中的节点不断尝试把交易结果打包成“区块”
    2. 区块大约每十分钟产生一块
    3. 每个区块包含:时间戳、随机数、对上一个区块的引用(即hash值)、上一区块生成以来发生的所有交易列表。核对规则如下:
      • 检查区块引用的上一个区块是否存在且有效
      • 检查区块的时间戳是否晚于以前的区块的时间戳,而且早于未来2小时
      • 检查区块的工作量证明是否有效
      • 将上一个区块的最终状态赋于S[0]
      • 假设TX是区块的交易列表,包含n笔交易。对于属于0……n-1的所有i,进行状态转换S[i+1] = APPLY(S[i],TX[i])。如果任何一笔交易i在状态转换中出错,退出程序,返回错误。
      • 返回正确,状态S[n]是这一区块的最终状态
  2. 矿工的作用和奖励
    1. 使用共识算法“工作量证明”,即不停的创建区块,并设置区块的随机值等随机手段,然后hash这个区块,得出hash值是否小于2^190(190是随着比特币的增长,不断变小的值),即为创建区块成功。创建区块者可以得到25BTC的奖励
    2. 矿工将交易打包到区块链。交易中的输入往往大于输出,差额部分就作为“交易费用”付给矿工。

默克尔树

  1. 定义:默克尔树是一种二叉树,由一组叶节点、一组中间节点和一个根节点构成。最下面的大量的叶节点包含基础数据,每个中间节点是它的两个子节点的哈希,根节点也是由它的两个子节点的哈希,代表了默克尔树的顶部。
  2. 特点:允许区块的数据可以零散地传送。节点可以从一个源下载区块头,从另外的源下载与其有关的树的其它部分,而依然能够确认所有的数据都是正确的

比特币智能合约的问题

  1. 缺少图灵完备
  2. 价值盲
  3. 缺少状态
  4. 区块链盲

以太坊的核心概念

以太坊账户

  1. 以太坊状态:是由被称为“账户”的对象和在两个帐号之间转移价值和信息的状态转换构成
  2. 以太坊账户包含四个部分:
    1. 随机数,用于确定每笔交易只能被处理一次的计数器
    2. 账户目前的以太币余额
    3. 账户的合约代码,如果有的话
    4. 账户的存储,默认为空
  3. 分成两类账户:外部所有账户(私钥控制)、合约账户(合约代码控制)

消息和交易

  1. 消息,类似于比特币的交易,但有三点不同
    1. 以太坊的消息可以由外部实体或者合约创建,然而比特币的交易只能从外部创建
    2. 以太坊消息可以选择包含数据
    3. 如果以太坊消息的接受者是合约账户,可以选择进行回应,这意味着以太坊消息也包含函数概念
  2. 交易是指存储的从外部账户发出的消息的签名数据包,包含
    1. to:消息的接收者
    2. v,r,s:用于确认发送者的签名
    3. value:从发送者转移到接收者Wei的数量。在合约创建交易中,value作为新建合约账户的开始余额
    4. data(可选域,只有在消息通信中存在):消息通信中的输入数据(也就是参数)。例如,如果智能合约就是一个域名注册服务,那么调用合约可能就会期待输入参数:域名和IP地址
    5. STARTGAS值:发送者愿意为执行交易支付gas数量的最大值。此值设置之后在任何计算完成之前就会被提前扣掉
    6. GASPRICE值:发送者愿意支付执行交易所需的每个gas的Wei数量
    7. nonce:发送者发送交易数的计数
    8. init(只有在合约创建交易中存在):用来初始化新合约账户的EVM代码片段。init值会执行一次,然后就会被丢弃。当init第一次执行的时候,它返回一个账户代码体,也就是永久与合约账户关联的一段代码。
  3. 创建合约有单独的交易类型和相应的消息类型;合约的地址是基于账号随机数和交易数据的哈希计算出来的

以太坊状态转换函数

  1. 状态转换函数

    1
    APPLY(S,TX) ­> S' or ERROR
    • 转换函数解析:
      1. 检查交易的格式是否正确(即有正确数值)、签名是否有效和随机数是否与发送者账户的随机数匹配。如否,返回错误
      2. 计算交易费用:fee=STARTGAS * GASPRICE,并从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。如果账户余额不足,返回错误
      3. 设定初值GAS = STARTGAS,并根据交易中的字节数减去一定量的瓦斯值
      4. 从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。
      5. 如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。
      6. 否则,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工

代码执行

  1. 以太坊虚拟机:EVM
  2. 可以访问三种数据空间:堆栈、内存、合约的长期存储

区块链和挖矿

  1. 每个区块:不仅包含交易记录和最近的状态,还包含区块序号和难度值。核对规则如下
    1. 检查区块引用的上一个区块是否存在和有效
    2. 检查区块的时间戳是否比引用的上一个区块大,而且小于15分钟
    3. 检查区块序号、难度值、 交易根,叔根和瓦斯限额(许多以太坊特有的底层概念)是否有效
    4. 检查区块的工作量证明是否有效
    5. 将S[0]赋值为上一个区块的STATE_ROOT
    6. 将TX赋值为区块的交易列表,一共有n笔交易。对于属于0……n-1的i,进行状态转换S[i+1] = APPLY(S[i],TX[i])。如果任何一个转换发生错误,或者程序执行到此处所花费的瓦斯(gas)超过了GASLIMIT,返回错误。
    7. 用S[n]给S_FINAL赋值, 向矿工支付区块奖励
    8. 检查S_FINAL是否与STATE_ROOT相同。如果相同,区块是有效的。否则,区块是无效的
  2. 矿工的奖励,同比特币

应用

  1. 代币系统
  2. 金融衍生品和价值稳定的货币
  3. 身份和信誉系统
  4. 去中心化存储
  5. 去中心化资质组织
  6. 其他
    1. 储蓄钱包
    2. 作物保险
    3. 一个去中心化的数据发布器
    4. 云计算
    5. 点对点赌博
    6. 预测市场
    7. 链上去中心化市场