以太坊智能合约的奇幻漂流

作者: Codefine好码实验室 | 来源:发表于2018-12-24 01:55 被阅读0次

    "A smart contract is a computer program executed in a secure environment that directly controls digital assets." -- Vitalik Buterin

    作为以太坊的标志性技术, 网络上已经有非常多的文章对智能合约进行了介绍。今天Cindy将主要带领大家经历一场以太坊上智能合约的生命周期之旅, 一起经历合约存储、创建、部署、执行、升级与销毁的过程。

    一起出发吧!

    第一站: 合约存储

    以太坊上两种账户类型: a) 个人账户 b)合约账户

    首先, 以太坊智能合约有两种类型的账户: 外部个人账户和合约账户。这两种类型账户的功能和特点都不一样。

    其次, 合约在部署时, 就会创建一个合约账户, 合约代码的可执行字节码(Bytecode)保存在合约账户(CA)中。具体来说就是存在账户codehash指向的存储区域; codeHash是代码的hash值,创建后不可更改。

    再次, 数据主要存储在账户storageRoot指向的存储区域; storageRoot对应合约存储结构的MPT树根节点hash值,通过它能够在数据库中检索到合约的变量信息。

    最后, 所有的基础存储目前都基于leveldb, 一种kv数据库。

    第二站: 合约创建

    这里我们用用户A的例子做说明。

  1. 用户A使用solidity等语言创建一份合约代码

  2. A在IDE/钱包/其他客户端,按一定的格式(from,data,value,Gas,GasPrice....)填写data,然后确认(即发起一次transaction)

  3. 客户端会填补 account nonce(tx计数器)、compile solidity、签名 等操作,并将to字段置零(代表合约创建)。

  4. 该tx广播到网络上,B节点收到该tx。

  5. B节点检查TX是否有效、格式是否正确,验证交易签名是否合法。如果符合要求,计算可能的最大交易费用,确定发送者的地址,并在本地的区块链上查看发送者的余额,如果账户余额不足以支付最大的交易费用,则返回错误。

  6. 对于符合要求的交易请求,B将其放在交易存储池中,并向其他节点转发(比如转发给了C)。C收到交易请求的节点重复用户B的处理过程。

  7. 第三站: 合约部署

    我们加入矿工B和C。

    部署与挖矿过程

  8. B和C各自从本地的交易存储池中拿到一批TX,然后打包进行hash计算(挖矿)。

  9. 假设B挖矿成功(获得了记账权),B会根据A提供的交易费用和合约代码,创建合约账户,并在账户空间中部署合约。合约账户地址在创建合约的TX确认后返回给A

  10. B打包好的区块(包含A创建的智能合约)发送至对等节点,并在全网传播。

  11. C接收到该区块,验证区块,如果区块通过验证:

    1. ‍C从内存池中删除A创建的智能合约交易请求

    2. C将区块链接到本地最长链上(同步区块)

    3. C将A的智能合约部署在本地区块链中。

    区块验证过程

    第四站: 合约执行

    合约执行过程

  12. 用户A按照一定格式在网络中发起一个TX请求;该请求被网络中节点B收到:

    1. 如果符合要求,计算可能的最大交易费用(最大交易费用=Gas Limit×GasPrice),确定发送方的地址,并在本地的区块链上从发送方账户中减去相应费用

    2. 如果账户余额不足,则返回错误,这条交易被直接丢弃。

  13. B 同步到此交易,检查交易是否有效、格式是否正确。

  14. 符合要求的交易请求,用户B将其放在交易存储池中,并向其他节点转发. 其他节点执行和B同样的操作过程.

  15. B挖矿成功。

    1. 对于转账交易,B将该交易和其他交易一起打包到区块。

    2. 对于合约调用交易,B将该交易和其他交易一起打包到区块中,并在本地的EVM上运行合约代码: 

      1. 如果代码并未结束而Gas已经用完,那么因代码运行而改变的状态回滚到代码运行之前,但是已经支付的交易费用不可收回,交易费用由B获得。

      2. 如果代码运行结束Gas还有剩余,那么B只会获得消耗的Gas×GasPrice作为手续费,不会收取剩余Gas对应的手续费。

    3. B将包含A交易请求的区块传播到对等节点,在网络中广播。

  16. C节点收到该区块后:

    1. 验证区块(用户A的交易的合法性也被再次验证)

      1. 验证通过,C将内存池中A的交易请求删掉,同时将B的区块添加到本地的区块链中

      2. 验证不通过,C丢弃该区块。

    2. 执行区块中的智能合约交易

      1. C在本地的EVM上运行该智能合约,并与B的执行结果互相验证。

  17. 网络上其他矿工节点重复C的执行过程:通过EVM在本地计算机上运行智能合约,作为他们参与挖矿进程的一部分,然后得出一个结果并进行验证。

    1. 理论上,如果没有人恶意操作,每个计算机代码运行的结果都是相同的,因为它们运行着提供了相同信息的相同合约代码。

    第五站: 合约升级

  18. 部署在以太坊区块链上的代码是不可改变的,即无法重新部署一个新的合约到相同的地址上。

  19. 智能合约升级较为困难, 务必需要一次性将合约写"完美"(测试/验证要求极高)。

  20. hacking办法:

    1. 部署一个拥有调用转发功能的智能合约

    2. 将收到的调用转发到另外一个包含逻辑功能的合约地址

    3. 当进行合约升级时,只需要部署一个新的合约并修改转发的目标地址,以指向新的合约。

    第六站: 合约销毁

    合约发起者可以调用selfdestruct()方法即可销毁合约。举例:

    终点站

    好啦, 看完了以太坊智能合约的6个生命周期过程, 各位是否在写代码的时候更有深入的体会了呢? 

    欢迎大家回复"加群",加入Codefine好码安全科技技术交流群,继续以太坊上的奇幻之旅吧!

    参考材料:

    https://blog.ethereum.org/2016/06/02/go-ethereums-jit-evm/

    https://github.com/ethereum/go-ethereum/blob/master/core/vm/evm.go

    以太坊技术详解与实战. 闫莺;郑凯;郭众鑫 编著 出版日期: 2018年06月


    ©本文为Codefine原创文章。作者简介:Codefine好码安全团队专注于智能合约安全审计和全生命周期管理, 已为全球多家交易所、钱包、公链做过智能合约安全审计和开发管理。团队通过独有的多维审计引擎,持续为合作伙伴提供正确、安全、可用的智能合约基础设施。官网地址:www.codefine.io

    本文经「原本」原创认证,作者好码实验室,访问yuanben.io查询【1Y8L5003】获取授权

    相关文章

      网友评论

        本文标题:以太坊智能合约的奇幻漂流

        本文链接:https://www.haomeiwen.com/subject/ukxakqtx.html