知乎专栏 | 多维度架构 |
Solidity对函数和状态变量提供了四种可见性。分别是external,public,internal,private。其中函数默认是public。状态变量默认的可见性是internal。
internal - 状态变量默认为internal类型,函数只能通过内部访问(当前合约或者继承的合约),可在当前合约或继承合约中调用。类似于Java的protected public - public标识的函数是合约接口的一部分。可以通过内部,或者消息来进行调用。与Java的public含义一致。 external - external标识的函数是合约接口的一部分。函数只能通过外部的方式调用。外部函数在接收大的数组时更有效。Java中无与此对应的关键字。 private - 只能在当前合约内访问,在继承合约中都不可访问。与Java中的private含义一致。 payable :可支付的函数修饰符,没有该修饰符无法接受转账操作。
assert(bool condition):不满足条件,将抛出异常
require(bool condition):不满足条件,将抛出异常
revert() 抛出异常
if(msg.sender != owner) { revert(); } assert(msg.sender == owner); require(msg.sender == owner);
接口是抽象的合约,接口中不能实现方法。
接口:
不能继承其他合约或接口
不能定义构造方法
不能定义变量
不能定义结构体
不能定义枚举
pragma solidity ^0.4.11; interface Token { function transfer(address recipient, uint amount) public; }
定义 library
pragma solidity ^0.4.25; // This is the same code as before, just without comments library Set { struct Data { mapping(uint => bool) flags; } function insert(Data storage self, uint value) public returns (bool) { if (self.flags[value]) return false; // already there self.flags[value] = true; return true; } function remove(Data storage self, uint value) public returns (bool) { if (!self.flags[value]) return false; // not there self.flags[value] = false; return true; } function contains(Data storage self, uint value) public view returns (bool) { return self.flags[value]; } }
调用库中的函数
contract C { using Set for Set.Data; // this is the crucial change Set.Data knownValues; function register(uint value) public { // Here, all variables of type Set.Data have // corresponding member functions. // The following function call is identical to // `Set.insert(knownValues, value)` require(knownValues.insert(value)); } }
pragma solidity ^0.4.25; library Search { function indexOf(uint[] storage self, uint value) public view returns (uint) { for (uint i = 0; i < self.length; i++) if (self[i] == value) return i; return uint(-1); } } contract C { using Search for uint[]; uint[] data; function append(uint value) public { data.push(value); } function replace(uint _old, uint _new) public { // This performs the library function call uint index = data.indexOf(_old); if (index == uint(-1)) data.push(_new); else data[index] = _new; } }