Ether(以太币)记载在 世界状态(world state) 里
世界状态 = 每个人账户的状态的总集合
Ether(以太币)余额因交易而变化
以太坊既可以看作静态的区块的串联, 也可以看作一个状态机, 随着用户不断地发起交易,促成这个状态机进行状态转移
该值会随着用户不断发送交易而递增,保障用户发出的交易是按照顺序被收纳入最终的区块链。 因为在同一个账户中,已执行交易总数不可以在区块链中再次出现。 当用户创建智能合约时,要指定合约地址,该地址是由用户账户的已执行交易总数和用户账户地址联合计算而得出的。
该值为 智能合约独有,外部账户不包含该值。 代码区即为智能合约代码本身。 在合约的生命周期中,该区域的内容是不可更改的 只读状态。 代码区存放于以太坊网络节点的硬盘中,当运行时被读入虚拟机执行。代码区的内容通过散列函数得出校验哈希值,该值即为代码区的哈希值。
为了解决转账地址填错的问题,该提议按照一定逻辑,将地址中的部分字母大写,与剩余的小写字母来形成校验和,让地址拥有自校验的能力,具体的代码参考下方
const createKeccakHash = require('keccak')
function toChecksumAddress (address) {
address = address.toLowerCase().replace('0x', '')
var hash = createKeccakHash('keccak256').update(address).digest('hex')
var ret = '0x'
for (var i = 0; i < address.length; i++) {
if (parseInt(hash[i], 16) >= 8) {
ret += address[i].toUpperCase()
} else {
ret += address[i]
}
}
return ret
}
交易活动步骤:
消息在账户与账户之间传递数据(data)与价值(value),消息的具体表现形式如下:
"原子性"
要么完全执行,要么完全不执行
"串行"执行
不会同时并行执行
"进入区块链的顺序不确定"
Web3.js代发的交易结构
{
nonce: web3.toHex(10),
GasPrice: web3.toHex(100000000000),
Gas: web3.toHex(140000),
from: '0x633296baebc20f33ac2e1c1b105d7cd1f6a0718b',
to: '0xD1E1cdbCE15f1009B5A7874053E09C728Df91d47',
value: web3.toHex(0),
data: '0xcc9ab24952616d6100000000000000000000000000000000000000000000000000000000'
}
字段解释:
汽油数量 *Gas *由用户指定,汽油单价 *GasPrice *由市场价格决定。运行交易后多余的 *Gas *会退还给用户(惩罚性虚拟机指令assert例外,会扣除所有的剩余未花费的 *Gas *) 。 *Gas *的数值人工预测并不准确,可以让客户端软件在签发交易时代为预测,无须自己手动填写。
若该交易为普通以太币转账交易,则接收方为受益人账户地址;若该交易为调用智能合约的交易,则接收方为智能合约的地址;若该交易为创建智能合约,则接收方地址可空缺。
当若进行以太币纯转账交易时,该字段可空缺;若进行为智能合约调用,则该值包含编码后的函数名和参数的字节码;若为进行合约创建,则该值包含初始化合约的字节码。
以太坊上最常见的交易:
这三种交易在交易发送时经历的步骤是 *一模一样 *的,区别仅在于填写交易时选择传递数据 data 还是传递价值 value 。 传递数据的即为合约相关操作,传递价值即为转账操作。
分布式系统的问题就在于如何协调各个节点步调一致、共同进退。这称之为“拜占庭将军问题”。
中心化支付系统与中心化支付系统的拓扑结构
Radix树
Merkle树和Merkle证明
Merkle树是一个在密码学中常使用的树形结构,适用于解决数据完整性问题。 它的结构功能异常简单,通常我们用二叉树的形式来表示一棵 Merkle树, 它存在的作用是数据分组并保证数据在存储中的完整性。 例如一棵包含了数字 1 到 8 的 Merkle二叉树
如果碰上基础数据集不是偶数个元素(例如仅有7个数据),则复制一个元素,让它与自己的双胞胎做哈希运算
Merkle Patricia树
以太坊团队开创性地融合了Radix树和Merkle树的结构,并进一步优化该结构的存储性能,形成了实用的Merkle Patricia树
Merkle Patiricia树 (以下简称MPT树) 是一个可以存储键值对 (key-value pair) 的高效数据结构,键、值分别可以是任意的序列化过的字符串。它具有Merkle树的密码学安全校验功能,提供树中的数据完整性与存在性的 Merkle 证明。它具有强大的互动能力,在log(N)级别的时间内完成插入、删除、查询等操作。我们来循序渐进地查看如何构建一棵 MPT树。
存储树,账户状态,世界状态的构成关系
根据以太坊黄皮书,账户若是一个智能合约账户,则必定包含了 *存储树 *(storageRoot)和 *代码存储 *(codeHash)
每个区块都有一棵独立的 交易树 (transactionsRoot)
单笔交易和交易树的构成
每个区块都有一棵独立的 收据树 (receiptsRoot)
从左到右:日志、交易收据、收据树的构成
区块
*区块头 *较为轻量级,包含了一系列的数值、引用的数值以及哈希值, 总长度在 508Byte 左右;
*区块体 *较为重量级,包含了该区块收纳的交易列表和叔块列表,长度视包含的交易多寡而定,目前在 20KB 左右 。
一个以太坊区块的示意图