热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

区块链技术与应用【肖臻老师】笔记整理之22ETH智能合约

注:没有全部复原,抽取了主体知识,加入了一些自己的理解,强烈建议去学习肖臻老师的课程,这绝对算得上是国内区块链讲解的顶级教程,纯学术和技术智能合约是以太坊的精髓。智能合约是运行在区




注:没有全部复原,抽取了主体知识,加入了一些自己的理解,强烈建议去学习肖臻老师的课程,这绝对算得上是国内区块链讲解的顶级教程,纯学术和技术


智能合约是以太坊的精髓。

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

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


  • balance 当前余额
  • nonce 交易次数
  • code 合约代码
  • storage 存储,数据结构是一棵MPT

Solidity是智能合约最常用的语言,语法上与Javascript很接近

在这里插入图片描述

强类型语言,

mapping不支持遍历,需要自己记录hash表中有哪些元素

event事件,是用来记录日志的

有两种方式,第一种是与合约同名的函数,没有返回值,第二种是使用constructor函数

构造函数constructor只能有一个


如何调用智能合约

调用合约与转账类似,

A->B,如果B是外部账户那就是最普通的交易,如果B是合约账户,那么就相当于发起对B的合约的一次调用

具体调用的是哪个函数,是在数据域中说明的,data域

在这里插入图片描述

在这里插入图片描述

emit的作用就是写一个Log

一个交易只能由外部账户发起,而不能由合约账户发起,

另一种交易方式:

在这里插入图片描述

delegatecall():与call()的方法基本上是一样的,一个主要的区别是,Delegatecall()不需要切换到被调用的合约的环境中去执行,而是在当前的环境中执行就可以了。

在这里插入图片描述

以太坊中凡是接受外部转账的交易都必须标记为payable(),否则给这个函数转钱的时候会抛出错误异常。

在这里插入图片描述

没有别的函数可调用时就调用fallback()函数

如果fallback()函数不是payable的,那么别的函数向该合约地址转账会引发异常

只有合约账户才有这些智能合约

转账金额是0,但是Gas 不能为0,那是给Miner的,否则miner不会打包区块

在这里插入图片描述

JVM:增强可移植性

EVM:世界计算机,256位寻址空间

在这里插入图片描述


  • Payload就是data域,用于存放调用的是合约中的哪个函数,函数的参数取值是什么
  • 当全节点收到对智能合约的调用的时候,首先是按照GasLimit算出可能需要的最大Gas费,然后一次性将Gas费从发起账户中扣除,然后再根据实际的汽油费,多退少了就回滚机制
  • 不同的指令消耗的Gas费是不一样的,一些简单的指令很便宜,比如加减操作,复杂的指令很贵,比如取哈希,需要存储状态的指令也很贵,读取公众数据是可以免费的

在这里插入图片描述


  • 以太坊中的交易具有原子性,一个交易要么全部执行 要么完全不执行,不会只执行一部分,交易既包含对普通的转账也包含对合约的调用。所以如果在执行智能合约的过程中出现错误,会导致整个交易的回滚,退回到开始执行之前的状态。比如交易进行到一半时,Gas消耗完了,那么交易要回滚,但是Gas费是不退回的。

  • revert()函数是无条件的终止

在这里插入图片描述


  • 直接调用会引起连锁式回滚
  • 使用call()的方式不会引起连锁式回滚

在这里插入图片描述


  • GasLimit:是整个区块所有交易Gas消耗的上限

  • 每个区块可以上调和下调上一个区块GasLimit的





    1


    1024




    \frac{1}{1024}


    10241​,所以最后趋近于所有矿工的平均值

  • 先Mining还是先执行智能合约?


    • 三棵树都是全节点在本地维护的数据结构
    • 执行智能合约是改变自己本地的状态,只有达成了共识,发布到区块上,当与发布区块的状态不一致时,Miner会丢弃自己的状态转而更新本地三棵树,进行同步。都是需要重新执行一遍
    • 所以先执行,后挖矿。
    • 得先更新Blockheader里面的Root,TxHash,ReceiptHash。确定了Block Header,然后才可以进行Minging
  • 会不会因为没有奖励,有的Miner就不去验证区块的正确性?


    • 可能会存在,但是如果不验证的话,那么其Block header就得不到更新,本地的状态不对,以后就无法Mining,发布的区块得不到别人的验证
  • 发布到区块链上的交易是不是都是成功执行的?:不一定


    • 如果智能合约出现了错误要不要也发布到区块链上去?
      • 要,否则Gas费用扣不掉,要达成共识,这样Miner才能收钱

在这里插入图片描述


  • status就是告诉你交易执行的情况是什么样

  • 智能合约支不支持多核并行处理?


    • Solidity不支持多线程,没有多线程的语句。

    • 给定 一个 智能合约,给定输入,它转移到的状态或者说是输出必须是完全确定的


      • 因为所有的全节点都得执行同一组操作到达同一种状态,如果状态不确定的话,那三个根哈希值根本对不上,必须完全确定才可以

      • 多线程的问题在于,多个核对内存访问顺序不同的话,执行结果有可能是不确定的

      • 导致执行结果不确定的操作:产生随机数。伪随机数的产生也是不确定的

在这里插入图片描述

在这里插入图片描述


  • 智能合约里没有办法获得精确的时间,只能获得和当前区块的时间信息

在这里插入图片描述


  • callcode
  • .transfer是指往address里转,只有一个参数,转入的地址

例子:简单拍卖

在这里插入图片描述

在这里插入图片描述


  • 有什么问题?

在这里插入图片描述


  • 最后都收不到钱,hackV1没有fallback函数,退款时会出现问题


    • 当一个合约收到转账没有调用任何函数时,会调用fallback,但是没有fallback函数,所以会调用失败,会抛出异常,而transfer函数,会引起连锁式的回滚,最后导致所有人都收不到钱。
  • 出现这种问题怎么办?


    • 没有办法233
    • Code is law,改不了,没有人篡改规则,坏处是规则不好也无法改变
    • 智能合约设计的不好的话,ether可能永久锁起来,谁都取不出来
    • 类似于不可撤销的信托。irrevocable trust
    • 一定要测试,测试再测试
  • 能不能留一个后门,以后改,类似系统管理员


    • 与去中心化理念是背道而驰的

在这里插入图片描述


  • 这样可以了吗?
  • 重入攻击

在这里插入图片描述


  • 直到什么时候结束?
    • 余额不够
    • 调用栈溢出
    • Gas费不够了

在这里插入图片描述


  • send和transfer有一个共同的特点:
    • 转账过去的Gas费只有2300Wei
    • 不足以让接收者再发起一次新的调用,只够写一个Log


推荐阅读
author-avatar
手机用户2602879667
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有