错误处理:
处理方式:回退状态,不能存在中间状态,保证每个调用都是事务性的。
assert/require
assert:检查内部,会消耗掉gas
require:检查外部,不会消耗gas
require举例:
pragma solidity ^0.4.20;
contract Sharer{
function sendHalf(address addr) public payable returns (uint balance){
require(msg.value % 2 == 0);
return this.balance;
}
}
assert举例:
pragma solidity ^0.4.20;
contract Sharer{
function sendHalf(address addr) public payable returns (uint balance){
require(msg.value % 2 == 0);
uint balanceBeforeTranfer = this.balance;
addr.transfer(msg.value / 2 + 1); //逻辑有误
assert(this.balance == balanceBeforeTranfer - msg.value / 2);
return this.balance;
}
}
函数参数:
输入参数
输出参数(函数返回值)
命名参数(调用)
参数解构(可以用元组返回多个类型的值)
pragma solidity ^0.4.20;
contract Test{
function simpleInput(uint a,uint b) public constant returns(uint sum,uint mul){
sum = a + b;
mul = a * b;
}
function testSimpleInput() public constant returns (uint sum,uint mul){
(sum,mul) = simpleInput({a:1,b:3}); //命名参数,解构
}
function f() public constant returns(uint,bool,uint){
return(7,true,2);
}
function g()public{
var(x,y,z) = f(); //解构
(,y,z) = f();
(x,) = (1,2);
(x,z) = (z,x);
}
}
控制解构:
if,else,while,do,for,break,continue,return,?:
没有switch,goto。
可见性:
public/private/external/internal
默认可见性时public,会自动创建一个访问器。
private仅能在当前合约中访问。
external仅支持消息调用。
internal可以在当前合约和继承的合约中访问。
函数:
构造函数
视图函数(constant.view):修改状态变量/触发事件/创建新合约都不能视为视图函数。
纯函数(pure):既不会读取变量也不会修改变量。
回退函数:被动调用的函数。合约要想转移需要回退函数,在发送以太币的时候、匹配到对应函数的时候都会调用。
pragma solidity ^0.4.20;
contract Test{
uint internal data;
constructor(uint a) public{
data = a;
}
event EVENT(uint a);
function testView()public constant returns(uint){
//data = 1;
//emit EVENT(1);
return data;
}
function f()public pure returns(uint){
//this.balance;
return 1 * 2 + 3;
}
function ()public payable{
//回退函数
}
}
在回退函数中写大量代码容易导致gas不够