【跟乐乐学solidity】五 智能合约接口规范:IBEP

编程入门 行业动态 更新时间:2024-10-11 17:30:06

【跟<a href=https://www.elefans.com/category/jswz/34/1750480.html style=乐乐学solidity】五 智能合约接口规范:IBEP"/>

【跟乐乐学solidity】五 智能合约接口规范:IBEP

一.接口规范的意义

我们都知道,智能合约本身是一个程序,它可以根据你的想法开发一些诸如众筹之类的应用,但智能合约本身更大的场景则是从合约池子购买和出售等作用,以及价格展示等等。
因此,以太智能合约提出了IERC20和ERC20等接口规范,用于让人们编写合约时,根据其接口来开发经典的交易功能。
对于IERC20和ERC20的标准实现,可以参考下面两个文章:
详细讲解ERC20:
IERC20及ERC20的标准实现例子:

二.IBEP-20规范接口的实现

IBEP-20是BSC智能链上的规范接口,BSC智能链和其智能合约本身就是完全属于以太智能链和其合约的复制版,所以其‘IBEP-20’接口和ERC-20以及IERC-20并没有多少区别。
考虑到BSC智能链的热度比较大,就以BSC智能链的合约规范接口作为例子来写一个实现模板。

需要注意的是,其中有三个非接口和合约本身的类存在,
一:Context
表示上下文
二:SafeMath
Library库,用于数据安全,防止溢出。
关于Library库的介绍,参考这个文章:
三:Ownable
合约权限设置。
可以设置放弃权限或转移权限,同时对一些函数的调用进行权限绑定,如绑定为仅合约持有者调用。

这三者虽然不属于IBEP-20接口,但同样是一个标准合约不可或缺的东西,所以一并附上。

pragma solidity 0.5.16;interface IBEP20 {/*** @dev Returns the amount of tokens in existence.* 返回账户余额*/function totalSupply() external view returns (uint256);/*** @dev Returns the token decimals.* 返回标记小数*/function decimals() external view returns (uint8);/*** @dev Returns the token symbol.* 返回合约token的符号*/function symbol() external view returns (string memory);/*** @dev Returns the token name.*  返回合约名称*/function name() external view returns (string memory);/*** @dev Returns the bep token owner.* 获取该合约所有者的地址*/function getOwner() external view returns (address);/*** @dev Returns the amount of tokens owned by `account`.* 返回指定账户地址在该合约中拥有的数量。*/function balanceOf(address account) external view returns (uint256);/*** @dev Moves `amount` tokens from the caller's account to `recipient`.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.** 将指定的数量转账给指定的目标地址。recipient为目标地址。*/function transfer(address recipient, uint256 amount) external returns (bool);/*** @dev Returns the remaining number of tokens that `spender` will be* allowed to spend on behalf of `owner` through {transferFrom}. This is* zero by default.** This value changes when {approve} or {transferFrom} are called.* 返回津贴享有者(spender)仍可从所有者(_owner)中提取的剩余令牌数量。默认为0* 调用{approve}或{transferFrom}时,此值会更改**/function allowance(address _owner, address spender) external view returns (uint256);/*** @dev Sets `amount` as the allowance of `spender` over the caller's tokens.** Returns a boolean value indicating whether the operation succeeded.** IMPORTANT: Beware that changing an allowance with this method brings the risk* that someone may use both the old and the new allowance by unfortunate* transaction ordering. One possible solution to mitigate this race* condition is to first reduce the spender's allowance to 0 and set the* desired value afterwards:* ** Emits an {Approval} event.* 将指定的账户(amount)设置为津贴享有者,并设定最多提取数量。若成功则返回true* 重要提示:使用这种方法更改津贴会带来风险* 有人可能通过不幸的交易顺序使用旧的和新的津贴。* 缓解这场竞争的一个可能解决方案则是,首先将支出者的津贴减少到0,并设置为之后的期望值。参考:***/function approve(address spender, uint256 amount) external returns (bool);/*** @dev Moves `amount` tokens from `sender` to `recipient` using the* allowance mechanism. `amount` is then deducted from the caller's* allowance.** Returns a boolean value indicating whether the operation succeeded.** Emits a {Transfer} event.** 指定发送者(sender)向接收者(recipient)转移指定数量的令牌。* 需要注意的是,即使双方或任何一方的地址值是0,仍然被视为正常转移。*/function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);/*** @dev Emitted when `value` tokens are moved from one account (`from`) to* another (`to`).** Note that `value` may be zero.* 该函数为事件函数(event),必须在发生’from‘向’to‘转移令牌时触发。value代表令牌数量,可以为0.* 创建新令牌的令牌契约应该在创建令牌时触发一个Transfer事件,_from地址设置为0x0。*/event Transfer(address indexed from, address indexed to, uint256 value);/*** @dev Emitted when the allowance of a `spender` for an `owner` is set by* a call to {approve}. `value` is the new allowance.* 该函数为事件函数(event),必须在approve函数被成功调用时触发,即:将某地址设置为津贴享用者,并成功返回true。*/event Approval(address indexed owner, address indexed spender, uint256 value);
}/** @dev Provides information about the current execution context, including the* sender of the transaction and its data. While these are generally available* via msg.sender and msg.data, they should not be accessed in such a direct* manner, since when dealing with GSN meta-transactions the account sending and* paying for execution may not be the actual sender (as far as an application* is concerned).** This contract is only required for intermediate, library-like contracts.* 提供有关当前执行上下文的信息,包括事务的发送方及其数据。虽然这些通常是可用的。* 通过'msg.sender”和“msg.data’,它们不应该在这样一个直接访问方式,因为在处理GSN元交易时,账户发送和支付执行可能不是实际的发送者(就申请而言)。* 此合约只适用于中间的、类库的合约。*/
contract Context {// Empty internal constructor, to prevent people from mistakenly deploying 空的内部构造函数,以防止错误部署// an instance of this contract, which should be used via inheritance. 这个合约的实例,应该通过继承来使用。constructor () internal { }function _msgSender() internal view returns (address payable) {return msg.sender;}function _msgData() internal view returns (bytes memory) {this; // silence state mutability warning without generating bytecode - see  msg.data;}
}/*** @dev Wrappers over Solidity's arithmetic operations with added overflow* checks.** Arithmetic operations in Solidity wrap on overflow. This can easily result* in bugs, because programmers usually assume that an overflow raises an* error, which is the standard behavior in high level programming languages.* `SafeMath` restores this intuition by reverting the transaction when an* operation overflows.** Using this library instead of the unchecked operations eliminates an entire* class of bugs, so it's recommended to use it always.* 在Solidity的算术操作上添加溢出检查的包装器。* solid中的算术运算在溢出时自动包装。这很容易导致bug,* 因为程序员通常假设溢出会引发错误,这是高级编程语言中的标准行为。* 当操作溢出时,' SafeMath '通过恢复事务来恢复这种直觉。* 使用这个库而不是未检查的操作可以消除整个类的bug,所以建议始终使用它。*/
library SafeMath {/*** @dev Returns the addition of two unsigned integers, reverting on* overflow.** Counterpart to Solidity's `+` operator.** Requirements:* - Addition cannot overflow.*/function add(uint256 a, uint256 b) internal pure returns (uint256) {uint256 c = a + b;require(c >= a, "SafeMath: addition overflow");return c;}/*** @dev Returns the subtraction of two unsigned integers, reverting on* overflow (when the result is negative).** Counterpart to Solidity's `-` operator.** Requirements:* - Subtraction cannot overflow.*/function sub(uint256 a, uint256 b) internal pure returns (uint256) {return sub(a, b, "SafeMath: subtraction overflow");}/*** @dev Returns the subtraction of two unsigned integers, reverting with custom message on* overflow (when the result is negative).** Counterpart to Solidity's `-` operator.** Requirements:* - Subtraction cannot overflow.*/function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {require(b <= a, errorMessage);uint256 c = a - b;return c;}/*** @dev Returns the multiplication of two unsigned integers, reverting on* overflow.** Counterpart to Solidity's `*` operator.** Requirements:* - Multiplication cannot overflow.*/function mul(uint256 a, uint256 b) internal pure returns (uint256) {// Gas optimization: this is cheaper than requiring 'a' not being zero, but the// benefit is lost if 'b' is also tested.// See:  (a == 0) {return 0;}uint256 c = a * b;require(c / a == b, "SafeMath: multiplication overflow");return c;}/*** @dev Returns the integer division of two unsigned integers. Reverts on* division by zero. The result is rounded towards zero.** Counterpart to Solidity's `/` operator. Note: this function uses a* `revert` opcode (which leaves remaining gas untouched) while Solidity* uses an invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function div(uint256 a, uint256 b) internal pure returns (uint256) {return div(a, b, "SafeMath: division by zero");}/*** @dev Returns the integer division of two unsigned integers. Reverts with custom message on* division by zero. The result is rounded towards zero.** Counterpart to Solidity's `/` operator. Note: this function uses a* `revert` opcode (which leaves remaining gas untouched) while Solidity* uses an invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {// Solidity only automatically asserts when dividing by 0require(b > 0, errorMessage);uint256 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;}/*** @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),* Reverts when dividing by zero.** Counterpart to Solidity's `%` operator. This function uses a `revert`* opcode (which leaves remaining gas untouched) while Solidity uses an* invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function mod(uint256 a, uint256 b) internal pure returns (uint256) {return mod(a, b, "SafeMath: modulo by zero");}/*** @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),* Reverts with custom message when dividing by zero.** Counterpart to Solidity's `%` operator. This function uses a `revert`* opcode (which leaves remaining gas untouched) while Solidity uses an* invalid opcode to revert (consuming all remaining gas).** Requirements:* - The divisor cannot be zero.*/function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {require(b != 0, errorMessage);return a % b;}
}/*** @dev Contract module which provides a basic access control mechanism, where* there is an account (an owner) that can be granted exclusive access to* specific functions.** By default, the owner account will be the one that deploys the contract. This* can later be changed with {transferOwnership}.** This module is used through inheritance. It will make available the modifier* `onlyOwner`, which can be applied to your functions to restrict their use to* the owner.* 提供基本访问控制机制的合同模块,* 有一个账户(所有者)可以被授予对特定功能的独占访问权。* 默认情况下,所有者帐户将是部署合同的帐户。稍后可以使用{transferOwnership}更改此设置。* 该模块通过继承使用。它将使修饰符“onlyOwner”可用,它可以应用于您的函数,以将它们的使用限制为所有者。*/
contract Ownable is Context {address private _owner;event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);/*** @dev Initializes the contract setting the deployer as the initial owner.*/constructor () internal {address msgSender = _msgSender();_owner = msgSender;emit OwnershipTransferred(address(0), msgSender);}/*** @dev Returns the address of the current owner.*/function owner() public view returns (address) {return _owner;}/*** @dev Throws if called by any account other than the owner.*/modifier onlyOwner() {require(_owner == _msgSender(), "Ownable: caller is not the owner");_;}/*** @dev Leaves the contract without owner. It will not be possible to call* `onlyOwner` functions anymore. Can only be called by the current owner.** NOTE: Renouncing ownership will leave the contract without an owner,* thereby removing any functionality that is only available to the owner.*/function renounceOwnership() public onlyOwner {emit OwnershipTransferred(_owner, address(0));_owner = address(0);}/*** @dev Transfers ownership of the contract to a new account (`newOwner`).* Can only be called by the current owner.*/function transferOwnership(address newOwner) public onlyOwner {_transferOwnership(newOwner);}/*** @dev Transfers ownership of the contract to a new account (`newOwner`).*/function _transferOwnership(address newOwner) internal {require(newOwner != address(0), "Ownable: new owner is the zero address");emit OwnershipTransferred(_owner, newOwner);_owner = newOwner;}
}contract BEP20Token is Context, IBEP20, Ownable {using SafeMath for uint256;mapping (address => uint256) private _balances;mapping (address => mapping (address => uint256)) private _allowances;uint256 private _totalSupply;uint8 private _decimals;string private _symbol;string private _name;constructor() public {_name = {{TOKEN_NAME}};_symbol = {{TOKEN_SYMBOL}};_decimals = {{DECIMALS}};_totalSupply = {{TOTAL_SUPPLY}};_balances[msg.sender] = _totalSupply;emit Transfer(address(0), msg.sender, _totalSupply);}/*** @dev Returns the bep token owner.*/function getOwner() external view returns (address) {return owner();}/*** @dev Returns the token decimals.*/function decimals() external view returns (uint8) {return _decimals;}/*** @dev Returns the token symbol.*/function symbol() external view returns (string memory) {return _symbol;}/*** @dev Returns the token name.*/function name() external view returns (string memory) {return _name;}/*** @dev See {BEP20-totalSupply}.*/function totalSupply() external view returns (uint256) {return _totalSupply;}/*** @dev See {BEP20-balanceOf}.*/function balanceOf(address account) external view returns (uint256) {return _balances[account];}/*** @dev See {BEP20-transfer}.** Requirements:** - `recipient` cannot be the zero address.* - the caller must have a balance of at least `amount`.*/function transfer(address recipient, uint256 amount) external returns (bool) {_transfer(_msgSender(), recipient, amount);return true;}/*** @dev See {BEP20-allowance}.*/function allowance(address owner, address spender) external view returns (uint256) {return _allowances[owner][spender];}/*** @dev See {BEP20-approve}.** Requirements:** - `spender` cannot be the zero address.*/function approve(address spender, uint256 amount) external returns (bool) {_approve(_msgSender(), spender, amount);return true;}/*** @dev See {BEP20-transferFrom}.** Emits an {Approval} event indicating the updated allowance. This is not* required by the EIP. See the note at the beginning of {BEP20};** Requirements:* - `sender` and `recipient` cannot be the zero address.* - `sender` must have a balance of at least `amount`.* - the caller must have allowance for `sender`'s tokens of at least* `amount`.*/function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {_transfer(sender, recipient, amount);_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "BEP20: transfer amount exceeds allowance"));return true;}/*** @dev Atomically increases the allowance granted to `spender` by the caller.** This is an alternative to {approve} that can be used as a mitigation for* problems described in {BEP20-approve}.** Emits an {Approval} event indicating the updated allowance.** Requirements:** - `spender` cannot be the zero address.*/function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));return true;}/*** @dev Atomically decreases the allowance granted to `spender` by the caller.** This is an alternative to {approve} that can be used as a mitigation for* problems described in {BEP20-approve}.** Emits an {Approval} event indicating the updated allowance.** Requirements:** - `spender` cannot be the zero address.* - `spender` must have allowance for the caller of at least* `subtractedValue`.*/function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "BEP20: decreased allowance below zero"));return true;}/*** @dev Creates `amount` tokens and assigns them to `msg.sender`, increasing* the total supply.** Requirements** - `msg.sender` must be the token owner*/function mint(uint256 amount) public onlyOwner returns (bool) {_mint(_msgSender(), amount);return true;}/*** @dev Moves tokens `amount` from `sender` to `recipient`.** This is internal function is equivalent to {transfer}, and can be used to* e.g. implement automatic token fees, slashing mechanisms, etc.** Emits a {Transfer} event.** Requirements:** - `sender` cannot be the zero address.* - `recipient` cannot be the zero address.* - `sender` must have a balance of at least `amount`.*/function _transfer(address sender, address recipient, uint256 amount) internal {require(sender != address(0), "BEP20: transfer from the zero address");require(recipient != address(0), "BEP20: transfer to the zero address");_balances[sender] = _balances[sender].sub(amount, "BEP20: transfer amount exceeds balance");_balances[recipient] = _balances[recipient].add(amount);emit Transfer(sender, recipient, amount);}/** @dev Creates `amount` tokens and assigns them to `account`, increasing* the total supply.** Emits a {Transfer} event with `from` set to the zero address.** Requirements** - `to` cannot be the zero address.*/function _mint(address account, uint256 amount) internal {require(account != address(0), "BEP20: mint to the zero address");_totalSupply = _totalSupply.add(amount);_balances[account] = _balances[account].add(amount);emit Transfer(address(0), account, amount);}/*** @dev Destroys `amount` tokens from `account`, reducing the* total supply.** Emits a {Transfer} event with `to` set to the zero address.** Requirements** - `account` cannot be the zero address.* - `account` must have at least `amount` tokens.*/function _burn(address account, uint256 amount) internal {require(account != address(0), "BEP20: burn from the zero address");_balances[account] = _balances[account].sub(amount, "BEP20: burn amount exceeds balance");_totalSupply = _totalSupply.sub(amount);emit Transfer(account, address(0), amount);}/*** @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.** This is internal function is equivalent to `approve`, and can be used to* e.g. set automatic allowances for certain subsystems, etc.** Emits an {Approval} event.** Requirements:** - `owner` cannot be the zero address.* - `spender` cannot be the zero address.*/function _approve(address owner, address spender, uint256 amount) internal {require(owner != address(0), "BEP20: approve from the zero address");require(spender != address(0), "BEP20: approve to the zero address");_allowances[owner][spender] = amount;emit Approval(owner, spender, amount);}/*** @dev Destroys `amount` tokens from `account`.`amount` is then deducted* from the caller's allowance.** See {_burn} and {_approve}.*/function _burnFrom(address account, uint256 amount) internal {_burn(account, amount);_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "BEP20: burn amount exceeds allowance"));}
}

更多推荐

【跟乐乐学solidity】五 智能合约接口规范:IBEP

本文发布于:2024-02-13 14:43:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1759059.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:乐乐   合约   接口   智能   IBEP

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!