家用比特币矿机:solidity与library的之间关系与应用

  solidity与Libraries(库)

  solidity是在以太坊网络和任何支持evm(以太坊虚拟机)的区块链上实现智能合约的高级编程语言之一。它的javascript语法和C语言风格的数据类型使它成为生态系统中最受欢迎和支持的语言。

  由于区块链的不变性,开发没有漏洞的智能合约非常重要。因此,对于以太坊智能合约的开发,开发人员应该始终尝试重用和依赖已经被许多开发人员审查、测试和使用过的代码,例如使用solidity库。

  在solidity中,库类似于合约,它们实现操作逻辑,并且可以部署一次以供不受限制数量的其他智能合约使用,而无需一次又一次地部署相同的逻辑。这有利于节省部署所需的gas费用。然而,如果多个合约依赖于同一段代码的话,那么如果该段代码存在漏洞,则可能会产生不良后果。因此,这是非常关键的调用,您应该非常谨慎地选择在智能合约中使用的库。库的好处不仅限于可重用性,它们还可以在一定程度上提高代码的可维护性、可读性甚至可升级性。

  在solidity中使用库

  库就像合约,我们使用library关键字来创建它们。但是库没有存储空间,不能保存任何以太坊,也不能继承或被继承。还有两种不同类型的库,具有外部功能的库称为链接库,它们应该首先部署,并且它们的地址应该通过部署过程添加到合约的bytecode中。只有内部函数的库称为嵌入式库。它们与合约一起部署,因此它们的bytecode成为合约bytecode的一部分,也可以通过jump命令访问。

  下面是一个简单的例子的safemath库,它有一个函数来添加两个uint256类型的数字,并防止可能的溢出错误。

  pragma solidity >=0.4.25 < 0.6.0;

  library SafeMath {

  function add(uint256 a, uint256 b) public pure returns (uint256){

  uint256 c=a + b;

  require(c >=a, "SafeMath: addition overflow");

  return c;

  }

  }

  要使用该库,我们首先使用指令将uint256类型附加到该库

  using SafeMath for uint256

  然后,uint256类型的任何变量都可以使用一个特殊的delegatecall调用函数add(),其中发送方和值不会更改,只是从父作用域传播到子作用域,而且存储仍然引用调用协定。

  uint256 currentBalance;

  function pay(uint256 amount) public {

  require(amount > 0, "amount is not bigger than zero");

  uint256 currentBalance =10;

  currentBalance =currentBalance.add(amount);

  }

  如前所述,库是没有存储空间,但是它们可以修改链接智能合约的存储空间,方法是将关键字存储空间添加到函数的第一个参数中,并使用struct将状态变量封装在库中,如safemath库的修改实现所示。我们将在地址数组库的实现中使用它。

  pragma solidity >=0.4.25 < 0.6.0;

  library SafeMath {

  struct Balance { uint256 _balance; }

  function add(Num storage self, uint256 amount) public {

  uint256 newBalance=self._ balance + amount;

  require(newBalance >=self._ balance, "addition overflow");

  self._ balance=newBalance;

  }

  }

  为什么需要一个地址数组?

  address是Solidity中的一种特殊数据类型,具有20个字节的值,并提供诸如transfer和balance之类的内置函数。 由于每个帐户和智能合约都通过唯一的地址表示,因此几乎每个智能合约项目都需要使用地址。

  简单地迭代一个完整的映射是不可能的,因此在许多情况下,开发人员必须将地址保存在数组中,特别是当涉及到在事务数据中不能给出地址的合约之间的链上交互时。最近我们在一个项目中工作,我们需要存储和管理一个数组中链上投资者的地址。在没有找到任何可用的公共库之后,我们实现了自己的库来管理地址数组。

  示例实现

  pragma solidity >=0.4.25 <0.6.0;

  library AddrArrayLib {

  using AddrArrayLib for Addresses;

  struct Addresses {

  address[] _items;

  }

  function pushAddress(Addresses storage self, address element) internal {

  if (!exists(self, element)) {

  self._items.push(element);

  }

  }

  function removeAddress(Addresses storage self, address element) internal returns (bool) {

  for (uint i=0; i < self.size(); i++) {

  if (self._items[i]==element) {

  self._items[i]=self._items[self.size() - 1];

  self._items.pop();

  return true;

  }

  }

  return false;

  }

  function getAddressAtIndex(Addresses storage self, uint256 index) internal view returns (address) {

  require(index < size(self), "the index is out of bounds");

  return self._items[index];

  }

  function size(Addresses storage self) internal view returns (uint256) {

  return self._items.length;

  }

  function exists(Addresses storage self, address element) internal view returns (bool) {

  for (uint i=0; i < self.size(); i++) {

  if (self._items[i]==element) {

  return true;

  }

  }

  return false;

  }

  function getAllAddresses(Addresses storage self) internal view returns(address[] memory) {

  return self._items;

  }

  }

  在上面的库代码中,我们有addresses结构,它包含address类型的数组和管理数组通常需要的函数,例如:

  · pushAddress:仅在地址不存在时将其添加到列表中。不允许使用重复地址,因为这会使数组更大,操作更复杂并增加使用gas。因此,我们假定对合同代码中的此类地址进行简单的特殊处理会更有效。

  · removeAddress:从列表中删除地址,如果地址已删除,则返回true。如果该地址不存在,则该函数将返回false。该方法将找到该元素,将其与最后一个元素交换,然后将其删除。

  · exists:如果数组中存在地址,返回true。

  · size:返回数组的大小。

  · getAddressAtIndex:获取给定索引处的地址。

  在所有函数中,我们使用关键字作为存储传递addresses参数,因此evm从智能合约的存储中通过引用传递它,而不是在内存中创建它的副本。

  现在我们将创建一个使用这个库来管理用户地址的示例合约,用户可以创建一个代币。

  pragma solidity >=0.4.25 < 0.6.0;

  import 'https://www.qukuaiwang.com.cn/node_modules/openzeppelin solidity/contracts/ownership/Ownable.sol';

  import 'https://www.qukuaiwang.com.cn/node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol';

  import 'https://www.qukuaiwang.com.cn/news/AddrArrayLib.sol';

  contract TokenContract is Ownable {

  using AddrArrayLib for AddrArrayLib.Addresses;

  using SafeMath for uint256;

  // List of trusted addresses which can mint tokens

  AddrArrayLib.Addresses trustedMinters;

  uint256 public totalSupply;

  mapping (address=> uint256) balances;

  constructor () public {

  totalSupply=100;

  balances[msg.sender]=100;

  }

  function addMinter(address minter) public onlyOwner() {

  trustedMinters.pushAddress(minter);

  }

  function removeMinter(address minter) public onlyOwner() {

  trustedMinters.removeAddress(minter);

  }

  function mintToken(address to, uint256 amount) external {

  require(trustedMinters.exists(msg.sender), 'The sender address is not registered as a Minter');

  totalSupply=totalSupply.add(amount);

  balances[to]=balances[to]. add(amount);

  }

  }

  在这个合约中,我们使用了两个嵌入式库,第一个是基于openzeppelin实现的嵌入式safemath库,它提供了添加的逻辑,但不会直接更改合约的状态,第二个是我们之前定义并通过其.sol文件导入的addrarraylib库。

  我们创建结构类型为AddrArrayLib.Addresses的私有变量,该私有变量表示合约的状态变量并存储地址。之后,我们有一个构造函数和三个合约函数:

  · addMinter函数接收新的Minter的地址,并调用trustMinters.pushAddress函数,该函数从存储中传入结构实例。

  · removeMinter函数。

  · mintToken它通过调用trustMinters.exists(msg.sender)来检查msg.sender是否存在于受信任的造币者数组中,并在成功验证之后创建该令牌。

  包含库,TokenContract和测试说明的存储库可在此链接下的Github上找到。https://github.com/51nodes/address-library-sample

  总结与未来工作

  在本文中,我们简要地解释了库,为什么使用它们以及如何使用它们。此外,我们还介绍了一个用于管理数组中地址的库的实现,我们认为这个库是智能合约经常需要的构建块。

  今后的工作重点是测试、改进现有功能和实现新功能。此外,我们还将分析gas成本,并将该库的链接版本与嵌入式版本进行比较。最后经过许多有经验的开发人员的审查,这个库将被部署在以太坊区块链上,并可用于新的项目。

文章内容系本站作者个人观点,不代表本站对其观点赞同或支持,文章的版权归该作者所有。如需转载,请注明文章来源。本文地址:http://www.cis.net.cn/kejikuaixun/43325.html
留言与评论(共有 条评论)
验证码:

最新文章

solidity与library的之间关系与应用

科技快讯
solidity与Libraries(库)solidity是在以太坊网络和任何支持evm(以太坊虚拟机)的区块链上实现智能合约的高级编程语言之一。它的javascript语法和C语言风格的数据类型使它成为生态系统中最受欢迎和支持

比特币宇航员彼得?蒂尔用加密登月的方式来推动市场

科技快讯
据报道,投资者彼得?蒂尔在比特币上押下了孤注一掷的大DU注。主流财经媒体报道,他的风险投资基金通过去年的1000个百分点的收益购买和持有数字资产,使分散的货币成为他公司最有价值的投资之一。彼得?蒂尔的登月DU注《华尔街日报》报道称,由彼得?蒂尔联合创立的风险投资公司Founders基金已经积累了数亿美元的不稳

澳大利亚电影点播发行商推出加密货币以奖励电影爱好者

科技快讯
澳大利亚Demand电影公司推出了一种新的虚拟货币,以奖励那些推广和观看电影预告片的用户。在该公司于下周二在德国上市之前,Demand电影公司将正式推出Screencreds加密货币。此新数字硬币是数字货币和区块链技术如何在电影业掀起波澜的最新

深度观察:区块链如何解决数字时代版权保护的“痛点”

科技快讯
党的十九大报告指出,要“倡导创新文化,强化知识产权创造、保护、运用”,确立了新时代包括版权在内的知识产权工作的总基调,为新时代版权工作指明了方向。《“十三五”国家知识产权保护和运用规划》中首次将知识产权规划列入国家重点专项规划。伴随产业升级,中国内容产业迎来黄金发展时期。然而,内容产业的迅速繁荣也伴随着侵权问题

区块链风险在哪里(区块链存在哪些风险)

科技快讯
据新华社消息,6月28日互联网法院对一起侵害作品信息网络传播权纠纷案进行了公开宣判,法院支持了原告采用作为存证方式并认定了对应的侵权事实。这是中国法院首次对采用存证的电子数据的法律效力予以确认。本案特别之处在于,原告

区块链双重支付指南:比特币如何解决独特的数字货币之谜

科技快讯
双重支付的问题:比特币是如何解决的?数字货币的概念已经存在很长一段时间了,它并不是10年前比特币第一次出现的时候产生的。然而,我们以前所有的尝试都失败了,原因很简单——双重支付。什么是双重支付?名称几乎完全说明了这一点,而双重支付则是两次使用相同金钱的行为。这是一个特定于加密的问题,它不会影响传统的物理货币。一旦

比特币核心开发者发布链上安全存储的金库样品

科技快讯
比特币长期开发者布莱恩·毕晓普(BryanBishop)说:“人们不擅长保证他们的私钥安全,因此从更好地编写软件、以及更好地保护[比特币]的角度来说,这是一场胜利。”CoinDesk此前报道,比特币的金库计划开始于2016年。这个计划最初是需要比特币核心开发者,通过他们从未实施过的硬分叉来完成。但现在,毕晓普在GitHub上推出的是一个无分叉的

Rate3 (电商币)为全球支付和电子商务网络提供全力支持

科技快讯
当今社会中,互联网与金融基础设施之间的联系密不可分。然而,为了确保金融交易的完整性和安全性,金融机构在某种程度上反而阻碍了金融基础设施的开拓与发展。由于进入市场的门槛较低,消费者并不相信银行具备自我监督的运作系统。与此同时,银行也不会通过单个实体来运营网络。因此,分散性制度更

使用GETH实现系统后端搭建

科技快讯
我正在创建一系列非常容易理解的文章,这些文章既解释了我所做的事情,也让我重写从旧的混乱黑客到希望更清洁版本的所有内容。使测试环境成为可能的单个主要组件是构建在geth源库中的模拟后端。模拟的后端是一个geth-