solidity语言14

it2022-05-05  110

solidity语言14

库(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; } } posted on 2018-03-01 11:37 北京涛子 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/liujitao79/p/8487639.html


最新回复(0)