详解以太坊的工作原理(四)

标签:
区块链以太坊 |
分类: IT技术类 |
交易和消息
之前说过以太坊是一个基于交易的状态机。换句话说,在两个不同账户之间发生的交易才让以太坊全球状态从一个状态转换成另一个状态。
最基本的概念,一个交易就是被外部拥有账户生成的加密签名的一段指令,序列化,然后提交给区块链。
有两种类型的交易:消息通信和合约创建(也就是交易产生一个新的以太坊合约)。
不管什么类型的交易,都包含:
- nonce:发送者发送交易数的计数
- gasPrice:发送者愿意支付执行交易所需的每个gas的Wei数量
- gasLimit:发送者愿意为执行交易支付gas数量的最大值。这个数量被设置之后在任何计算完成之前就会被提前扣掉
- to:接收者的地址。在合约创建交易中,合约账户的地址还没有存在,所以值先空着
- value:从发送者转移到接收者的Wei数量。在合约创建交易中,value作为新建合约账户的开始余额
- v,r,s:用于产生标识交易发生着的签名
- init(只有在合约创建交易中存在):用来初始化新合约账户的EVM代码片段。init值会执行一次,然后就会被丢弃。当init第一次执行的时候,它返回一个账户代码体,也就是永久与合约账户关联的一段代码。
- data(可选域,只有在消息通信中存在):消息通话中的输入数据(也就是参数)。例如,如果智能合约就是一个域名注册服务,那么调用合约可能就会期待输入域例如域名和IP地址
http://7fvhfe.com1.z0.glb.clouddn.com/wp-content/uploads/2017/10/201710110607104479.png
在“账户”这个章节中我们学到交易—消息通信和合约创建交易两者都总是被外部拥有账户触发并提交到区块链的。换种思维思考就是,交易是外部世界和以太坊内部状态的桥梁。
http://7fvhfe.com1.z0.glb.clouddn.com/wp-content/uploads/2017/10/201710110607149106.png
但是这也并不代表一个合约与另一个合约无法通信。在以太坊状态全局范围内的合约可以与在相同范围内的合约进行通信。他们是通过“消息”或者“内部交易”进行通信的。我们可以认为消息或内部交易类似于交易,不过与交易有着最大的不同点—它们不是由外部拥有账户产生的。相反,他们是被合约产生的。它们是虚拟对象,与交易不同,没有被序列化而且只存在与以太坊执行环境。
当一个合约发送一个内部交易给另一个合约,存在于接收者合约账户相关联的代码就会被执行。
http://7fvhfe.com1.z0.glb.clouddn.com/wp-content/uploads/2017/10/201710110607179673.png
一个重要需要注意的事情是内部交易或者消息不包含gasLimit。因为gas limit是由原始交易的外部创建者决定的(也就是外部拥有账户)。外部拥有账户设置的gas limit必须要高到足够将交易完成,包括由于此交易而长生的任何”子执行”,例如合约到合约的消息。如果,在一个交易或者信息链中,其中一个消息执行使gas已不足,那么这个消息的执行会被还原,包括任何被此执行触发的子消息。不过,父执行没必要被还原。
区块
所有的交易都被组成一个”块”。一个区块链包含了一系列这样的链在一起区块。
在以太坊中,一个区块包含:
- 区块头
- 关于包含在此区块中交易集的信息
- 与当前块的ommers相关的一系列其他区块头
Ommers解释
“ommer”到底是什么? ommer就是一个区块的父区块与当前区块父区块的父区块是相同的。让我们快速了解一下ommers是用来干嘛的,并且为什么一个区块需要为ommers包含区块头。
由于以太坊的构造,它的区块生产时间(大概15秒左右)比其他的区块链例如Bitcoin(大概10分钟左右)要快很多。这使得交易的处理更快。但是,更短的区块生产时间的一个缺点就是:更多的竞争区块会被矿工发现。这些竞争区块同样也被称为“孤区块”(也就是被挖出来但是不会被添加到主链上的区块)。
Ommers的目的就是为了帮助奖励矿工纳入这些孤区块。矿工包含的ommers必须是有效的,也就是ommers必须在父区块的第6个子区块之内或更小范围内。在第6个子区块之后,陈旧的孤区块将不会再被引用(因为包含老旧的交易会使事情变得复杂一点)。
Ommer区块会收到比全区块少一点的奖励。不管怎样,依然存在激励来让矿工们纳入孤区块并能从中获得一些报酬。
区块头
让我们再回到区块的问题上。我们前面提到每个区块都有一个“区块头”,但这究竟是什么?
区块头是一个区块的一部分,包含了:
- parentHash:父区块头的Hash值(这也是使得区块变成区块链的原因)
- ommerHash:当前区块ommers列表的Hash值
- beneficiary:接收挖此区块费用的账户地址
- stateRoot:状态树根节点的Hash值(回忆一下我们之前所说的保存在头中的状态树以及它使得轻客户端认证任何关于状态的事情都变得非常简单)
- transactionsRoot:包含此区块所列的所有交易的树的根节点Hash值
- receiptsRoot:包含此区块所列的所有交易收据的树的根节点Hash值
- logsBloom:由日志信息组成的一个Bloom过滤器
(数据结构) - difficulty: 此区块的难度级别
- number:当前区块的计数(创世纪块的区块序号为0,对于每个后续区块,区块序号都增加1)
- gasLimit:每个区块的当前gas limit
- gasUsed: 此区块中交易所用的总gas量
- timestamp:此区块成立时的unix的时间戳
- extraData:与此区块相关的附加数据
- mixHash:一个Hash值,当与nonce组合时,证明此区块已经执行了足够的计算
- nonce:一个Hash值,当与mixHash组合时,证明此区块已经执行了足够的计算
http://7fvhfe.com1.z0.glb.clouddn.com/wp-content/uploads/2017/10/201710110607201425.png
注意每个区块是如何包含三个树结构的,三个树结构分别对应:
- 状态(stateRoot)
- 交易(transactionsRoot)
- 收据(receiptsRoot)
这三个树结构就是我们前面讨论的Merkle Patricia树。