我们许多时候需要这样做,因此这个模式在以太坊智能合约开拓中很是风行。
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———————-
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;
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。