solidity :外部可见性 & modfier & fallback

https://solidity.readthedocs.io/en/develop/contracts.html#visibility-and-getters

  • 可见性参考:http://www.tryblockchain.org/Solidity-VisibilityandAccessors-可见性和访问控制器.html
  • Solidity中有两种函数调用方式
    • internal do not create an actual EVM call (also called a “message call”)

      • 合约内部的函数之间可以直接调用。比如在contract C中定义了两个函数g()f(uint),在g中可以直接return f(5)+g();
      • 这种函数调用在EVM中被解析为简单的jump,即需要的变量也好,代码也好,已经加载到memory中了;
    • external 会创建实际的EVM调用(消息调用)

      • 比如this.f(3); contractInstance.g();f(3)则不可以。此时是消息调用,不是jumpthis不可以使用在构造函数中,因为合约实例还没有被创建。

function状态变量 的四种类型可见性,其中函数默认是public,状态变量默认是internal

  • external:外部的

    • 可以由其他合约或者交易发起调用(只能通过external方式调用)
    • 不可以被内部调用,如f();,但是可以this.f();
    • 外部函数有时候在接收到大的数组数据时比较有效
  • public:公共的

    • 内部调用 或者 通过消息(即externalinternal两种调用方式)
    • 对于 public状态变量,会自动的生成getter函数。这个函数是外部external可见的。当在内部访问的时候,即不使用this,相当于状态变量。当外部访问的时候,如this.data(),则等价于函数。
      • 对于数组类型的public状态变量,则可以使用getter的作用只返回一个元素,而不是整个数组,从而节省gas。
  • internal:内部的

    • 只能内部访问,即从当前合约或者派生合约
    • 不用this
  • private:私有的

    • 只能在定义的合约中使用,不能在派生合约中使用
  • externalpublicexternal方式调用下的区别是:

    • public更昂贵,需要花费的gas要多一些,因为需要把参数都拷贝到memory中,而external可以直接使用calldata.

值得注意的是:区块链外部的人可以看到区块链上的所有东西。私有的private仅仅是防止其他合约访问和修改信息。对区块链外面的世界依然是完全可见的。

  • 外部可见性定义方式
    • 对于变量 变量类型 可见性 变量名;
    • 对于函数 function 函数名(形参类型 形参名)可见性 returns(返回值类型 返回变量名)
pragma solidity >=0.4.0 <0.7.0;

contract C {
    uint private data;

    function f(uint a) private pure returns(uint b) { return a + 1; }
    function setData(uint a) public { data = a; }
    function getData() public view returns(uint) { return data; }
    function compute(uint a, uint b) internal pure returns (uint) { return a + b; }
}

// This will not compile
contract D {
    function readData() public {
        C c = new C();
        uint local = c.f(7); // error: member `f` is not visible
        c.setData(3);
        local = c.getData();
        local = c.compute(3, 5); // error: member `compute` is not visible
    }
}

contract E is C {
    function g() public {
        C c = new C();
        uint val = compute(3, 5); // access to internal member (from derived to parent contract)
    }
}
  • modifier
    • 改变函数的行为
    • 在函数执行之前自动检查环境
    • 是合约中可以被继承的部分。可以被派生类的合约重载。
modifier 名称{
	require(
    相当于执行某个函数之前需要判断的一些条件,if()这种
    );
    _;   //使用这个modifier的函数在判断完上面的条件之后,就把函数插入到这里来执行。
}
function 函数名() modifier的名称,可见性 returns(){
...
}
  • fallback 函数:当接收到合约调用,没有其他的函数可以匹配的时候执行。相当于一个默认函数。可以使用payable,这个函数可以把发来交易中的ether存入合约。如果函数体中没有对ether做任何处理,那这笔ether将无法被提取。
    • 合约中唯一一个没有名字的函数
    • 没有参数,没有返回值。但是参数中可以包含mag.data,用来检索调用中提供的payload。
    • 必须是external的可见性

没有fallback函数的合约,在收到ether时,会作为创世交易(coinbase transaction)的接收方,或者作为selfdestruct(自毁)的目的地。

  • msg.data(uint):complete calldata

  • msg.sender(address):sender of the message (current call)

  • tx.origin(address):sender of the transaction (full call chain)

  • msg.value(uint):number of wei sent with the message

  • assert(bool condition):

    • invalidates the transaction if the condition is not met - to be used for internal errors.
  • require(bool condition):

    • reverts if the condition is not met - to be used for errors in inputs or external components.
  • require(bool condition, string message):

    • reverts if the condition is not met - to be used for errors in inputs or external components. Also provides an error message.
  • iterative_mapping使用方法参考:https://medium.com/rayonprotocol/creating-a-smart-contract-having-iterable-mapping-9b117a461115

  • soidity中的变量:http://liyuechun.org/2017/09/30/solidity-contract-0006/,http://liyuechun.org/2017/09/30/solidity-contract-0007/

你可能感兴趣的:(精通比特币学习笔记,编程语言)