• solidity-library


    library

    1)直接使用
    使用库合约的合约,可以将库合约视为隐式的父合约(base contracts),当然它们不会显式的出现在继承关系中。意思就是不用写is来继承,直接可以在合约中使用:

    library Set {
      struct Data { mapping(uint => bool) flags; }
    }
    
    contract C {
        Set.Data knownValues;
    }


    但调用库函数的方式非常类似,如库L有函数f(),使用L.f()即可访问。此外,internal的库函数对所有合约可见,如果把库想像成一个父合约就能说得通了。当然调用内部函数使用的是internal的调用惯例,这意味着所有internal类型可以传进去,memory类型则通过引用传递,而不是拷贝的方式。

    library Set {
      // We define a new struct datatype that will be used to
      // hold its data in the calling contract.
      struct Data { mapping(uint => bool) flags; }
    
      // Note that the first parameter is of type "storage
      // reference" and thus only its storage address and not
      // its contents is passed as part of the call. (意思是说这是个引用传递) This is a
      // special feature of library functions.  It is idiomatic(就是惯例都把第一个变量命名为self,当然你也可以命名为其他的)
      // to call the first parameter 'self', if the function can
      // be seen as a method of that object.
      function insert(Data storage self, uint value)
          returns (bool)
      {
          if (self.flags[value])
              return false; // already there
          self.flags[value] = true;
          return true;
      }
    
      function remove(Data storage self, uint value)
          returns (bool)
      {
          if (!self.flags[value])
              return false; // not there
          self.flags[value] = false;
          return true;
      }
    
      function contains(Data storage self, uint value)
          returns (bool)
      {
          return self.flags[value];
      }
    }
    
    
    contract C {
        Set.Data knownValues;
    
        function register(uint value) {
            // The library functions can be called without a
            // specific instance of the library, since the
            // "instance" will be the current contract.
            if (!Set.insert(knownValues, value))
                throw;
        }
        // In this contract, we can also directly access knownValues.flags, if we want.
    }


    上面的例子中:
        •    Library定义了一个数据结构体struct Data,用来在调用的合约中使用(库本身并未实际存储的数据)。如果函数需要操作数据,这个数据一般是通过库函数的第一个参数传入(Data storage self),按惯例会把参数名定为self。
        •    另外一个需要留意的是上例中self的类型是storage,那么意味着传入的会是一个引用,而不是拷贝的值,那么修改它的值,会同步影响到其它地方,俗称引用传递,非值传递。
        •    库函数的使用不需要实例化,c.register函数中可以看出是直接使用Set.insert。但实际上当前的这个合约本身就是它的一个实例。
        •    这个例子中,c可以直接访问knownValues。虽然这个值主要是被库函数使用的

    对比普通合约来说,库的限制:
        •    无状态变量(state variables)。
        •    不能继承或被继承
        •    不能接收ether。


    2)通过附着库(Using for)来使用库
    指令using A for B;用来附着库里定义的函数(从库A)到任意类型B。这些函数将会默认接收调用函数对象的实例作为第一个参数。语法类似,python中的self变量一样。
    using A for *的效果是,库A中的函数被附着在做任意的类型上。
    在这两种情形中,所有函数,即使那些第一个参数的类型与调用函数的对象类型不匹配的,也被附着上了。类型检查是在函数被真正调用时,函数重载检查也会执行。
    using A for B;指令仅在当前的作用域有效,且暂时仅仅支持当前的合约这个作用域,后续也非常有可能解除这个限制,允许作用到全局范围。如果能作用到全局范围,通过引入一些模块(module),数据类型将能通过库函数扩展功能,而不需要每个地方都得写一遍类似的代码了。
    上面的例子就改成了:

    contract C {
        using Set for Set.Data; // this is the crucial change
        Set.Data knownValues;
    
        function register(uint value) {
            // Here, all variables of type Set.Data have
            // corresponding member functions.
            // The following function call is identical to
            // Set.insert(knownValues, value)
            if (!knownValues.insert(value))
                throw;
        }
    }


    //其实就是本来要访问的话的语句是Set.insert(knownValues, value),现在是knownValues.insert(value),即将库中的函数都附着在了结构体struct Data上,因为之前库函数的第一个参数self的声明其实也是这个结构体(Data),附着后调用时就可以省略掉第一个参数了,因为它默认接收调用函数对象的实例作为第一个参数。就算库中没有结构体,那么附着的一定是函数的第一个参数声明的那个self的类型,如string、uint[]等,如下面的例子:

    library Search {
        function indexOf(uint[] storage self, uint value)
    
    contract C {
        using Search for uint[];
        uint[] data;
    //这样调用就可以变成:
    data.indexOf(value);
  • 相关阅读:
    android如何播放资源文件夹raw中的视频
    android studio添加三方jar包
    golang自动导入postgresql脚本
    xorm使用pgsql的例子
    python安装psycopg2
    制作u盘启动的工具
    codis须知
    redis3.0自带集群配置
    keepalive配置db层的ha的一些注意点
    phalcon安装笔记
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/9590541.html
Copyright © 2020-2023  润新知