# 【易错概念】以太坊Solidity函数的external/internal，public/private，view/pure/payable区别

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

`function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]`

```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 {
requests[requestID].callback(response);
}
}

contract OracleUser {
Oracle constant oracle = Oracle(0x1234567); // 已知的合约
oracle.query("USD", this.oracleResponse);
}
function oracleResponse(bytes response) public {
// 使用数据
}
}```

#### 2. 函数可见性说明符：public，private，external，internal

• `public`：内部、外部均可见（参考为存储/状态变量创建 getter 函数
• `private`：仅在当前合约内可见
• `external`：仅在外部可见（仅可修饰函数）——就是说，仅可用于消息调用（即使在合约内调用，也只能通过 `this.func` 的方式）
• `internal`：仅在内部可见（也就是在当前 Solidity 源代码文件内均可见，不仅限于当前合约内，译者注）

```function myFunction() <visibility specifier> returns (bool) {
return true;
}```

#### 3. 函数修改器

pure 修饰函数时：不允许修改或访问状态——但目前并不是强制的。 view 修饰函数时：不允许修改状态——但目前不是强制的。 payable 修饰函数时：允许从调用中接收 以太币Ether 。 constant 修饰状态变量时：不允许赋值（除初始化以外），不会占据 存储插槽storage slot 。 constant 修饰函数时：与 view 等价。 anonymous 修饰事件时：不把事件签名作为 topic 存储。 indexed 修饰事件时：将参数作为 topic 存储。

Solidity中文帮助文档

0 条评论

• ### 【易错概念】Solidity语法的合约/抽象合约/接口/库的定义

以太坊智能合约语言Solitidy是一种面向对象的语言，本文清楚合约定义，以及派生的抽象合约，接口，库的定义。

• ### 第十二课 SOLIDITY语法难点解析及故障排查

（1）推荐编辑器 目前尝试 Solidity 编程的最好的方式是使用 Remix （需要时间加载，请耐心等待）。Remix 是一个基于 Web 的 IDE，它...

• ### 链安科技：智能合约call、delegatecall底层函数使用需谨慎

2018年5月11日ATN Token遭受恶意攻击(详见：https://atn.io/resource/aareport.pdf)，攻击者利用DSAuth库与...

• ### Windows客户端C/C++编程规范“建议”——函数

等级：【要求】 说明：每个函数的代码行数控制应该控制在80行以内。如果超过这个限制函数内部逻辑一般可以拆分。如果试图超过这个标准，请列出理由。但理由不包含如下...

• ### Unity基础系列（三）——数学表面（数字雕刻）

在完成前面的教程之后，我们有一个基于线条的视图，并在游戏模式下显示一个正弦波动画。当然还可以通过修改代码来显示其他数学函数。甚至可以在Unity编辑器处于播放模...

• ### 说说Python中闭包是什么？

答：可以将闭包理解为一种特殊的函数，这种函数由两个函数的嵌套组成，外函数和内函数。在一个外函数中定义了一个内函数，内函数里运用了外函数的临时变量，并且外函数的返...

• ### JS 计时器参数剖析与真题

HTML5学堂-码匠：计时器的第一个参数，包含几种不同的书写方法，可以是函数名，匿名函数，JS代码字符串，还有一些面试题当中会出现“函数调用”的书写方式。 那么...

• ### 深入解析golang编程中函数的用法

函数是一组一起执行任务的语句。每Go程序具有至少一个函数，它一般是main()，以及所有的最琐碎程序可以定义附加函数。 你可以将代码放到独立的功能。如何划分代码...

• ### 深入理解JavaScript中的函数

函数于软件开发者而言并不是什么奇幻世界。如果你的日常活动涉及到编码，哪怕是一点点，那么在一天结束的时候，你一定创建/修改了一个或多个函数。