《以太坊白皮书》解读二:以太坊基本概念
以太坊
以太坊基础层内置图灵完备编程语言的区块链,任何人都可以利用这一点设立自由定义的所有权规则、交易方式和状态转换函数。
以太坊账户
以太坊的账户包含四个部分:
随机数,用于确定每笔交易只能被处理一次的计数器
账户目前的以太币余额
账户的合约代码,如果有的话
账户的存储(默认为空)
以太坊有两种类型的账户:外部所有的账户(由私钥控制的,也就是一般意义的账户)和合约账户(由合约代码控制)。外部账户没有代码,人们可以通过创建和签名一笔交易从一个外部账户发送消息。合约账户有代码,每当合约账户收到一条消息,合约内部的代码就会被激活,允许它对内部存储进行读取和写入,和发送其它消息或者创建合约。
消息和交易
以太坊消息与比特币消息有所不同:前者的消息可以由外部账户或者合约账户创建,后者只能由外部账户创建;还有前者的消息可以包含数据;第三,合约账户是消息接收者,可以选择函数进行回应,这是比特币不能实现的。
以太坊中“交易”是指存储从外部账户发出的消息的签名数据包。交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和两个被称为STARTGAS和GASPRICE的数值。
交易包含消息的接收者、用于确认发送者的签名、以太币账户余额、要发送的数据和STARTGAS和GASPRICE的数值。Every transaction must specify a quantity of "gas" that it is willing to consume (called startgas), and the fee that it is willing to pay per unit gas (gasprice). At the start of execution, startgas * gasprice ether are removed from the transaction sender's account.(参考内容2),STARTGAS是一种限制,主要是为了防止代码的指数型爆炸和无限循环。GASPRICE是每一计算步骤需要支付矿工的费用。
消息中还需要了解合约账户与外部账户具有同样的权利。以太坊平台的强大之处在于去中心化的组织和代理合约不需要关心合约的每一参与方是什么类型的账户。
以太坊状态转换函数
以太坊的状态转换函数:APPLY(S,TX) -> S',交易过程如下:
1、首先检查交易的格式是否正确,签名是否有效,随机数是否与发送者账户的随机数匹配。
2、计算交易费用:费用=STARTGAS * GASPRICE,从签名中确定发送者的地址。从发送者的账户中减去交易费用和增加发送者的随机数。
3、设定初值GAS = STARTGAS,并根据交易中的字节数减去一定量的瓦斯值。
4、从发送者的账户转移价值到接收者账户。如果接收账户还不存在,创建此账户。如果接收账户是一个合约,运行合约的代码,直到代码运行结束或者瓦斯用完。
5、如果因为发送者账户没有足够的钱或者代码执行耗尽瓦斯导致价值转移失败,恢复原来的状态,但是还需要支付交易费用,交易费用加至矿工账户。
6、如果交易终止,将所有剩余的瓦斯归还给发送者,消耗掉的瓦斯作为交易费用发送给矿工。
代码执行
以太坊合约的代码使用低级的基于堆栈的字节码的语言写成的,被称为“以太坊虚拟机代码”或者“EVM代码”。代码由一系列字节构成,每一个字节代表一种操作。一般而言,代码执行是无限循环,程序计数器每增加一(初始值为零)就执行一次操作,直到代码执行完毕或者遇到错误,STOP或者RETURN指令。
操作可以访问三种存储数据的空间:
堆栈,一种后进先出的数据存储,32字节的数值可以入栈,出栈;
内存,可无限扩展的字节队列;
合约的长期存储,一个秘钥/数值的存储,其中秘钥和数值都是32字节大小,与计算结束即重置的堆栈和内存不同,存储内容将长期保持。
当以太坊虚拟机运行时,它的完整的计算状态可以由元组(block_state, transaction, message, code, memory, stack, pc, gas)来定义,这里block_state是包含所有账户余额和存储的全局状态。每轮执行时,通过调出代码的第pc(程序计数器)个字节,当前指令被找到,每个指令都有定义自己如何影响元组。
区块链和挖矿
以太坊区块与比特币区块的区别是前者除了包括交易记录和状态之外,还包括区块序号和难度值。
![](https://img.haomeiwen.com/i1785959/b34b2ec47c2bc47a.png)
区块确认步骤:
1、检查引用的父区块是否有效
2、检查区块的时间戳
3、检查区块序号、难度值、 交易根,叔根和瓦斯限额是否有效
4、检查区块的工作量证明
5、赋值,交易的状态转换
6、检查gas费,发放矿工奖励
对每个区块的状态的存储在树结构中(tree structure,“帕特里夏树”(“Patricia Tree”)),每增加一个区块只需要改变树结构的一小部分。利用相邻区块的树结构大致相同,只存储一次,让指针引用两次。
这种树结构中包括了对默克尔树概念的修改,不仅允许改变节点,而且还可以插入和删除节点。另外,因为所有的状态信息是最后一个区块的一部分,所以没有必要存储全部的区块历史-这一方法如果能够可以应用到比特币系统中,经计算可以对存储空间有10-20倍的节省。
参考内容
1、以太坊白皮书
2、ethereum wiki