1. 函数类型:内部(internal)函数和外部(external)函数

函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量,也可以将一个函数作为参数进行传递,还能在函数调用中返回函数类型变量。 函数类型有两类:- 内部(internal)函数和 外部(external) 函数:

内部函数只能在当前合约内被调用(更具体来说,在当前代码块内,包括内部库函数和继承的函数中),因为它们不能在当前合约上下文的外部被执行。 调用一个内部函数是通过跳转到它的入口标签来实现的,就像在当前合约的内部调用一个函数。

外部函数由一个地址和一个函数签名组成,可以通过外部函数调用传递或者返回。

函数类型表示成如下的形式

function () {internal|external} [pure|constant|view|payable] [returns ()]

与参数类型相反,返回类型不能为空 —— 如果函数类型不需要返回,则需要删除整个 returns () 部分。

函数类型默认是内部函数,因此不需要声明 internal 关键字。 与此相反的是,合约中的函数本身默认是 public 的,只有当它被当做类型名称时,默认才是内部函数。

有两种方法可以访问当前合约中的函数:一种是直接使用它的名字,f ,另一种是使用 this.f 。 前者适用于内部函数,后者适用于外部函数。

如果当函数类型的变量还没有初始化时就调用它的话会引发一个异常。 如果在一个函数被 delete之后调用它也会发生相同的情况。

如果外部函数类型在 Solidity 的上下文环境以外的地方使用,它们会被视为 function 类型。 该类型将函数地址紧跟其函数标识一起编码为一个 bytes24 类型。。

请注意,当前合约的 public 函数既可以被当作内部函数也可以被当作外部函数使用。 如果想将一个函数当作内部函数使用,就用 f 调用,如果想将其当作外部函数,使用 this.f 。

除此之外,public(或 external)函数也有一个特殊的成员变量称作 selector,可以返回 ABI 函数选择器:

pragma solidity ^0.4.16;

contract Selector {

function f() public view returns (bytes4) {

return this.f.selector;

}

}

如果使用内部函数类型的例子:

pragma solidity ^0.4.16;

library ArrayUtils {

// 内部函数可以在内部库函数中使用,

// 因为它们会成为同一代码上下文的一部分

function map(uint[] memory self, function (uint) pure returns (uint) f)

internal

pure

returns (uint[] memory r)

{

r = new uint[](self.length);

for (uint i = 0; i < self.length; i++) {

r[i] = f(self[i]);

}

}

function reduce(

uint[] memory self,

function (uint, uint) pure returns (uint) f

)

internal

pure

returns (uint r)

{

r = self[0];

for (uint i = 1; i < self.length; i++) {

r = f(r, self[i]);

}

}

function range(uint length) internal pure returns (uint[] memory r) {

r = new uint[](length);

for (uint i = 0; i < r.length; i++) {

r[i] = i;

}

}

}

contract Pyramid {

using ArrayUtils for *;

function pyramid(uint l) public pure returns (uint) {

return ArrayUtils.range(l).map(square).reduce(sum);

}

function square(uint x) internal pure returns (uint) {

return x * x;

}

function sum(uint x, uint y) internal pure returns (uint) {

return x + y;

}

}

另外一个使用外部函数类型的例子:

pragma solidity ^0.4.11;

contract Oracle {

struct Request {

bytes data;

function(bytes memory) external callback;

}

Request[] requests;

event NewRequest(uint);

function query(bytes data, function(bytes memory) external callback) public {

requests.push(Request(data, callback));

NewRequest(requests.length - 1);

}

function reply(uint requestID, bytes response) public {

// 这里要验证 reply 来自可信的源

requests[requestID].callback(response);

}

}

contract OracleUser {

Oracle constant oracle = Oracle(0x1234567); // 已知的合约

function buySomething() {

oracle.query("USD", this.oracleResponse);

}

function oracleResponse(bytes response) public {

require(msg.sender == address(oracle));

// 使用数据

}

}

注解

Lambda 表达式或者内联函数的引入在计划内,但目前还没支持。

2. 函数可见性说明符:public,private,external,internal

public:内部、外部均可见(参考为存储/状态变量创建 getter 函数)

private:仅在当前合约内可见

external:仅在外部可见(仅可修饰函数)——就是说,仅可用于消息调用(即使在合约内调用,也只能通过 this.func 的方式)

internal:仅在内部可见(也就是在当前 Solidity 源代码文件内均可见,不仅限于当前合约内,译者注)

函数可见性说明符格式:

function myFunction() returns (bool) {

return true;

}

3. 函数修改器

pure 修饰函数时:不允许修改或访问状态——但目前并不是强制的。

view 修饰函数时:不允许修改状态——但目前不是强制的。

payable 修饰函数时:允许从调用中接收 以太币Ether 。

constant 修饰状态变量时:不允许赋值(除初始化以外),不会占据 存储插槽storage slot 。

constant 修饰函数时:与 view 等价。

anonymous 修饰事件时:不把事件签名作为 topic 存储。

indexed 修饰事件时:将参数作为 topic 存储。

4. 参考

Oracle public view,【易错概念】以太坊Solidity函数的external/internal,public/private,view/pure/payable区别...相关推荐

  1. 以太坊Solidity函数的external/internal,public/private区别

    2019独角兽企业重金招聘Python工程师标准>>> 1 函数类型内部(internal)函数和外部(external)函数 函数类型是一种表示函数的类型.可以将一个函数赋值给另一 ...

  2. 7.mysql用户管理,总结-count,exists,in,view易错点

    1.理论 /*创建本地用户teacher,密码为123456,本地用户student,无密码 */ create user `teacher`@`localhost` identified by '1 ...

  3. 【重磅推荐】基于truffle-contract库实现的以太坊solidity合约调用案例(注:web3.js切勿和truffle-contract库同时使用,否则报错,无法修复!)

    1.一个基于truffle-contract库实现的以太坊solidity智能合约调用案例! 2. 注意:truffle-contract库和web3.js使用nodej或import同时导入转码的时 ...

  4. 以太坊solidity智能合约-生成随机数

    Solidity随机数生成 在以太坊的只能合约中,没有提供像其他面向对象编程一样的生成随机数的工具类或方法.其实,所谓的随机数也是伪随机的,没有哪一种语言能够真正的生成随机数. 对于solidity来 ...

  5. 【区块链 | Solidity】以太坊Solidity如何实现海量空投代币?

    以太坊Solidity如何实现海量空投代币? 1. 摘要 通证token项目启动时,短期内繁荣生态,要舍得给粉丝们打币,把利益分出去.本文聚焦在技术层面,实现如何快速完成TOKEN海量空投,既要节约时 ...

  6. 以太坊solidity迁移flow cadence指南11 ---NFT盲盒应用

    NIST Warning:阅读本文,需要至少幼儿园中班数学水平,要能数到10!对那些只会1以内加法的码农,请在有经验的码农陪同下观看本文. 背景知识 本节主要介绍cadence随机数在盲盒中的应用. ...

  7. 以太坊Solidity发布0.8.3版本

    官方消息,以太坊Solidity发布0.8.3版本.官方表示,一个错误修复版本,修复了优化器如何处理Keccak256操作码的一个重要错误.此外,它还包括对优化器的两个改进. 文章链接:https:/ ...

  8. 【区块链】以太坊Solidity编程:合约调用与web3.js

    以太坊Solidity编程:合约调用与Web3.js 合约部署方法 合约的编译 使用浏览器编译器Remix 使用truffle编译,目前是最常用的编译方式 Solc或者Web3.js编译合约,使用相对 ...

  9. 以太坊Solidity之Truffle的使用流程与集成指南

    一.Truffle 简介 ① 什么是 Truffle ? Truffle 是一个世界级的开发环境,测试框架,以太坊的资源管理通道,致力于让以太坊上的开发变得简单. Truffle 有以下特性: 内置的 ...

最新文章

  1. android Tabhost部件
  2. linux内核网络协议栈--数据包的数据收发简略流程图(二十八)
  3. java用流体加减乘除_任意输入两个数,完成加法、减法、乘法、除法运算!(加减乘除运算分别定义四个方法)_学小易找答案...
  4. 杨国福或夺“麻辣烫第一股”,是否名副其实?
  5. VMware Workstation Pro通过ISO系统镜像安装ubuntu-18.04.2
  6. 简述JAVA线程调度的原理,Rxjava原理(二)--线程调度
  7. [设计模式] ------ 模板模式
  8. 接口测试Fiddler实战
  9. 关于ajax的content-download时间过慢问题的解决方案与思考
  10. Hive on Spark与SparkSql的区别
  11. Linux环境下实现一个简单socket通信
  12. java常见数据算法_冒泡排序
  13. 1028: [JSOI2007]麻将 - BZOJ
  14. Java不能做游戏?快来看看这个Java版超级玛丽吧。
  15. LiveVideoStackCon2021 北京站专访:从上云到创新,视频云的新技术、新场景
  16. 通过IMAP方式迁移U-Mail邮件到Exchange 2013之Exchange 2007 升级到Exchange 2013!
  17. 洛谷T37537 公主的考验
  18. 中山西路620号 的人才服务中心搬到 梅园路77号去了
  19. html中的阴影怎么使用,css 内阴影怎么做
  20. import androidx.core.app.Fragment;报红

热门文章

  1. python引用传递_python 是值传递还是引用传递 知乎
  2. matlab的7.3版本是什么_乐建工程宝V6.3版本升级说明公告
  3. PHP递归删除目录面试题,PHP 递归删除目录中文件
  4. java中同时两人提交数据_如何一起发送JSON请求和发布表单数据请求?
  5. 和push的区别_还没有理解let 和 const的用法和区别吗,几百字让你立马搞懂
  6. flash 用 html 播放,使用flash插件在HTML上播放音频
  7. python nlp data_Python nlpaug包_程序模块 - PyPI - Python中文网
  8. 11-Docker Bridge详解
  9. Problem E: 建立链表(线性表)
  10. UVA - 1587 ​​​​​​​Box