函数类型

  1. internal:仅供内部调用,在继承时类似protected,可被子类调用,机器码中通过jump实现,部署后无法被外部调用
  2. private:仅供内部调用,无法被子类调用,机器码中通过jump实现,部署后无法被外部调用
  3. public:可供内外部调用,同时在内部调用时会使用jump实现。
  4. external:为外部调用,正常情况下在solidity中无法被自身调用,但可以通过address(this).xxx或者低级调用来使用,但此时使用的是xxcall,可能会产生一次Internal Transaction。

特殊修饰符

  1. pure:禁止读取或修改任何EVM状态(包括gasleft、balance、address),即保证在相同的输入下,输出一定,而不依赖EVM的状态。
  2. view:表明函数不修改任何EVM状态(Storage、balance...),包括自身合约的状态以及其他任何合约的状态,但可以读取状态,这样的函数的结果一般可以通过EVM状态直接计算出来(除非与Transaction相关,msg/block/tx/gasleft),所以web3.js也提供不发送Transaction就能获取函数返回值的call方法
  3. payable:表示该函数可以接受value不为0的Trasaction,若没有该修饰符,当msg.value不为0时,会发生revert。

特殊函数

constructor

构造函数,实际上不包含在最终部署的合约代码中,而是在部署的那笔Transaction中执行。

同时,由于执行构造函数时合约尚未被真正部署,所以是无法调用自身函数的(也需要注意调用的外部合约是否会调用自身,这样也会导致transaction failed)。

但实际上在构造函数执行时,部署的合约的地址已经确定,可以正常地使用ADDRESS,也可以修改Storage、balance等。

在新版的solidity中(0.7.0起),constructor不能有private/public等可见性修饰符,但可以正常地使用payable。

receive

设计为接收eth(wei)的函数,当Transaction的data为空时,会调用这个函数。

在solidity中,该函数必须为payable,同时,该函数在solidity中不能接受参数、也无法返回数据,但这只是语言限制,实际上可以通过内联汇编绕过。

fallback