库(Libraries)

库类似合约,实现仅在专门地址部署一次,使用EVM的DELEGATECALL的功能重复使用的目的。意思是当库函数被调用后,代码执行在被调用的合约的环境。例如,使用this调用合约,可以访问的调用合约的storage.孤立的库代码仅能访问变量,不能修改变量

pragma solidity ^0.4.16;

library Set {
struct Data {
mapping(uint => bool) flags;
} 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));
}
// In this contract, we can also directly access knownValues.flags, if we want.
}

如何使用库的memory类型和内部函数实现自定义类型,而无须使用外部方法调用

pragma solidity ^0.4.16;

library BigInt {
struct bigint {
uint[] limbs;
} function fromUint(uint x) internal pure returns (bigint r) {
r.limbs = new uint[](1);
r.limbs[0] = x;
} function add(bigint _a, bigint _b) internal pure returns (bigint r) {
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length));
uint carry = 0; for (uint i = 0; i < r.limbs.length; ++i) {
uint a = limb(_a, i);
uint b = limb(_b, i);
r.limbs[i] = a + b + carry; if (a + b < a || (a + b == uint(-1) && carry > 0))
carry = 1;
else
carry = 0;
} if (carry > 0) {
// too bad, we have to add a limb
uint[] memory newLimbs = new uint[](r.limbs.length + 1);
for (i = 0; i < r.limbs.length; ++i)
newLimbs[i] = r.limbs[i]; newLimbs[i] = carry;
r.limbs = newLimbs;
}
} function limb(bigint _a, uint _limb) internal pure returns (uint) {
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0;
} function max(uint a, uint b) private pure returns (uint) {
return a > b ? a : b;
}
} contract C {
using BigInt for BigInt.bigint; function f() public pure {
var x = BigInt.fromUint(7);
var y = BigInt.fromUint(uint(-1));
var z = x.add(y);
}
}

关键字Using For

using A for B 附加库函数A到类型B,类似python的self

using A for * 附加库函数A到所有类型

pragma solidity ^0.4.16;

library Set {
struct Data {
mapping(uint => bool) flags;
} function insert(Data storage self, uint value) public returns (bool) {
if (self.flags[value])
return false; // already there self.flags[value] = true;
return true;
} function remove(Data storage self, uint value) public returns (bool) {
if (!self.flags[value])
return false; // not there self.flags[value] = false;
return true;
} function contains(Data storage self, uint value) public view returns (bool) {
return self.flags[value];
}
} contract C {
using Set for Set.Data; // this is the crucial change
Set.Data knownValues; function register(uint value) public {
require(knownValues.insert(value));
}
}

使用另外方式扩展基本类型

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语言14的更多相关文章

  1. 用solidity语言开发代币智能合约

    智能合约开发是以太坊编程的核心之一,而代币是区块链应用的关键环节,下面我们来用solidity语言开发一个代币合约的实例,希望对大家有帮助. 以太坊的应用被称为去中心化应用(DApp),DApp的开发 ...

  2. 第一行代码:以太坊(2)-使用Solidity语言开发和测试智能合约

    智能合约是以太坊的核心之一,用户可以利用智能合约实现更灵活的代币以及其他DApp.不过在深入讲解如何开发智能合约之前,需要先介绍一下以太坊中用于开发智能合约的Solidity语言,以及相关的开发和测试 ...

  3. Solidity语言系列教程

    Solidity 是一门面向合约的.为实现智能合约而创建的高级编程语言.这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在 以太坊虚拟机(EVM) 上运行. ...

  4. solidity语言介绍以及开发环境准备

    solidity语言介绍以及开发环境准备   Solidity 是一门面向合约的.为实现智能合约而创建的高级编程语言.这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的 ...

  5. 用C++生成solidity语言描述的buchi自动机的初级经验

    我的项目rvtool(https://github.com/Zeraka/rvtool)中增加了生成solidity语言格式的监控器的模块. solidity特殊之处在于,它是运行在以太坊虚拟机环境中 ...

  6. Solidity语言基础 和 Etherum ERC20合约基础

    1. 类型只能从第一次赋值中推断出来,因此以下代码中的循环是无限的,  小. for (var i = 0; i < 2000; i++) { ... } --- Solidity Types ...

  7. solidity语言

    IDE:Atom 插件:autocomplete-solidity 代码自动补齐   linter-solium,linter-solidity代码检查错误   language-ethereum支持 ...

  8. solidity语言13

    函数过载 合约内允许定义同名函数,但是输入参数不一致 pragma solidity ^0.4.17; contract A { function f(uint _in) public pure re ...

  9. solidity语言12

    View Functions 函数声明为视图,将无权修改状态 pragma solidity ^0.4.16; contract C { function f(uint a, uint b) publ ...

随机推荐

  1. 【算法笔记】B1014 福尔摩斯的约会

    1014 福尔摩斯的约会 (20 分) 大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hy ...

  2. html的第一个程序

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. $_SERVER['SCRIPT_NAME']、$_SERVER['SCRIPT_FILENAME']及__FILE__不同

    $_SERVER['SCRIPT_NAME'].$_SERVER['SCRIPT_FILENAME']及__FILE__不同 在PHP中,有时需要知道脚本所处的位置,这时会用到$_SERVER['SC ...

  4. [转] docker save与docker export的区别

    [From]http://cnodejs.org/topic/59a2304f7aeedce818249eeb 很久没有写博客了,坟头草都长了老高了.写博客要靠惯性,一旦停下来时间长了,就很难再坚持下 ...

  5. javaScript 和 node.js 的一些文章收集

    这里收集了一些文章的链接,方便自己查询翻看,也避免把别人的成果复制过来再发布,节约时间. ThinkJS 3 正式版发布 我来回答饿了么大前端的问题(1) 一起理解 Virtual DOM 探讨Nod ...

  6. [转] Tomcat 禁用URL中的JSESSIONID

    [From] http://stackoverflow.com/questions/962729/is-it-possible-to-disable-jsessionid-in-tomcat-serv ...

  7. C++ GUI Qt4编程(05)-2.2GoToCell

    1. 使用Qt设计师创建GoToCell对话框. 2. gotocelldialog.cpp #include <QRegExp> #include "gotocelldialo ...

  8. Oracle RAC集群搭建(一)-ASM共享存储卷

    01, ASM共享存储卷 安装集群的话,必须要有共享磁盘,目的是为作裁决磁盘使用.还需要有数据文件的共享磁盘 02,规划 主机 裁决磁盘 数据 rac1        1G*1          20 ...

  9. Linux私房菜阅读笔记

    在线man:http://www.linux.com/linux-man-pages 计算机硬件五大单元: 1.输入 2.输出 3.控制单元 4.算数逻辑单元 5.内存   CPU种类 1.RISC( ...

  10. Ajax的XMLHttpRequest对象

    编写一个例子:从服务器取回一个Hello Ajax字符串. HTML: <input type="button" value="ajax提交" oncli ...