Solidity语言的函数非常灵活,可以进行各种复杂操作, 函数接受类型化的参数作为输入, 也可以返回任意数量的值作为输出。
function <function name>(<parameter types>) {internal|external|public|private} [pure|view|payable] [returns (<return types>)]
-
function:声明函数时的固定用法。要编写函数,就需要以 function 关键字开头。
-
:函数名。
-
():圆括号内写入函数的参数,即输入到函数的变量类型和名称。
-
{internal|external|public|private}:函数可见性说明符,共有4种。
-
public:内部和外部均可见。
-
private:只能从本合约内部访问,继承的合约也不能使用。
-
external:只能从合约外部访问(但内部可以通过 this.f() 来调用,f是函数名)。
-
internal: 只能从合约内部访问,继承的合约可以用。 注意 1:合约中定义的函数需要明确指定可见性,它们没有默认值。 注意 2:public|private|internal 也可用于修饰状态变量。public变量会自动生成同名的函数,用于查询数值。未标明可见性类型的状态变量,默认为internal。
-
[pure|view|payable]:决定函数权限/功能的关键字。payable(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入 ETH。
-
[returns ()]:函数返回的变量类型和名称。
-
view: 不修改状态。以下操作被视作修改状态
- 修改状态变量。
- 产生事件。
- 创建其它合约。
- 使用 selfdestruct。
- 通过调用发送以太币。
- 调用任何没有标记为 view 或者 pure 的函数。
- 使用低级调用。
- 使用包含特定操作码的内联汇编。
-
pure: 不读取或修改状态。以下为被视作读取状态
- 读取状态变量。
- 访问 address(this).balance 或者 .balance。
- 访问 block, tx, msg 中任意成员 (除 msg.sig 和 msg.data 之外)。
- 调用任何未标记为 pure 的函数。
- 使用包含某些操作码的内联汇编。
每个引用类型都有一个额外的属性,即 "数据位置", 关于它的存储位置。有三个数据位置。 memory, storage 和 calldata。引用类型包括结构、数组和映射。值类型的变量被使用时,会得到一个独立的副本。
- memory: 其寿命限于外部函数调用, 数据内容可修改。
- storage: 存储状态变量的位置,其寿命限于合约的寿命。函数里的参数和临时变量一般用memory
- calldata 包含函数参数的特殊数据位置,数据不可修改。使用calldata可以避免复制, 也可以确保数据不能被修改。
-
在 storage 和 memory 之间的分配(或从 calldata 中分配) 总是创建一个独立的拷贝。
-
从 memory 到 memory 的赋值只创建引用。 这意味着对一个内存变量的改变在所有其他引用相同数据的内存变量中也是可见的。
-
从 storage 到 local 存储变量的赋值也只赋值一个引用。
-
所有其他对 storage 的赋值总是拷贝的。 这种情况的例子是对状态变量或存储结构类型的局部变量成员的赋值, 即使局部变量本身也是一个引用。
全局变量是全局范围工作的变量,都是solidity预留关键字。他们可以在函数内不声明直接使用 常见的全局变量有:
时间单位
1 == 1 seconds
1 minutes == 60 seconds
1 hours == 60 minutes
1 days == 24 hours
1 weeks == 7 days
以太坊单位
1 wei == 1
1 gwei == 1e9
1 ether == 1e18