以太坊运行原理笔记:
(参考以太坊黄皮书)
那么既然是区块链,必然是从创世区块开始(Genesis),创世区块有一个最初的原始状态,通过交易,状态逐步改变至最终的状态,也就是理解为基于交易的状态机。(黄皮书中定义)。交易是状态改变的桥梁。
挖矿是为争夺记账权,且获得奖励。那么挖矿作为状态转换函数来实现。
以太坊挖矿者在区块链状态中获取随机数据,计算一些从区块链最后的N个区块中随机选择的交易,然后返回结果散列。
先来看看以太坊的挖矿流程:
每一个区块中,通过区块头来生成一个seed,这个seed称为种子,种子只和当前的区块有关。
种子产生一个16MB的伪随机缓存。
基于上述的缓存,那么再生成一个1GB的DAG数据集。缓存和数据集存在依赖关系,一般来说数据集依赖缓存的某些元素,那么简单来说的话,就是只要有缓存,即可计算出数据集DAG中指定位置的元素。
矿工所做的事情,就是在数据集DAG中随机去选择元素,且对其进行散列的一个过程。就个比特币中区寻找nonce一样的模式。
那么对比比特币的挖矿,以太坊目前只需要验证者花费一定数量的缓存即可,验证指定元素的散列是不是小于某个散列值。
缓存和数据集DAG每增加30000个区块更新一次,故矿工的精力应该是在读取数据集上而不是去改变。
这种方式的优点,以太坊中的智能合约会有任何种类的计算,这样ASIC就是一个提供计算的的专门的集成电路。就类似一个全球计算机的CPU。然后挖矿中要求保存全节点完整的区块链。
以太坊在计划过度到POS机制,那么以太坊的POS机制先用V神的一段话来说明:POS协议,每个人都是“矿工”,因此,除非他们选择通过放弃以太币来违反规则,否则每个人都必须承担确认和验证交易的责任,从本质上来说,这才是去中心化的管理模式,能够提高利益相关者在网络中的参与度。
以太币:那么以太币的来源包括以下几部分:
矿前奖励:预付款给与贡献者6000万个以太币
区块的奖励:目前挖出一个区块奖励5个以太币给矿工。
叔块奖励:这个和比特币不同,矿工在挖出一个区块后,但是并不是在主链上,那么这个区块叫做叔区。如果这个叔区块在后续挖矿中作为叔区块被引用了,那么挖出这个区块的矿工获得7/8的区块奖励,也就是4.375个以太币,且另外引用这个区块的矿工获得0.15个以太币,注意,这里的引用最多两个。
比特币的总量是2100万个,每年以太币发行1800万。之前笔者文章中有提到过,这个数字货币因为密钥的丢失,所以每年的发行和意外的丢失会达到一个动态的平衡。并不是你看官方数据有多少就真正有多少在流通,这个应该能理解。
从矿工的角度来看待以太币,那么就分为三块:
挖矿的奖励,这个还是5个以太币。(固定收益)
交易的手续费,之前就有人一直在问万一哪天比特币2100万挖完之后,挖矿如何获得收益,那么交易费就是其中的一项收益,以太坊上交易都会带上交易费用,那么这个也就是矿工的一部分所得。(动态收益)
叔区块收益,上文就提到过的,这个区块如果有叔区块,那么从叔区块中获得1/32个以太币也就是0.15个以太币的收益。且每个区块至多引用两个叔区块,被引用过的区块不能再被引用。(动态收益)
以太币的单位:
基本单位为wei,下表具体是各个比例:
单位维度个数 (wei)
wei1 wei1000
Kwei1e3 wei1000000
Mwei1e6 wei1000000000
Gwei1e9 wei1000000000000
microether1e12 wei10000000000000000
milliether1e15 wei10000000000000000000
ether1e18 wei10000000000000000000000
状态
世界状态:世界状态(state)是在地址(160位的标识符)和账户状态(序列化为RLP的数据结构)的映射。在实施过程中会映射维护在一个修改的Merkle Patricia树上。后端有一个后端数据库去维护映射,称为状态数据库。
这个结构的根节点基于密码学依赖所有内部数据的,它的hash作为整个系统状态的一个安全标识
通过改变根节点的hash来恢复一个先前的状态,因为在区块链中存储了所有这样的根节点hash值。可以恢复到特定的历史状态。
账户状态包括:
nonce:当前账户地址发出的交易数量、或者该账户创建的合约数量。
balance:账户余额。
storageRoot:保存账户存储的Merkle Patricia树的根节点256位hash,256位整数键值的Keccak 256位hash值到256位整数值的RLP编码的映射。
codeHash:该账户的EVM代码hash值,该地址接收一个消息调用时候,代码执行,创建后不可更改。
(来自黄皮书)
交易消息
交易
以太坊的交易最直观解释:从外部账户发送到区块链上的另一个账户的消息和签名的数据包。
包含如下内容:
发送者的签名
接收的地址
转移的数字货币数量等内容
以太坊上的交易都是需要支付费用,和比特币以比特币来支付一定的交易费用不同,以太坊上固定了这个环节,那么这个间接理解是以太坊的一种安全防范错误,防止了大量的无意义的交易,保证一定的安全性,特别是智能合约的创建、执行、调用都需要消耗费用,那么也保证了整个系统的稳定性,防止了一些链上无意义的恶意行为。
交易手续费
以太坊的核心是EVM,以太坊虚拟机,那么在EVM中执行的字节码都是要支付费用。也就是经常看到的Gas、Gas limit、Gas Price这几个概念。
Gas:字面理解就是汽油,以太坊和日常的汽车一样需要Gas才能运行。Gas是一笔交易过程中计算消耗的基本单位。有一个列表可以直观看到在以太坊中操作的Gas消耗量:
操作Gas消耗具体内容
step1执行周期的默认费用。
stop0终止操作是免费的。
suicide0智能合约账户的内部数据存储空间,当合约账户调用suicide()方法时,该值将被置为null。
sha320加解密
sload20在固定的存储器中去获取
sstore100输入到固定的存储器中
balance20账户余额
create100创建合约
call20初始化一个只读调用
memory1扩充内存额外支付的费用
txdata5交易过程中数据或者编码的每一个字节的消耗
transaction500交易费用
contract creation53000homestead中目前从21000调整到53000
所以有些公司或者个人觉得区块链技术去中介化,不需要中心服务器,这种开发模式是比较便宜的,但是事实上区块链的开发不比之前的那些传统软件开发来的便宜。
Gas Price:字面理解汽油价格,这个就像你去加油站,95#汽油今天是什么价格。一个Gas Price就是单价,那么你的交易费用=Gas*Gas Price,然后以以太币来ether来支出。当然你觉得我不想支付费用,你可以设置Gas Price为0,但是选择权在矿工手中,矿工有权选择收纳交易和收取费用,那么最简单的想想很难让一个矿工去接收一个价格很低的交易吧。另外提一句,以太坊默认的Gas Price是1wei。
Gas Limit:字面理解就是Gas的限制,限制是必要的,没有限制就没有约束。这个Gas Limit是有两个意思的。首先针对单个交易,那么这个表示交易的发起者他愿意支付最多是多少Gas,这个交易发起者在发起交易的时候需要设置好。还有一个是针对区块的Gas Limit,一个单独的区块也有Gas的限制。
具体交易
以太坊上交易可以是简单的以太币的转移,同时也可以是智能合约的代码消息。列个表格看下交易的具体内容:
代码内容
from交易发起者的地址、不能为空,源头都没有不合理。
to交易接收者的地址(这个可以为空,空的时候就表示是一个合约的创建)
value转移的以太币数量
data数据字段。这个字段存在的时候表示的是,交易是一个创建或者是一个调用智能合约的交易
Gas Limit字面理解就是Gas的限制,限制是必要的,没有限制就没有约束。这个Gas Limit是有两个意思的。首先针对单个交易,那么这个表示交易的发起者他愿意支付最多是多少Gas,这个交易发起者在发起交易的时候需要设置好。还有一个是针对区块的Gas Limit,一个单独的区块也有Gas的限制。
Gas Price一个Gas Price就是单价,那么你的交易费用=Gas*Gas Price,然后以以太币来ether来支出。以太坊默认的Gas Price是1wei。
nonce用于区别用户发出交易的标识。
hash交易ID,是由上述的信息生成的一个hash值
r、s、v交易签名的三部分,交易发起者的私钥对hash签名生成。
交易分三种类型
转账:简单明了的以太坊上的以太币的转移,就和比特币类似,A向B转移一定数量的以太币。这种交易包含:交易发起者、接收者、value的数量,其余类似Gas Limit、hash、nonce都会默认生成。
智能合约创建:创建智能合约就是把智能合约部署到区块链上,那么这个时候to是一个空的字段。data字段则是初始化合约的代码。
智能合约执行:合约创建部署在区块链上,那么执行就是会加上to字段到要智能合约执行的地址,然后data字段来指定调用的方法和参数的传递。
消息
合约之间可以发生“消息”,消息是虚拟对象,不会序列化,存在于以太坊的执行环境中,消息一般包括如下:
发送者
接收者
以太币数量
可选数据字段
一个startgas
消息类似交易,但是交易是由一个合约产生,在以太坊环境中,但执行某些代码的合约的时候,在call函数时候,会产生并执行一个消息。消息触发接收方账户运行代码,理解为合约之间的互相作用。