赞
踩
数字加密货币可以分为原生币和代币(token)。ERC(Etherum Request for Comments)是以太坊开发者针对代币提交的协议提案,而20表示的是协议的编号。所有符合ERC-20标准的代币都能立即兼容以太坊钱包,并且降低了token的开发门槛,只要实现ERC-20协议就可以快速开发出一种新的token。除此之外,通过实现ERC标准还增加了合约之间的互操作性、token的安全性。但是ERC-20也有着一些缺陷,比如:发布后不能修改合约、如果向合约中发送的不是ETH,而是其他token,那么智能合约将不能退还你发送的token。
这个网站列举了所有的ERC协议,可以进行参考:https://eips.ethereum.org/erc
function totalSupply() public view returns (uint256)
function balanceOf(address _owner) public view returns (uint256 balance)
function transfer(address _to, uint256 _value) public returns (bool success)
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success)
function approve(address _spender, uint256 _value) public returns (bool success)
function allowance(address _owner, address _spender) public view returns (uint256 remaining)
event Transfer(address indexed _from, address indexed _to, uint256 _value)
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
function name() public view returns (string)
function symbol() public view returns (string)
function decimals() public view returns (uint8)
//------ERC20.sol pragma solidity 0.6.0; abstract contract ERC20{ function totalSupply() virtual public view returns (uint256); function balanceOf(address _owner) virtual public view returns (uint256 balance); function transfer(address _to, uint256 _value) virtual public returns (bool success); function transferFrom(address _from, address _to, uint256 _value) virtual public returns (bool success); function approve(address _spender, uint256 _value) virtual public returns (bool success); function allowance(address _owner, address _spender) virtual public view returns (uint256 remaining); event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); } //-------myERC20.sol pragma solidity ^0.6.0; import "./ERC20.sol"; // 实现安全运算 contract SafeMath { function safeMul(uint256 a, uint256 b) internal returns (uint256) { uint256 c = a * b; assert(a == 0 || c / a == b); return c; } function safeDiv(uint256 a, uint256 b) internal returns (uint256) { assert(b > 0); uint256 c = a / b; assert(a == b * c + a % b); return c; } function safeSub(uint256 a, uint256 b) internal returns (uint256) { assert(b <= a); return a - b; } function safeAdd(uint256 a, uint256 b) internal returns (uint256) { uint256 c = a + b; assert(c>=a && c>=b); return c; } function assert(bool assertion) internal { if (!assertion) { revert(); } } } contract SafeMath { function safeMul(uint256 a, uint256 b) internal returns (uint256) { uint256 c = a * b; assert(a == 0 || c / a == b); return c; } function safeDiv(uint256 a, uint256 b) internal returns (uint256) { assert(b > 0); uint256 c = a / b; assert(a == b * c + a % b); return c; } function safeSub(uint256 a, uint256 b) internal returns (uint256) { assert(b <= a); return a - b; } function safeAdd(uint256 a, uint256 b) internal returns (uint256) { uint256 c = a + b; assert(c>=a && c>=b); return c; } function assert(bool assertion) internal { if (!assertion) { revert(); } } } contract myERC20 is ERC20, SafeMath{ address public payable owner; // 定义合约拥有者 uint256 _totalSupply; // token发行总量 mapping(address => uint256) _balance; // 地址拥有的token mapping(address => mapping(address => uint256)) approve; // 地址授权给另一个地址token event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); // 构造函数,初始化token总量、合约拥有者。 constructor(uint256 totalSupply) public { _totalSupply = totalSupply; _owner = msg.sender; } modifier onlyOwner(){ require(msg.sender == _owner); _; } // 向_to中空投_value的token function airDrop (address _to, uint256 _value) onlyOwer public { require(_to != address(0)); _balance[_to] = SafeMath.safeAdd(_balance[_to], _value); _totalSupply = SafeMath.safeAdd(_totalSupply, _value); } // 返回token总量 function totalSupply() override public view returns (uint256) { return _totalSupply; } // 返回_owner拥有token的数量 function balanceOf(address _owner) override public view returns (uint256 balance) { require(owner != address(0)); return _balance[_owner]; } // 向_to中转入_value的token function transfer(address _to, uint256 _value) override public returns (bool success) { require(_to != address(0)); require(_value > 0); require(_balance[msg.sender] >= _value); _balance[msg.sender] = SafeMath.safeSub(_balance[msg.sender], _value); _balance[_to] = SafeMath.safeAdd(_balance[_to], _value); emit Transfer( msg.sender, _to, _value); return true; } // 从_from向_to转入_value的token function transferFrom(address _from, address _to, uint256 _value) override public returns (bool success) { require(_from != address(0)); require(_to != address(0)); require(_approve[_from][msg.sender] >= _value); _approve[_from][msg.sender] = SafeMath.safeSub(_approve[_from][msg.sender], _value); _balance[_to] = SafeMath.safeAdd(_balance[_to], _value); emit Transfer(_from, _to, _value); return true; } // 授权给_spender _value数量的token function approve(address _spender, uint256 _value) override public returns (bool success) { require(_spender != address(0)); require(_balance[msg.sender] >= _value); _approve[msg.sender][_spender] = SafeMath.safeAdd(_approve[msg.sender][_spender], _value); _balance[msg.sender] = SafeMath.safeSub(_balance[msg.sender], _value); emit Approval(msg.sender, _spender, _value); return true; } // 查询_owner向_spender授权了多少token function allowance(address _owner, address _spender) override public view returns (uint256 remaining) { require(_owner != address(0)); require(_spender != address(0)); return _approve[_owner][_spender]; } // 提取token function withdrawEther(uint256 _value) public{ require(msg.sender == owner); owner.transfer(_value); } }
ERC-721官方的解释是:Non-Fungible Tokens(非同质化代币),简写为NFT。实现了ERC-72协议的token,每个都有自己的唯一性和独特价值,并且不可分割。目前主要适用于收藏品、游戏等需要确定唯一性资产的场景。
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function getApproved(uint256 _tokenId) external view returns (address);
function setApprovalForAll(address _operator, bool _approved) external;
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
function name() external view returns (string _name);
function symbol() external view returns (string _symbol);
function tokenURI(uint256 _tokenId) external view returns (string);
function totalSupply() external view returns (uint256);
function tokenByIndex(uint256 _index) external view returns (uint256);
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
//---ERC721.sol pragma solidity ^0.6.0; abstract contract ERC721{ function balanceOf(address _owner) virtual external view returns (uint256); function ownerOf(uint256 _tokenId) virtual external view returns (address); function transferFrom(address _from, address _to, uint256 _tokenId) virtual external payable; function safeTransferFrom(address _from, address _to, uint256 _tokenId) virtual external payable; function safeTransferFrom(address _from, address _to, uint256 _tokenId, byte data) virtual external payable; function approve(address _approved, uint256 _tokenId) virtual external payable; function setApprovalForAll(address _operator, bool _approved) virtual external; function getApproved(uint256 _tokenId) virtual external view returns (address); function isApprovedForAll(address _owner, address _operator) virtual external view returns (bool); event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); } //-----myArt.sol pragma solidity ^0.6.0; import "./ERC721.sol"; contract pcArtCoin is ERC721{ // 合约拥有者 address public fundation; // 资产结构体 struct asset{ uint256 _tokenId; // token ID address owner; // token 拥有者地址 address approver; // token 被授权的地址 uint256 timestamp; // 时间戳 byte data; // token 中包含的数据 } // 地址拥有的NFT数量 mapping(address => uint256) balances; // NFT编号对应的资产 mapping(uint256 => asset) tokens; // 授权 mapping(address => mapping(address => bool)) isAllProved; event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); // 设置资产 function setAssert(uint256 number, address owner, byte data) onlyFundation public{ require(owner != address(0)); // 生产随机的token ID uint256 tokenId = uint256(keccak256(abi.encodePacked(number, msg.sender, now, owner, data))); // 保证token ID不同 require(tokens[tokenId]._tokenId != tokenId); // 设置资产 asset memory Asset = asset(tokenId, owner, address(0), now, data); tokens[tokenId] = Asset; } modifier onlyFundation(){ require(msg.sender == fundation); _; } // 返回_owner拥有NFT的数量 function balanceOf(address _owner) override external view returns (uint256){ require(_owner != address(0)); return balances[_owner]; } // 返回_tokenId的拥有者 function ownerOf(uint256 _tokenId) override external view returns (address){ require(_tokenId != 0); return tokens[_tokenId].owner; } // 从_from转到_to, NFT编号为_tokenId function transferFrom(address _from, address _to, uint256 _tokenId) override external payable{ // 安全检查 require(tokens[_tokenId].owner == _from); require(_from != address(0) && _to != address(0) && _tokenId != 0); require(msg.sender == _from || tokens[_tokenId].approver == msg.sender); tokens[_tokenId].owner = _to; tokens[_tokenId].approver = address(0); tokens[_tokenId].timestamp = now; tokens[_tokenId].data = byte(""); balances[_from] -= 1; balances[_to] += 1; emit Transfer(_from, _to, _tokenId); } function safeTransferFrom(address _from, address _to, uint256 _tokenId) override external payable{ require(tokens[_tokenId].approver == _from); // 判断_to不为合约地址 require(addrCheck(_to)); require(_from != address(0) && _to != address(0) && _tokenId != 0); require(msg.sender == _from || tokens[_tokenId].approver == msg.sender); tokens[_tokenId].owner = _from; tokens[_tokenId].approver = address(0); tokens[_tokenId].timestamp = now; tokens[_tokenId].data = byte(""); balances[_from] -= 1; balances[_to] += 1; emit Transfer(_from, _to, _tokenId); } function safeTransferFrom(address _from, address _to, uint256 _tokenId, byte data) override external payable{ require(tokens[_tokenId].owner == _from); require(addrCheck(_to)); require(_from != address(0) && _to != address(0) && _tokenId != 0); require(msg.sender == _from || tokens[_tokenId].approver == msg.sender); tokens[_tokenId].owner = _to; tokens[_tokenId].approver = address(0); tokens[_tokenId].timestamp = now; tokens[_tokenId].data = data; balances[_from] -= 1; balances[_to] += 1; emit Transfer(_from, _to, _tokenId); } function approve(address _approved, uint256 _tokenId) override external payable{ require(tokens[_tokenId].owner == msg.sender); require(_tokenId != 0); tokens[_tokenId].approver = _approved; emit Approval(msg.sender, _approved, _tokenId); } // 向_operator 授权操作 function setApprovalForAll(address _operator, bool _approved) override external{ require(_operator != address(0)); require(isAllProved[msg.sender][_operator] != _approved); isAllProved[msg.sender][_operator] = _approved; emit ApprovalForAll(msg.sender, _operator, _approved); } // 获取 _tokenId token的被授权人 function getApproved(uint256 _tokenId) override external view returns (address){ require(_tokenId != 0); return tokens[_tokenId].approver; } function isApprovedForAll(address _owner, address _operator) override external view returns (bool){ require(_owner != address(0) || _operator != address(0)); return isAllProved[_owner][_operator]; } // 判断是否为合约地址,是返回false,不是返回true function addrCheck(address _addr) private view returns (bool){ uint256 size; assembly{ size := extcodesize(_addr) } require(size == 0); return true; } }
如果代码有不足之处,欢迎评论区指出。另外推荐一个github地址,上面有许多区块链学习资源及技术文章,同样欢迎参观,一起学习进步:https://github.com/mindcarver。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。