可见性修饰符
决定函数何时和被谁调用。
public :函数对外可见,可以在任何地方调用,不管是内部还是外部;
private :函数对外不可见,只能被合约内部调用;
external:函数对外可见,只能从合约外部调用;
internal :函数对外不可见,只能被合约内部调用或者被继承的合约调用;
注意点
不写默认就是public
状态修饰符
用来表示函数如何与区块链交互。
view :运行这个函数不会更改和保存任何数据;
pure :运行这个函数不仅不会往区块链写数据,甚至不从区块链读取数据;
constant: 和view的功能是一样的,在5.0版本后被废弃;
example
pragma solidity ^0.8.0;
contract Test{
uint256 public a1 = 100;
uint256 a2 = 256;
//为了明确语义,一般要加上view(constant两者完全相同)
//表示不会修改函数内的状态变量
function add() view returns(int){
return a1+a2;
}
function setValue(int num){
a1 = num;
}
function setValue1(int num) view{
a1 = num;
}
//因为pure不读也不写入链,因此带pure的函数一般只做纯逻辑的处理
function isEqual(int a, int b) public pure returns(bool) {
return a == b;
}
}
注意点
这两种在被合约外部调用的时候都不花费任何gas
但是它们在被内部其他函数调用的时候将会耗费gas。
自定义修饰符(modifiers)
如onlyowner、aboveLevel等自定义的modifiers,对于这些修饰符我们可以自定义其对函数的约束逻辑。
所有自定义的修饰符都需要在逻辑最后留下占位符 “_;”
//第一个自定义修饰器,要求只能够合约的拥有者才能够操作
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
//第二个自定义函数修饰器,要求消息发送者携带的value大于合约的vulue
modifier antherModifier() {
require(msg.value > address(this).value,"your balance is not enough");
_;
}
这些修饰符可以同时作用于一个函数定义上,如:
function test() external view onlyOwner anotherModifier { }
payable修饰符
可以接收以太的特殊函数修饰符
example_one
pragma solidity ^0.4.24;
contract test1 {
uint public num;
//如果构造函数中未指定payable关键字,那么创建合约时不允许转账
//如果指定了payable,则可以转账
constructor() public {
//构造函数
}
//任何函数,只要指定了payable关键字,这个合约就可以接受转账,调用时,也可以转0
function giveMoney() public payable {
}
}
example_two
contract OnlineStore {
function buySomething() external payable {
// 检查以确定0.001以太发送出去来运行函数:
require(msg.value == 0.001 ether);
// 如果为真,一些用来向函数调用者发送数字内容的逻辑
transferThing(msg.sender);
}
}
注意点
如果一个函数没标记为payable, 而你尝试利用上面的方法发送以太,函数将拒绝你的事务。