《以太坊白皮书》原文链接:https://github.com/ethereum/wiki/wiki/White-Paper
Ethereum
Ethereum: a blockchain with a built-in Turing-complete programming language, allowing anyone to write smart contracts and decentralized applications where they can create their own arbitrary rules for ownership, transaction formats and state transition functions.
以太坊: 一个内置了图灵完备的程序语言的区块链。任何人可以编写智能合约;或者 “可以创造任意属于自己的规则” 的去中心化应用;以及交易格式和状态转化函数。
#4 Ethereum State Transition Function
以太坊中的状态转化函数 APPLY(S, TX) -> S'
可以被定义为:
- 检查交易格式是否正确(例如是否有正确的金额),数字签名是否有效,以及随机数是否匹配发送者的账户中的随机数。如果上述的条件不满足,则返回错误。
- 计算交易的费用是否等于
STARTGAS * GASPRICE
,并通过数字签名确认发送者的地址。在发送者的账户余额中减去交易的费用并增加发送者账户的随机数。如果账户余额不足,则返回错误。 - 初始化
GAS = STARTGAS
,然后根据交易中每个字节所需要的 gas 去掉一部分 gas。 - 把交易的数额从发送者账户转移到接受者账户。如果接受者账户不存在,就创建一个新的账户。如果接受者账户是一个合约,那么执行合约中的代码直到完成执行或者消耗完所有的 gas。
- 如果因为发送者的余额不足导致数额转移失败,或者合约代码执行完成前消耗完所有 gas,那么把状态回退到交易之前,但交易的手续费并不会退回,而且会加到矿工的账户中。
- 如果交易成功,退换剩余的 gas 对应的费用给发送者,然后把消耗掉的 gas 对应的费用支付给矿工。
举个例子,假设合约代码为:
if !self.storage[calldataload(0)]:
self.storage[calldataload(0)] = calldataload(32)
Note
通常来说合约代码是低等级的 EVM 代码。上面使用的是一种高等级语言
Serpent
。因为这样更加清晰,而且也可以运行为 EVM 代码。
假设合约在空的存储情况下运行,且发送了一个金额为 10,gas 为 2000,每个以太的 gas 价格为 0.001,以及 64 字节数据(0-31 字节表示数字 2
,32-63 字节表示字符串 CHARLIE
)的交易。在这个情景下状态转化函数的过程为:
- 检查交易是否合法以及交易格式是否正确
- 检查交易的发送至是否有
2000 * 0.001 = 2
的以太余额。如果有,那么从发送者的账户中减去 2 个以太 - 初始化 gas 值为2000;假设交易的长度为 170 字节,且每个字节的手续费为 5。gas 值减去 850 剩下 1150
- 从发送者的账户余额中减去 10 以太,并在接收者账户中增加 10 以太
- 运行这段代码(这个例子中代码的结果很简单:检查存储中索引为
2
的值,如果这个索引下的存储中没有值,那么把它赋值为字符串CHARLIE
)。假如这段代码耗费了 187 gas,那么 gas 值剩余 `1150 - 187 = 963 - 返还
963 * 0.001 = 0.963
以太到发送者的账户中,并返回结果的状态。
如果交易的接收端没有合约,那么整个交易的手续费用会变得很简单:用 GASPRICE
乘上整个交易的字节长度就能获得最后的交易手续费用。而且交易中一并发送的数据会变得无关紧要。
#5 Blockchain & Mining
以太坊中的区块链和比特币的区块链大致相同,但也有不同之处:以太坊的区块链架构和比特币的不同,交易的列表和最近的状态会在以太坊的区块链中保存一份拷贝。除此之外,以太坊中的区块的数量和挖矿难度都会保存在区块链中。
以太坊中基本的区块验证算法如下:
- 检查引用的上一个区块是否存在且有效
- 检查当前区块的时间戳是否大于上一区块且差值小于15分钟
- 检查区块序号、难度、交易根、叔根和 gas 限额 (一些低等级以太坊特有的) 是否有效
- 检查 POW 是否有效
- 令
S[0]
为上一区块的最终状态 - 令
TX
为区块包含的 n 条交易的列表。对于0...n-1
中所有的i
,让S[i+1] = APPLY(S[i], TX[i])
。如果任一应用返回错误,或者 gas 的消耗超出额度,直接返回错误。 - 令
S_FINAL
为S[n]
,然后把奖励给予矿工。 - 检查
S_FINAL
在 Merkle Tree 中的根节点是否和当前区块链中最后一个区块的状态在 Merkle Tree 中的根节点相同。如果相同,那么这个区块有效。
这样的算法似乎看上去效率很低,因为每个区块都需要储存所有状态的信息。但其实在以太坊中,其效率与比特币系统可以相提并论,因为所有状态都是以树结构存储的,每个区块的生成只需要对整个树的某一小部分做修改。通常,对两个相连的区块,其树结构大致相同。因此,数据可以只存储一次,通过指针(子树的哈希值)达到多次引用。另外,由于最新的所有状态信息存储在区块链中最后一个区块中,那么就没有必要再保存整个区块链的历史记录了 —— 这种策略如果应用在比特币系统中,大概可以节省 5 - 20 倍的存储空间。
#6 Applications
通常来讲,以太坊为基础的应用有三种类型:
- 金融应用。提供给用户更为强大的渠道去管理用户的资金,且用户可以通过这些资金进入一些合约。包含子货币,金融衍生品,对冲合约,储蓄钱包,遗嘱,甚至一些种类的全面的雇佣合约。
- 半金融应用。这些应用中,用户的资金需要参与,但资金相关的只是一小部分,更多的是与钱无关的部分。例如一个强制自我奖励机制的解决计算性问题的应用(并不能懂这是什么应用。。)。
- 非金融应用。例如一些去中心自治系统或者线上投票。
白皮书中还列举了几种比较有特点的应用:令牌系统、金融衍生品和稳定价值货币、身份和信誉系统、去中心存储、去中心自治组织等。其中比较有意思的是去中心自治组织,下面会详细阐述。
DAO
去中心化自治组织(DAO, decentralized autonomous organization)的概念,最早在 Oei Brafman 2007年出版的《海星和蜘蛛》一书中提出:
蜘蛛是中心化(细胞)组织的例子,如果把它的头切掉后(整个组织)就无法生存了。海星则是由彼此对等(无中心)的一堆细胞组成,海星撕下的每只触手都可成长为完整的海星。
文中的蜘蛛和海星,分别映射了中心化组织 (现实中的绝大部分组织) 和去中心化组织。基于区块链的技术,这种 “海星“ 得以存在:运行在以太坊系统上的一系列可以实现组织职能的智能合约集合。
对于现在的传统公司或组织来说,通常其等级结构都是自上而下的。例如股份制公司,董事会和 CEO 负责公司整体的的运营和管理。普通员工的决策并不能影响到整家公司。
去中心化自治组织,或者去中心化自治公司 (DAC, decentralized autonomous company) 与传统组织或公司相比,最大的不同是:这种公司或组织由所有成员共同拥有和经营,而不是单一个人拥有并经营。比特币就是一个很好的例子,整个比特币由所有参与的节点共同维护,而没有一个中心化的 “中央管理者”。网络中的任一节点都是对等的,没有权力上的优劣。
在这种 DAO 或者 DACs 中,其 “规则” 通常以代码的形式写在智能合约当中。这些 “规则” 决定了这家公司或组织可以干什么:它是卖东西的,还是提供服务的等等。而且,这个 “规则” 是可以被修改的:只要超过一定数量的人参与投票并同意,那么创始人就可以修改原先写好的智能合约(可以理解成人人都是董事会成员,人人都可以参与决定公司的未来,同时人人都需要承担决策的风险)。
最重要的是,以太坊系统,或者区块链,并不限定这个组织或公司的功能和领域,它只提供给组织或公司一个经济激励平台作为基础。也就是说,就像股份制公司一样,区块链只是像股市一样提供给其一个获得激励、回报的平台,而公司的产业,取决于参与的股东(DAO/DACs 中的每个节点)。
Tom Ding 在《2020: A Call for DApps and DAOs》中解释,这种形式的公司非常适合完成一些小而简单,重复性的工作。
每个工作在网络中能够轻易地被分割,从而工作可被程序或者人为验证,这个过程非常难被操纵。
因为这种形式的公司其职能由其智能合约的内容决定,而智能合约的执行则可以完全自动化,“人” 在其中所扮演的角色只是负责一些机器力所不能及的事:例如修正整个公司的目标或者部分职能。就像一家完全自动化的无人商店,顾客想购买某样产品只需要在以太坊中发起相应的交易,其余的工作都交给了智能合约去执行,“人” 所需要做的只是修改商品的内容等等(其实与一些电商平台如淘宝、京东等很类似)。
阅读 Github 上 《Ethereum - White Paper》 的一些笔记