Solidity函数声明和类型

  • 函数的值类型有两类:内部(internal)类型和外部(external)类型
  • 内部函数只可以在当前合约内部被调用(即在当前代码块内,包括内部库函数和继承函数),因为他们不能在当前合约的上下文中的外部被执行。调用一个内部函数是通过跳转到它的入口标签来实现的,就像在当前合约的内部调用一个函数
  • 外部函数是由一个地址和一个函数的签名组成,可以通过外部函数调用传递或者返回
  • 调用内部函数,直接使用名字f
  • 调用外部函数:this.f(当前合约),a.f(外部合约)
  • 除了使用外部函数调用外,还可以使用继承机制

例子(外部函数调用)

contract C{uint a;function f() public{}
}
contract D{function g() public{C c = new C();c.f();}
}

例子(继承机制)

  • 可以使用internal函数/public函数,不可以使用private函数
  • D继承C合约,只会把交叉的函数编译上传
contract C{uint a;function f() public{}
}
contract D is C{function g() public{f();}
}

函数的可见性

  • 函数的可见性可以指定为external、public、internal或者private;对于状态变量,不可以设置为external,默认是internal
  • external:外部函数作为合约接口的一部分,意味着我们可以从其他合约和交易中调用。一个外部函数f不可以从内部调用(即f不起作用,但是this.f可以)。当接收到大量的数据的时候,外部函数有时候会更有效率
  • public:public函数是合约接口的一部分,相当于定义了一个view类型的可以返回参数的函数,可以在内部或者通过消息调用。对于public状态变量,会自动生成一个getter函数

例子

uint public a;//将a声明为public,就相当于为a定义了如下的函数形式
function a() public view returns (uint){return a;
}
  • internal:这些函数和状态变量只能是内部访问(即从当前合约内部或者从其他派生的合约访问),不可以使用this
  • private:private函数和状态变量仅在当前定义他们的合约中使用,并且不能被派生合约使用。

函数状态可变性

  • payable:允许从消息调用中接收以太币Ether
  • constant:和view相同,一般只修饰状态变量,不允许赋值(除了初始化之外)
 constructor()public payable{}//创建合约的同时需要往合约上面转钱
  • pure:纯函数,不允许修改或者访问状态
  • view:不允许修改状态

函数状态可变性

  • 修改状态变量
  • 产生事件
  • 创建其他合约
  • 使用selfdestruct(自杀/自毁)
  • 通过调用发送以太币
  • 调用任何没有标记为view或者pure的函数
  • 使用低级调用
  • 使用包含特定操作吗的内联汇编

以下是被认为从状态中进行读取

  • 读取状态变量
  • 访问this.balance或者<address>.balance
  • 访问block、tx、msg中任意成员(除了msg.sig和msg.data之外)
  • 调用任何未标记为pure的函数
  • 使用包含某些操作码的内联汇编

函数修饰器 modifier

  • 使用修饰器modifier可以轻松改变函数的行为。例如,他们可以在执行函数之前自动检查某个条件。修饰器modifier是合约的可继承属性,并可能被派生合约覆盖
  • 如果同一个函数有多个修饰器modifier,他们之间可以使用空格隔开,修饰器modifier会依次检查执行。

代码

contract Purchase{address public seller;constructor() public{seller = msg.sender;}modifier onlySeller(){require(msg.sender == seller,"Only seller");_;}function f() public view onlySeller returns(uint){return 200;}
}

效果展示

  • msg.sender是合约的部署者,只有合约的部署者调用f函数,返回200,剩余的人会返回错误信息,only seller
  • require(msg.sender == seller,"Only seller");逗号之前是检查条件,之后是返回报错信息,检查条件在代码流程之前执行
  • _;将代码流程嵌套到这里,指代检查条件执行之后,执行代码的逻辑。(函数体)

回退函数(fallback)

  • 回退函数(fallback function)是合约中的特殊函数;没有名字,不能有参数也不能有返回值
  • 如果在一个到合约的调用中,没有其他函数与给定的函数标示符匹配(或者没有提供调用函数),你们这个函数(fallbacj函数)会被执行
  • 每当合约收到以太币(没有任何数据),回退函数就会执行。此外,为了接收以太币,fallback函数必须标记为payable。如果不存在这样的函数,则合约不能通过常规交易接收以太币
  • 在上下文中只有很少的gas可以用来完成回退函数的调用,所以使fallback函数的调用尽量廉价很重要

代码

pragma solidity >0.4.99  <0.6.0;
contract Sink{function() external payable{}
}
contract Test{function() external {x=1;}uint x;
}contract Caller{function calllTest(Test test)public returns(bool){(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));require(success);address payable testPayable = address(uint160(address(test)));return testPayable.send(2 ether);}
}

注解

  • 调用合约中不存在的函数和转钱的时候会调用回退函数
  • 回退函数适用在合约5.0版本以上

事件(event)

  • 事件是以太坊EVM提供的一种日志基础设施。事件可以用来做操作记录,存储为日志。也可以用来实现一些交互功能,比如通知UI,返回函数的调用结果
  • 当定义的事件被触发时,可以将事件存储到EVM的交易日志中,日志是区块链中的一种特殊的数据结构;日志和合约相互关联,与合约的存储合并存入到区块链条中,只要某个区块可以访问,其相关的日志就可以访问,但是在合约中是不可以之间访问日志和事件数据
  • 可以通过日志实现简单支付验证SPV,如果一个外部实体提供了一个带有这种证明的合约,它可以检查日志是否真实存在于区块链中

异常处理

  • 适用状态恢复异常来处理异常。这样的异常将会撤销对于当前的调用(及其所有的子调用)中的状态所做的所有的更改,并且向调用者返回错误
  • 函数的assert和require用于判断条件,并且在不满足条件的时候抛出异常
  • assert()一般只应用于测试内部的错误,并且检查异常
  • require()应用于确保满足有效的条件(如输入或合约的状态变量),或者验证调用外部合约的返回值
  • revert()用于抛出异常,它可以标记一个错误并且将当前调用回退

单位

  • 以太币单位之间的换算就是在数字后边加上wei、finney、szabo或者ether来实现,如果没有单位,缺省为wei

时间

  • 秒是缺省单位,在时间单位之间,数字后面带有seconds、minutes、hours、days、weeks和years的可以进行换算 但是这些后缀不可以直接用在变量的后边,如果需要使用到时间单位(例如days)来将输入变量转换为时间,可以使用如下方式
function f(uint start,uint daysAfter)public{if (now >= start + daysAfter * 1 days)
}

深入理解Solidity 三相关推荐

  1. Java虚拟机JVM简介与理解(三)

    Java虚拟机JVM简介与理解(三) 问题背景 PC程序计数器 虚拟机栈 本地方法栈 堆 元空间 方法区 运行时常量池 直接内存 Lyric: 彻底把我囚禁在你的呼吸 问题背景 Java虚拟机JVM简 ...

  2. 通过Socket编程理解TCP三次握手

    Socket编程--应用层开发 由于传输层以下都是属于操作系统内部的服务(内部的网络管理模块) Socket就是其提供的窗口,如果你想利用系统网络管理中的传输层.网络层.链路层服务你都需要通过Sock ...

  3. 如何理解道德经三个字

     <道德经到底在说什么>(一)如何理解道德经三个字 一.道 <尔雅·释宫>:一达谓之道路,二达谓之歧旁,三达谓之剧旁,四达谓之衢,五达谓之康,六达谓之庄,七达谓之剧骖,八达 ...

  4. 本质安全设备标准(IEC60079-11)的理解(三)

    本质安全设备标准(IEC60079-11)的理解(三) 对于标准中"fault"的理解 第一,标准中对fault的定义是这样的: 3.7.2 fault any defect of ...

  5. PPP完全理解(三)

    PPP完全理解(三) 内核ppp协议处理模块代码分析 作者:李圳均 日期:2013/11/27 点对点协议(PPP)为在点对点连接上传输多协议数据包提供了一个标准方法.ppp 位于数据链路层,是一种为 ...

  6. 挣值分析-概念理解(三步学会)

      对于新接触挣值分析的人来说,看到密密麻麻的公式(PV.EV.AC.SV.SPI.CV.CPI.ETC.EAC.BAC),很容易搞混之间的关系,以下是自己的学习心得和理解,希望帮助读者快速稳固的学会 ...

  7. 【Solidity】3.类型 - 深入理解Solidity

    索引 [Solidity]1.一个Solidity源文件的布局 [Solidity]2.合约的结构体 [Solidity]3.类型 [Solidity]4.单位和全局可变量 [Solidity]5.表 ...

  8. 深入理解Emoji(三) —— Emoji详解

    深入理解Emoji(一) -- 字符集,字符集编码 深入理解Emoji(二) -- 字节序和BOM Emoji字符是Unicode字符集中一部分. 特定形象的Emoji表情符号对应到特定的Unicod ...

  9. 递归函数的理解 (三种类型)

    函数的递归调用 递归问题是一个说简单也简单,说难也有点难理解的问题.我想非常有必要对其做一个总结. 首先理解一下递归的定义,递归就是直接或间接的调用自身.而至于什么时候要用到递归,递归和非递归又有那些 ...

最新文章

  1. android图片保存形式,Android应用开发之Android ScrollView截图和图片保存到相册的方式...
  2. SpringCloud注册与发现Eureka
  3. Ubuntu18.04 安装wine
  4. can卡通用测试软件LCANTest详细介绍
  5. cadence从原理图导出器件库_一种cadence中原理图替换元器件库的方法与流程
  6. Maya 2018 for Mac中文破解版永久激活方法含注册机
  7. ppm/℃是什么单位?什么意思?
  8. 数据库:order by排序语句的用法
  9. 人工智能,机器学习,深度学习(笔记)
  10. java 获取当前第几周_java 计算当前日期是今年的第几周 和 该周的开始日期及结束日期...
  11. 螺旋线java_java怎么画布画阿基米螺旋线
  12. OPPOR9Android 6.0过程,超简单 OPPOR9升级Android 6.0系统 详细教程
  13. 【批处理DOS-CMD命令-汇总和小结】-上网和网络通信相关命令-用户账户管理-文件(夹)共享(net)
  14. 友元(友元函数、友元类、类成员函数的友元)
  15. 如何推广淘宝店铺方法:导购网站免费推广
  16. Pt100转RS-485,热电阻温度Modbus数据采集模块 WJ125
  17. 网易互娱人工智能工程师笔试题
  18. OpenSSL、OpenSSL-FIPS、OpenSSL-FIPS-ECP的区别
  19. vs2013设置不生成.sdf和ipch文件
  20. 单因素方差分析,卡方检验,充分条件必要条件

热门文章

  1. mfc点击按钮让对话框关闭_WinXP系统开始菜单中关机按钮消失的恢复教程
  2. 【转】c#数字图像处理(一)Bitmap类、 Bitmapdata类和 Graphics类
  3. SharePoint PowerShell命令系列
  4. html背景定位,css background-position center left right top bottom代表意思
  5. 查找算法-(顺序查找、二分查找、插值查找、斐波那契查找)
  6. REVERSE-COMPETITION-GeekChallenge2021
  7. RSA公私钥加解密方式-工具类
  8. musictools怎么用不了_夏天少不了一只草编包,怎么搭配才不像“买菜用”?
  9. 【HDU - 1542】Atlantis (线段树,扫描线)
  10. spring的beanutils工具类_基于spring-beans实现工具类BeanUtils基于Class实例化注入对象及查找方法、复制属性等操作...