本文首发于深刻浅出区块链社区 原文连接:智能合约语言 Solidity 教程系列3 - 函数类型原文已更新,请读者前往原文阅读html
Solidity 教程系列第三篇 - Solidity 函数类型介绍。 Solidity 系列完整的文章列表请查看分类-Solidity。编程
Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解,若是你还不了解,建议你先看以太坊是什么oracle
本文前半部分是参考Solidity 官方文档(当前最新版本:0.4.20)进行翻译,后半部分函数可见性( public, external, internal, privite )深度分析(仅针对专栏订阅用户)。编程语言
函数也是一种类型,且属于值类型。 能够将一个函数赋值给一个函数类型的变量。还能够将一个函数做为参数进行传递。也能够在函数调用中返回一个函数。 函数类型有两类:内部(internal)和外部(external)函数函数
内部(internal)函数只能在当前合约内被调用(在当前的代码块内,包括内部库函数,和继承的函数中)。 外部(external)函数由地址和函数方法签名两部分组成,可做为外部函数调用的参数,或返回值。学习
函数类型定义以下:区块链
function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]
若是函数不须要返回,则省去returns (<return types>) 函数类型默认是internal, 所以internal能够省去。但以此相反,合约中函数自己默认是public的, 仅仅是看成类型名使用时默认是internal的。ui
有两个方式访问函数,一种是直接用函数名f, 一种是this.f, 前者用于内部函数,后者用于外部函数。this
若是一个函数变量没有初始化,直接调用它将会产生异常。若是delete了一个函数后调用,也会发生一样的异常。编码
若是外部函数类型在Solidity的上下文环境之外的地方使用,他们会被视为function类型。它会编码为20字节的函数所在地址,和在它以前的4字节的函数方法签名一块儿做为bytes24类型。 合约中的public的函数,可使用internal和external两种方式来调用。 internal访问形式为f, external访问形式为this.f
public (或 external) 函数有一个特殊的成员selector, 它对应一个ABI 函数选择器。 ```js pragma solidity ^0.4.16;
contract Selector { function f() public view returns (bytes4) { return this.f.selector; } } ```
下面的代码显示内部(internal)函数类型的使用:
pragma solidity ^0.4.16; library ArrayUtils { // internal functions can be used in internal library functions because // they will be part of the same code context 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; } }
下面的代码显示外部(external)函数类型的使用:
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 { // Here goes the check that the reply comes from a trusted source requests[requestID].callback(response); } } contract OracleUser { Oracle constant oracle = Oracle(0x1234567); // known contract function buySomething() { oracle.query("USD", this.oracleResponse); } function oracleResponse(bytes response) public { require(msg.sender == address(oracle)); // Use the data } }
请订阅区块链技术查看。
咱们也推出了目前市面上最全的视频教程:深刻详解以太坊智能合约语言Solidity 目前咱们也在招募课程体验师,能够点击连接了解。
☛ 深刻浅出区块链 - 系统学习区块链,打造最好的区块链技术博客。
☛ 个人知识星球为各位解答区块链技术问题,欢迎加入讨论。
☛ 关注公众号“深刻浅出区块链技术”第一时间获取区块链技术信息。