solidity中函数的形式:
function <function name> (<parameter types>) {internal|external|public|private} [pure|view|payable] [returns (<return types>)]
function
:声明函数时的固定用法,想写函数,就要以function关键字开头。<function name>
:函数名(<parameter types>)
:函数的参数,也就是要输入到函数的变量类型和名字。{internal|external|public|private}
:函数可见性说明符,一共4种。没标明函数类型的,默认internal
。public
: 内部外部均可见。(也可用于修饰状态变量,public变量会自动生成getter
函数,用于查询数值).private
: 只能从本合约内部访问,继承的合约也不能用(也可用于修饰状态变量)。external
: 只能从合约外部访问(但是可以用this.f()
来调用,f
是函数名)internal
: 只能从合约内部访问,继承的合约可以用(也可用于修饰状态变量)。
[pure|view|payable]
:决定函数权限/功能的关键字。payable
(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入ETH
。pure
和view
的介绍见下一节。[returns ()]
:函数返回的变量类型和名称。
到底什么是Pure
和View
?
pure
跟view
关键字的函数是不改/写链上状态的,因此用户直接调用他们是不需要付gas的(合约中非pure
/view
函数调用它们则会改写链上状态,需要付gas)。
包含
pure
关键字的函数,不能读取也不能写入存储在链上的状态变量。包含
view
关键字的函数,能读取但也不能写入状态变量。不写
pure
也不写view
,函数既可以读取也可以写入状态变量。
在以太坊中,以下语句被视为修改链上状态:
写入状态变量。
释放事件。
创建其他合同。
使用selfdestruct.
通过调用发送以太币。
调用任何未标记view或pure的函数。
使用低级调用(low-level calls)。
使用包含某些操作码的内联汇编。
以下被认为是从状态中读取:
- 读取状态变量。
- 访问
this.balance
或者<address>.balance
。- 访问
block
,tx
,msg
中任意成员 (除msg.sig
和msg.data
之外)。- 调用任何未标记为
pure
的函数。- 使用包含某些操作码的内联汇编。
代码
1. pure v.s view
// SPDX-License-Identifier: MIT
//声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
pragma solidity ^0.8.4;
contract HelloWeb3{
uint256 public number = 5;
//定义add函数 external是可以从合约外部调用此函数
function add() external{
number = number + 1;
}
//pure 不能读取也不能写入存储在链上的状态变量number
//那pure函数能做些什么?举个例子,你可以给函数传递一个参数 _number,然后让他返回 _number+1。
function addPure(uint256 _number) external pure returns(uint256 new_number){
new_number = _number+1;
}
//view 能读取,但不能够改写状态变量number
//可以稍微改写下方程,让他不改写number,而是返回一个新的变量。
function addView() external view returns(uint256 new_number) {
new_number = number + 1;
}
}
2. internal v.s. external
// SPDX-License-Identifier: MIT
//声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
pragma solidity ^0.8.4;
contract Web3{
uint256 public number = 5;
// internal: 内部
function minus() internal {
number = number - 1;
}
// 合约内的函数可以调用内部函数
function minusCall() external {
minus();
}
}
3. payable
// SPDX-License-Identifier: MIT
//声明solidity版本 这行代码意思是源文件将不允许小于 0.8.4 版本或大于等于 0.9.0 版本的编译器编译
pragma solidity ^0.8.4;
contract HelloWeb3{
// payable: 递钱,能给合约支付eth的函数
function minusPayable() external payable returns(uint256 balance) {
balance = address(this).balance;
}
}
this关键字可以让我们引用合约地址
我们可以在返回的信息中看到,合约的余额是1 ETH。
Example:
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。