可见性或权限控制(Visibility And Accessors)
可见性
- external 外部可见性
可以被其它合约或发起交易的方式调用
在合约内部调用要使用this.f() - public 公开可见性
public
类型的状态变量,会自动创建一个访问器 - internal 内部可见性
- private 私有可见性
| | 合约内部 | 继承合约 | 外部合约 | 发起交易
| ------------ | ------------ | ------------ | ------------
| external | Y | Y | Y | Y
| public | Y | Y | Y | N
| internal | Y | Y | N | N
| private | Y | N | N | N
函数默认是
public
状态变量默认的可见性是internal
访问函数(Getter Functions)
public
的状态变量,编译器会默认创建访问函数。
contract C{
uint public data = 10;
}
变量data为public,所以创建访问函数如下:
function data() view return (uint data)
外部可以使用C.data()访问它。
注意:在外部函数中的状态变量访问,只能通过this.data()的方式。
比如:
contract C{
uint public c = 10;
function accessInternal() internal returns (uint){
return c;
}
function accessExternal() external returns (uint){
return this.c();
}
}
注意:public的mapping默认访问参数是需要参数的,并不是之前说的访问函数都是无参的。
如下:
mapping (address => uint256) public balanceOf;
function balanceOf(address _owner) view returns (uint256 balance)
函数修改器(Function Modifiers)
http://www.tryblockchain.org/Solidity-FunctionModifiers-%E5%87%BD%E6%95%B0%E4%BF%AE%E6%94%B9%E5%99%A8.html
修改器(Modifiers)
可以用来轻易的改变一个函数的行为。比如用于在函数执行前检查某种前置条件。
-
修改器(Modifiers)
可以被继承 -
修改器(Modifiers)
可以被重写(override) -
修改器(Modifiers)
可以接收参数的 -
_
表示修改器(Modifiers)
修饰的函数体替换位置
pragma solidity ^0.4.0;
contract owned {
function owned() { owner = msg.sender; }
address owner;
// This contract only defines a modifier but does not use
// it - it will be used in derived contracts.
// The function body is inserted where the special symbol
// "_;" in the definition of a modifier appears.
// This means that if the owner calls this function, the
// function is executed and otherwise, an exception is
// thrown.
modifier onlyOwner {
if (msg.sender != owner)
throw;
_;
}
}
contract mortal is owned {
// This contract inherits the "onlyOwner"-modifier from
// "owned" and applies it to the "close"-function, which
// causes that calls to "close" only have an effect if
// they are made by the stored owner.
function close() onlyOwner {
selfdestruct(owner);
}
}
contract priced {
// Modifiers can receive arguments:
modifier costs(uint price) {
if (msg.value >= price) {
_;
}
}
}
contract Register is priced, owned {
mapping (address => bool) registeredAddresses;
uint price;
function Register(uint initialPrice) { price = initialPrice; }
// It is important to also provide the
// "payable" keyword here, otherwise the function will
// automatically reject all Ether sent to it.
function register() payable costs(price) {
registeredAddresses[msg.sender] = true;
}
function changePrice(uint _price) onlyOwner {
price = _price;
}
}
例子:使用修改器实现的一个防重复进入锁
pragma solidity ^0.4.0;
contract Mutex {
bool locked;
modifier noReentrancy() {
if (locked) throw;
locked = true;
_;
locked = false;
}
/// This function is protected by a mutex, which means that
/// reentrant calls from within msg.sender.call cannot call f again.
/// The `return 7` statement assigns 7 to the return value but still
/// executes the statement `locked = false` in the modifier.
function f() noReentrancy returns (uint) {
if (!msg.sender.call()) throw;
return 7;
}
}