美文网首页
solidity系列教程<九>库(library)的使用

solidity系列教程<九>库(library)的使用

作者: addin_gao | 来源:发表于2019-04-18 11:01 被阅读0次

库与合约类似,它也部署在一个指定的地址上(仅被部署一次,当代码在不同的合约可反复使用)

因为库合约是一个独立的代码,它仅可以访问主调合约明确提供的状态变量,否则,没办法法去知道这些状态变量。

对比普通合约来说,库存在以下的限制(这些限制将来也可能在将来的版本被解除):

  • 无状态变量(state variables)。
  • 不能继承或被继承
  • 不能接收以太币
  • 不能销毁一个库

库有许多使用场景。两个主要的场景如下:

  • 如果有许多合约,它们有一些共同代码,则可以把共同代码部署成一个库。这将节省gas,因为gas也依赖于合约的规模。因此,可以把库想象成使用其合约的父合约。使用父合约(而非库)切分共同代码不会节省gas,因为在Solidity中,继承通过复制代码工作。
  • 库可用于给数据类型添加成员函数。(using for)

第一种使用库

pragma solidity ^0.4.16;

library Set {
  // 定义了一个结构体,保存主调函数的数据(本身并未实际存储的数据)。
  struct Data { mapping(uint => bool) flags; }

  // self是一个存储类型的引用(传入的会是一个引用,而不是拷贝的值),这是库函数的特点。
  // 参数名定为self 也是一个惯例,就像调用一个对象的方法一样.
  function insert(Data storage self, uint value)
      public
      returns (bool)
  {
      if (self.flags[value])
          return false; // 已存在
      self.flags[value] = true;
      return true;
  }

  function remove(Data storage self, uint value)
      public
      returns (bool)
  {
      if (!self.flags[value])
          return false; 
      self.flags[value] = false;
      return true;
  }

  function contains(Data storage self, uint value)
      public
      view
      returns (bool)
  {
      return self.flags[value];
  }
}

contract C {
    Set.Data knownValues;

    function register(uint value) public {
        // 库函数不需要实例化就可以调用,因为实例就是当前的合约
        require(Set.insert(knownValues, value));
    }
    // 在这个合约中,如果需要的话可以直接访问knownValues.flags,
}

using for:
指令using A for B;用来把库函数(从库A)关联到类型B。这些函数将会把调用函数的实例作为第一个参数。语法类似,python中的self变量一样。例如:A库有函数 add(B b1, B b2),则使用Using A for B指令后,如果有B b1就可以使用b1.add(b2)。

using A for * 表示库A中的函数可以关联到任意的类型上。

使用Using for的方式来对基本类型(elementary types)进行扩展:

pragma solidity ^0.4.16;

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 {
        // 进行库调用
        uint index = data.indexOf(_old);
        if (index == uint(-1))
            data.push(_new);
        else
            data[index] = _new;
    }
}

相关文章

网友评论

      本文标题:solidity系列教程<九>库(library)的使用

      本文链接:https://www.haomeiwen.com/subject/fiqpiftx.html