- 必读 : Ethereum White Paper
-
Externally owned account(EOA) VS. Contract account
两者都使用20字节的地址。EOA外部拥有账户是由用户通过公钥/私钥秘钥对控制的,通过以太坊客户端创建,由秘钥对生成的账户地址。而Contract account则是EOA通过调用创建合约的方法创建的账户,账户内包含合约代码,由调用方EOA的地址和调用方等nonce(该值针对EOA递增,目的为防止重放攻击)经过PLP编码和KEC散列生成账户地址。交易只能由EOA发起,目的方可以是EOA(常见的转账行为,交易transaction的data字段为空),也可以是合约账户(调用执行智能合约,一次调用中也可能包含跨合约调用,即合约账户到另一个合约账户,此时交易transaction的data字段存放的是合约调用的方法名,参数等二进制数据),还有合约部署(目的地址为0,交易transaction的data字段存放)。
It is not the code that is executed on subsequent transactions sent to the contract. That code is returned by the initialization code. Essentially, the code in the data field is a program that is going to write a program that gets deployed as a smart contract.(部署字节码 + 合约字节码 + AUXDATA + Swarm hash) The standard initialization code generated by the Solidity compiler does the following:
- Runs the code in the contract’s constructor, setting storage values, etc.
- Copies the code for the rest of the contract into memory and returns it.
新部署的合约代码被打包提交到链上后,所有到运行节点都会执行data字段里的部署代码(特殊情况是部分节点只按需存储部分数据),其合约存在于各运行节点各自的EVM内,并且对应的地址都是一致,即地址与合约对应,保证后续的合约调用。合约代码存放在EVM的virtual rom内,code hash值为代码的哈希值,storage hash存放的是账户的MPT树的root hash。简之,部署合约三个步骤:1. 创建合约账户 2. 执行合约的初始化 3. 拷贝到virtual rom
How Ethereum Transactions Work
How Smart Contract Deployment Works
-
MPT
MPT(Merkle Patricia Tries)是以太坊中存储区块数据的核心数据结构,它是 Merkle Tree 和 Patricia Tree 融合一个树形结构。附上经典的官方结构示例。具体的代码分析网上资料详细。
以太坊采用改进的Merkle树,因为前后两个block的数据绝大部分都是相同的,不需要同时存储两份。新block的树可以引用上一个block,加上新block内的交易修改的账户。
以太坊源码分析–MPT树
Ethereum以太坊源码分析(三)Trie树源码分析(上)
Ethereum以太坊源码分析(三)Trie树源码分析(下) -
Event
In Ethereum, when a transaction is mined, smart contracts can emit events and write logs to the blockchain that the frontend can then process. Event在Ethereum里主要有三种用途:- smart contract return values for the user interface
发送交易调用合约的返回结果是交易的哈希值,而不是合约的返回值(只有在被打包进区块时才执行合约)。执行合约产生的结果可以作为时间写入区块,调用方可以根据合约哈希值相应获取。 - asynchronous triggers with data
异步时间触发,类似于观察者模式。 - a cheaper form of storage
称为log(通过LOG这个EVM操作码)。相比stroage耗费的gas小得多,可以用作存储,但是不能在合约中被调用。例如可以存放历史数据,前端可以通过遍历区块去获取。
- smart contract return values for the user interface
- GHOST
GHOST协议(Greedy Heaviest Observed Subtree protocol)。同样是POW,比特币由于出块时间10min,取最长链。而Ethereum出块时间短(6s),不足扩撒至全网,如果取最长链,则地域优势明显。因此,Ethereum选择最重的链,也就是兄弟节点之间子树节点最多的被选为主链。例子可以参考 以太坊Ghost协议和叔块。主要是要解决 1. 出块速度快,存在多个节点同时出块,但是在自身出块后才接收到别的节点传输的块,浪费算力。2. 更严重的是因为出块速度块带来的地域优势,越早接收到合法块的节点出下一个块的可能性更大,从而造成的中心化风险。通过增加叔块选择最重的链,也就是选择工作量最大的链,降低地域优势。同时奖励叔块,激励节点出块。
官方文档 - Modified GHOST Implementation : 详细介绍了GHOST稀释风险,以及叔块的选择标准和奖励方案。