==在发布智能合约时要不断测试==

![[Pasted image 20240429153056.png]]

  • solidity语言不支持遍历
  • 智能合约的执行都在在修改本地的数据,只有在执行完并发布到区块链上之后才会成为共识
  • 要先执行合约,在挖矿
    • 要先知道block header中的三棵树的root hash才能开始挖矿
  • solidity不支持多线程
    • 执行结果不确定
  • ==在区块链上调用任何未知的合约都是危险的,要处处小心==
  • 外部账户如何调用智能合约

    • 创建一个交易,接收地址为调用的那个智能合约的地址,data域填写要调用的函数及其参数的编码值
  • 一个合约如何调用另一个合约中的函数

    • 直接调用
      • ![[Pasted image 20240429154013.png]]
    • 使用address类型的call()函数
      • ![[Pasted image 20240429154358.png]]
    • 代理调用delegatecall()
      • 不需要再被调用的合约执行,可以带在殿前合约中执行
  • fallback()函数
    • 匿名函数,无参数和返回值
    • 两种情况会被调用
      • 直接像一个合约地址转账而不加任何data
      • 被调用的函数不存在
    • 转账金额不为零,仍需要声明payable
    • 只有合约账户才有fallback和payable,外部账户没有

智能合约的创建和运行

  • 创建账户:
    • 外部账户发起一个转账交易到0x0的地址
    • 把合约的代码放在data域里面
    • 转账金额为0
  • 运行在EVM上(Ethereum Virtual Machine)256位 -:提供一个虚拟机,让智能合约提供一个一致的平台

汽油费(gas fee)

  • 智能合约是一个turing-complete Programming Model(图灵完备模型)
  • 出现死循环怎么办
    • 执行合约的指令要收取gas fee,由发起交易的人来支付
      • ![[Pasted image 20240429160438.png]]
        • price是单位gas价格
        • gaslimit是能支付的最大gas值
        • payload是data域
      • 先支付最大汽油费,然后多退,少的话就回滚交易
        • 但是已经消耗的gas不会返还
          • 防止攻击
      • EVM中不同指令的gas fee不同
        • 复杂的或需要存储状态的指令会比简单的昂贵
  • block header里的gas limit是区块中所有交易的gas fee的上限
    • 在发布区块时新的区块可以把gas limit上调或下调至少1/1024
  • 收取gas fee时,在本地维护的状态树上扣除余额

错误处理

  • 智能合约没有try-catch
    • 出现错误用户不能自己决定行为
  • ETH中的交易具有原子性,要么执行要么不执行。
    • 在智能合约的执行出现任何错误,会直接回滚
  • asssert语句:
    • 判断内部条件
  • require:
    • 外部条件
      • 例:函数输入是否符合要求
  • revert:
    • 无条件执行错误

嵌套调用

  • 调用一个合约调用另一个合约的函数
    • 直接调用会引起发起调用合约的回滚
    • 函数调用不会
  • 一个合约向另一个合约账户转账,没有指明调用那个函数,仍会引起嵌套调用

receipt数据结构

  • ![[Pasted image 20240429165601.png]]
    • 收据内容

智能合约可以得到的区块内容

  • 给定区块的hash——最近256个
  • 挖出当前区块的miner地址(coinbase)
  • 当前区块的难度
  • gas限额
  • 当前区块号
  • 自unix epoch起始当前区块的时间戳

可以得到的调用信息

![[Pasted image 20240429171013.png]]

地址类型

![[Pasted image 20240429171107.png]]

  • transfer会导致连锁式回滚
  • call的转账会把剩余的所有gas全发过去

智能合约实例

![[Pasted image 20240429172955.png]]
上面合约应定义一个fallback函数,否则会报错,导致连锁性的回滚,里面的钱会被永久锁定
code is law
irrevocavle trust
![[Pasted image 20240429174754.png]]

  • 重入攻击(Re-enteancy Attack)
    • 当合约账户收到ETH,但为调用函数时,会自动执行fallback函数
    • 三种转帐方式都会处罚fallback函数
    • fallback函数由用户自己书写![[Pasted image 20240429175108.png]]
    • ![[Pasted image 20240429175358.png]]![[Pasted image 20240429175700.png]]