ETH——智能合约

智能合约是以太坊的精髓,也是以太坊和比特币最大的一个区别。

什么是智能合约

  • 智能合约是运行在区块链上的一段代码, 代码的逻辑定义了合约的内容。

  • 智能合约的账户保存了合约当前的运行状态

    • balance:当前余额
    • nonce:交易次数
    • code:合约代码
    • storage:存储,数据结构是一棵MPT
  • Solidity是智能合约最常用的语言,语法上与JavaScript很接近。

    ETH——智能合约_第1张图片
    合约账户之间也可以进行调用。其调用方式如下:

  • 直接调用
    ETH——智能合约_第2张图片
    如果调用的合约在过程中出现错误,会导致发起调用的这个合约也跟着一起回滚,例如A的合约操作异常,会导致B的合约也跟着出错。

  • address类型call()函数调用

    如果在调用过程中,被调用合约出现异常,call()函数会返回false,表明这个调用是失败的,但是发起调用的函数不会抛出异常,而会继续执行。

  • delegatecall()调用

ETH——智能合约_第3张图片

关于payable(),以太坊中凡是要接受外部转账的函数,都必须标志位payable。

  • fallback()函数
    ETH——智能合约_第4张图片
    该函数主要是防止A向B转账,但没有在data域中说明要调用哪个函数或说明的要调用函数不存在,此时调用fallback()函数。
    只有合约账户才有代码,因此这些只和合约账户有关。如果没有fallback(),在发生之前的情况后,就会直接抛出异常。
    另:转账金额和汽油费是不同的。汽油费是为了让矿工打包该交易,而转账金额是单纯为了转账,其可以为0,但汽油费必须给。

智能合约的创建和运行


EVM类似于JVM,增强了可移植性。通过加一层虚拟机,对智能合约的运行提供一个一致性的平台。所有有时候也被称为world wide computer。EVM寻址空间也是非常大的,256位。

汽油费(gas fee)

比特币与以太坊设计理念有很大差别的,比特币的设计理念是简单,脚本语言的功能很有限,不支持循环。以太坊的智能合约是一个图灵完备的编程模型,很多功能在比特币平台上实现起来很困难,甚至实现不了,而在以太坊平台上就很容易实现起来,当然也会有问题,比如可能导致死循环。
对于死循环问题是一个Halting Problem,停机问题,是不可解的。

错误处理

以太坊中交易具有原子性,要么全执行,要么全不执行,不会只执行一部分(包含智能合约)。
需要注意的是,在执行过程中产生错误导致回滚,已经消耗掉的汽油费是不会退回的。从而有效防止了恶意节点对全节点进行恶意调用。
ETH——智能合约_第5张图片

ETH——智能合约_第6张图片

智能合约支不支持多核并行处理?
多个核对内存访问顺序不同的情况下,执行的结果有可能是不确定的。以太坊中产生的随机数也不是真正意义上的随机数,是伪随机数。

ETH——智能合约_第7张图片
ETH——智能合约_第8张图片
ETH——智能合约_第9张图片
在以太坊中,转账有以下三种方法:transfer、send、call。

  • transfer在转账失败后会导致连锁性回滚,抛出异常,类似于直接调用;
  • send转账失败会返回false,不会导致连锁性回滚。
  • call的方式本意是用于发动函数调用,但是也可以进行转账。
    前两者在调用时,只发生2300wei的汽油费,这点汽油费很少,只能写一个log,而call的方式则是将自己还剩下的所有汽油费全部发送过去(合约调用合约时常用call,没用完的汽油费会退回)。例如A合约调用B合约,而A不知道B要调用哪些合约,为了防止汽油费不足导致交易失败,A将自己所有汽油费发给B来减少失败可能性。

ETH——智能合约_第10张图片
智能合约这么写存在问题:

ETH——智能合约_第11张图片
智能合约的规则是由代码逻辑决定的,code is law。代码一旦发布到区块链上就改不了了,这样的好处是没有人能篡改规则,这样的坏处是规则中有漏洞也改不了。
智能合约如果设计的不好的话,有可能会把收到的以太币永久的锁起来,导致谁也无法取不出来。

ETH——智能合约_第12张图片
ETH——智能合约_第13张图片
ETH——智能合约_第14张图片
黑客递归调用重复取钱,持续到拍卖合约账户余额不够,汽油费不够(因为每次调用都会消耗汽油费),调用栈溢出 。
ETH——智能合约_第15张图片
参考资料:https://www.bilibili.com/video/BV1Vt411X7JF?p=22

你可能感兴趣的:(区块链技术)