以太坊并不存在中心服务器,而是基于p2p协议连接起来的平等节点,在众多节点中存储了全部数据。当用户发起一笔交易,会通过广播通知每一个节点,矿工对此进行验证打包并进一步广播,在区块链确认以后,此操作即认为是不可更改的。
在每个节点上,数据是以区块链来存储的。区块链由一个个块串起来而组成。以太坊被描述为一个交易驱动的状态机。它在某个状态下接收一些输入,会确定的转移到另一个状态。
状态机,包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(alphabet)、一个映射输入符号和当前状态到下一状态的转换函数(transition function)的计算模型。
在以太坊的一个状态下,每个账户都有确定的余额和状态信息,当他接收到新的交易以后就会进入一个新的状态,从创世块开始,不断的收到新的交易,由此能进入到一系列新的状态。
以太坊每隔一段时间就会把一批交易信息打包存储到一个块里,这个块中包含的信息有:
- ParentHash:父块的哈希值
- Number:块编号
- Timestamp:块产生的时间戳
- GasUsed:交易消耗的Gas
- GasLimit:Gas限制
- Difficulty:POW的难度值
- Beneficiary:块打包手续费的受益人,也称矿工
- Nonce:一个随机数,使得块头哈希满足POW需求
这些字段我们在上面的web3接口中都可以获取得到。
nonce,整数类型,允许使用相同随机数覆盖自己发送的处于pending状态的交易。
为了防止交易的重播攻击,每笔交易必须有一个nonce随机数,针对每一个账户nonce都是从0开始,当nonce为0的交易处理完之后,才会处理nonce为1的交易,并依次加1的交易才会被处理。以下是nonce使用的几条规则:
- 当nonce太小,交易会被直接拒绝。
- 当nonce太大,交易会一直处于队列之中,这也就是导致我们上面描述的问题的原因;
- 当发送一个比较大的nonce值,然后补齐开始nonce到那个值之间的nonce,那么交易依旧可以被执行。
- 当交易处于queue中时停止geth客户端,那么交易queue中的交易会被清除掉。