http://www.7klian.com

OpenZeppelin 7个最常利用的合约

    struct Role {
我们许多时候需要这样做,因此这个模式在以太坊智能合约开拓中很是风行。
Tokens (代币或通证)
        return c;
library SafeMath {
    }
    }
[4] ERC20代币: https://learnblockchain.cn/docs/eips/eip-20.html
    }
        require(isOwner(), “Ownable: caller is not the owner”);
        uint256 newItemId = _tokenIds.current();
library SafeCast {
    }
    }
    return 99;
        _;
4. 安详范例转换库:SafeCast
    constructor () internal {
    return _a.toUint8();
        return c;
        uint256 c = a + b;
2. 利用 Roles 举办脚色节制

OpenZeppelin的智能合约代码库[1]是开拓者的宝库,OpenZeppelin代码库包括了颠末社区审查的ERC代币尺度、安详协议以及许多的帮助东西库,这些代码可以辅佐开拓者专注业务逻辑的,而无需从头发现轮子。
            _minters.add(minters[i]);
基于OpenZeppelin开拓合约,即可以提高代码的安详性,又可以提高开拓效率,文本罗列了最应该添加到我们项目标 7个OpenZeppelin合约。
            _burners.add(burners[i]);
    }
}
    }
        require(value < 2**32, “SafeCast: value doesn\’t fit in 32 bits”);
pragma solidity ^0.5.5;
        require(newOwner != address(0), “Ownable: new owner is the zero address”);
    function renounceOwnership() public onlyOwner {
contract GameItem is ERC721Full {
OpenZeppelin的ERC20举办了尺度的基本实现,,ERC20Detailed 合约包括了特另外选项:譬喻代币名称、代币代号以及小数点位数。
会见节制合约
import “@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol”;
下面的代码展示了如何利用isContract()函数:
        uint256 c = a – b;
}
        require(value < 2**16, “SafeCast: value doesn\’t fit in 16 bits”);
        require(c >= a, “SafeMath: addition overflow”);
  }
        return uint128(value);
        emit OwnershipTransferred(address(0), msgSender);
        return _addr.isContract();
        return role.bearer[account];
留意在结构函数中如何配置合约的owner账号。当Ownable的子合约(即担任Ownable的合约)初始化时,陈设的账号就会配置为_owner。
有时候在Solidity合约中需要相识一个地点是普通钱包地点照旧合约地点。OpenZeppelin的Address库提供了一个要领isContract()可以帮我们办理这个问题。
    }
        for (uint256 i = 0; i < burners.length; ++i) {
import “@openzeppelin/contracts/utils/Address.sol”;
        require(value < 2**64, “SafeCast: value doesn\’t fit in 64 bits”);
  function castToUint8(uint _a) public returns (uint8) {
    modifier onlyOwner() {
举办会见节制另一个相对付Ownable合约 更高级一些的是利用 Roles 库, 它可以界说多个脚色,对付需要多个会见条理的节制时,该当思量利用Roles库。
        _mint(player, newItemId);
        require(b <= a, errorMessage);
    }
contract BasicUtils {
        require(value < 2**8, “SafeCast: value doesn\’t fit in 8 bits”);
}
算术运算
}
    return 1;
contract GLDToken is ERC20, ERC20Detailed {
    function toUint16(uint256 value) internal pure returns (uint16) {
import “@openzeppelin/contracts/token/ERC20/ERC20.sol”;
        uint256 c = a * b;
        require(b != 0, errorMessage);
pragma solidity ^0.5.0;
    function checkIfContract(address _addr) public {
        // assert(a == b * c + a % b); // There is no case in which this doesn’t hold
  using SafeCast for uint;
    using Roles for Roles.Role;
pragma solidity ^0.5.5;
        }
    }
下面的示例代码是如何利用SafeCast将uint转换为uint8:
    function isOwner() public view returns (bool) {
SafeMath库的浸染是帮我们举办算术运中举办须要的查抄,制止代码中因算术运算(如溢出)而引入裂痕。
SafeCast的源代码如下:
由于Roles是一个Solidity库而非合约,因此不能通过担任的方法来利用,需要利用solidity的using语句[3]来将库中界说的函数附加到指定的数据范例上。
    function owner() public view returns (address) {
6. 非同质化代币:ERC721Enumerable / ERC721Full
留意:在本文中我们利用的OpenZeppelin版本为2.5.x,利用 solidity 0.5.x编译器编译。
        require(_burners.has(msg.sender), “DOES_NOT_HAVE_BURNER_ROLE”);
        _tokenIds.increment();
    }
        return div(a, b, “SafeMath: division by zero”);
        if (a == 0) {
    address private _owner;
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
contract OwnableContract is Ownable {
pragma solidity ^0.5.0;
}
        return mod(a, b, “SafeMath: modulo by zero”);
        // Solidity only automatically asserts when dividing by 0
        return sub(a, b, “SafeMath: subtraction overflow”);
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
    }
    }
不需要本身实现完整的ERC20代币[4]合约 ,OpenZeppelin已经帮我们实现好了, 我们只需要担任和初始化就好了。
import “../GSN/Context.sol”;
        require(account != address(0), “Roles: account is the zero address”);
    }
  }
    }
OpenZeppelin的Roles库的源代码如下:
        }
  function restrictedFunction() public onlyOwner returns (uint) {
假如需要列举一个账号的所持有的ERC721资产,需要利用ERC721Enumerable合约而不是基本的 ERC721,
}
        _mint(to, amount);
        // Gas optimization: this is cheaper than requiring ‘a’ not being zero, but the
contract BasicSafeCast {
        return c;
import “@openzeppelin/contracts/token/ERC721/ERC721Full.sol”;
[2] 修饰器: https://learnblockchain.cn/docs/solidity/structure-of-a-contract.html#modifier
import “@openzeppelin/contracts/ownership/Ownable.sol”;
        _setTokenURI(newItemId, tokenURI);
        return _msgSender() == _owner;
        for (uint256 i = 0; i < minters.length; ++i) {
[1] OpenZeppelin的智能合约代码库: https://openzeppelin.com/
}
using SafeMath for uint256;
    constructor(uint256 initialSupply) ERC20Detailed(“Gold”, “GLD”, 18) public {
    }
    }
        // benefit is lost if ‘b’ is also tested.
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    function remove(Role storage role, address account) internal {
        return uint8(value);
    }
        return uint16(value);
        // Only burners can burn
    {
    constructor(address[] memory minters, address[] memory burners)
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
    }
        _owner = newOwner;
pragma solidity ^0.5.0;
        return uint64(value);
        address msgSender = _msgSender();
OpenZeppelin也提供了非同质化代币的实现,我们同样不需要把完整的把尺度实现一次。
和Roles库的用法雷同,你需要利用using语句将SafeMath库中的函数附加到uint256范例上,譬喻:
        require(c / a == b, “SafeMath: multiplication overflow”);
[3] using语句: https://learnblockchain.cn/docs/solidity/contracts.html#using-for
        require(b > 0, errorMessage);
下面是一个简朴的、担任自Ownable的合约:
        // Only minters can mint
    }
        return c;
    }
    }
        require(value < 2**128, “SafeCast: value doesn\’t fit in 128 bits”);
pragma solidity ^0.5.0;
    function add(Role storage role, address account) internal {
ERC721Enumerable提供了_tokensOfOwner()要领 直接支持列举特定账号的所有资产。假如你但愿有所有的扩展成果合约,那么可以直接选择ERC721Full。下面的代码展示了基于ERC721Full定制非同质化代币:
Ownable合约的陈设账号会被当做合约的拥有者(owner),某些合约函数,譬喻转移所有权,就限制在只答允拥有者(owner)挪用。
        require(_minters.has(msg.sender), “DOES_NOT_HAVE_MINTER_ROLE”);
    Roles.Role private _minters;
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
References
        return a % b;
1. 利用 Ownable 举办所有者限制
    }
        _mint(msg.sender, initialSupply);
library Roles {
[5] 7 OpenZeppelin Contracts You Should Always Use: https://medium.com/better-programming/7-openzeppelin-contracts-you-should-always-use-5ba2e7953cc4
    function toUint8(uint256 value) internal pure returns (uint8) {
    using Counters for Counters.Counter;
    }
contract Ownable is Context {
        _owner = address(0);
ERC20Detailed
[6] Alex Roan: https://medium.com/@alexroan?source=post_page—–5ba2e7953cc4———————-

作者:Alex Roan[6]
        public
    constructor() ERC721Full(“GameItem”, “ITM”) public {
    function has(Role storage role, address account) internal view returns (bool) {
        emit OwnershipTransferred(_owner, address(0));
        role.bearer[account] = true;
}
        uint256 c = a / b;
OpenZeppelin 的 Ownable合约提供的onlyOwner 修饰器[2]是用来限制某些特定合约函数的会见权限。
    }
    }
    }
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
pragma solidity ^0.5.0;
    function toUint64(uint256 value) internal pure returns (uint64) {
7. 用 Address库识别地点
作为一个智能合约开拓者,我们经常会思考如何淘汰合约的执行时间以及空间,节省代码空间的一个步伐就是利用更少位数的整数范例。但不幸的是,假如你利用uint8作为变量范例,那么在挪用SafeMath库函数之前,就必需先将其转换为uint256范例,然后在挪用SafeMath库函数之后,还需要再转换回uint8范例。SafeCast库的浸染就在于可以帮你完成这些转换而无需担忧溢出问题。
    function mint(address to, uint256 amount) public {
        emit OwnershipTransferred(_owner, newOwner);
            return 0;
通过添加onlyOwner 修饰器 来限制 restrictedFunction 函数合约的owner账号可以乐成挪用:
        require(!has(role, account), “Roles: account already has role”);
    function _transferOwnership(address newOwner) internal {
}
import “@openzeppelin/contracts/drafts/Counters.sol”;
    function awardItem(address player, string memory tokenURI) public returns (uint256) {
}
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
永远不要直接利用算术运算符譬喻:+、-、*、/ 举办数学计较,除非你相识如何查抄溢出裂痕,不然就没法担保这些算术计较的安详性。
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    using Address for address;
    Counters.Counter private _tokenIds;
        require(has(role, account), “Roles: account does not have role”);
原文链接:7 OpenZeppelin Contracts You Should Always Use[5]
3. 安详的算术运算库:SafeMath
import “@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol”;
    }
下面是Ownable合约的源代码:
    }
  }
    function transferOwnership(address newOwner) public onlyOwner {
    function burn(address from, uint256 amount) public {
import “@openzeppelin/contracts/token/ERC20/ERC20.sol”;
        return _owner;
import “@openzeppelin/contracts/access/Roles.sol”;
    Roles.Role private _burners;
        ERC20Detailed(“MyToken”, “MTKN”, 18)
        _transferOwnership(newOwner);
  function openFunction() public returns (uint) {
下面是一个操作OpenZeppelin的ERC20和ERC20Detailed合约实现定制代币的例子:
pragma solidity ^0.5.0;
下面是SafeMath的源代码:
        return newItemId;
pragma solidity ^0.5.5;
import “@openzeppelin/contracts/math/SafeCast.sol”;
    function toUint32(uint256 value) internal pure returns (uint32) {
       _burn(from, amount);
pragma solidity ^0.5.0;
下面的代码利用Roles库用 _minters和_burners 两种脚色去限制函数:
        role.bearer[account] = false;
        }
第8行的浸染是将Roles库中的函数附加到Roles.Role范例上。第18行就是在Roles.Role范例上直接利用这些库函数的要领:_minters.add(),个中add()就是Roles库提供的实现。
        return uint32(value);
帮助东西库
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        mapping (address => bool) bearer;
    }
    }
    function toUint128(uint256 value) internal pure returns (uint128) {
contract MyToken is ERC20, ERC20Detailed {
        _owner = msgSender;

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。