ERC-20
Introduction to ERC-20
Digital encrypted currencies can be divided into native and token currencies. ERC (Etherum Request for Comments)It is the agreement proposal submitted by the Taifang developer for tokens, and 20 represents the number of the agreement. All tokens that meet the ERC-20 standard are immediately compatible with the Taifang wallet and reduce the threshold for token development. As long as the ERC-20 protocol is implemented, a new token can be developed quickly. In addition, the interoperability between contracts, toke can be increased by implementing the ERC standard.However, ERC-20 also has some drawbacks, such as the inability to modify the contract after it is published, and the inability to return the token you sent to the contract if it is not an ETH but another token.
This website lists all ERC protocols for reference: https://eips.ethereum.org/erc
ERC-20 currency standard
- Minimum unit: 6 functions, 2 events
- TotSupply: Get total token distribution
function totalSupply() public view returns (uint256) - balanceOf: Get the _owner token
function balanceOf(address _owner) public view returns (uint256 balance) - transfer: token to _to into _value
function transfer(address _to, uint256 _value) public returns (bool success) - transferFrom: token to _value from _from
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) - approve: authorize token
function approve(address _spender, uint256 _value) public returns (bool success) - allowance: returns the number of remaining token s used
function allowance(address _owner, address _spender) public view returns (uint256 remaining) - Transfer: Transfer events
event Transfer(address indexed _from, address indexed _to, uint256 _value) - Approval: Authorized withdrawal event
event Approval(address indexed _owner, address indexed _spender, uint256 _value)
- TotSupply: Get total token distribution
- Optional unit: 3 functions
- Name:token name
function name() public view returns (string) - logo Identity of Symbol:token
function symbol() public view returns (string) - Decimals: Return by decimal, e.g. input 360000000 to 3.6
function decimals() public view returns (uint8)
- Name:token name
ERC-20 Cases
//------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"; // Implement secure operations 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; // Define contract owner uint256 _totalSupply; // Total token Issues mapping(address => uint256) _balance; // Address-owned token mapping(address => mapping(address => uint256)) approve; // Address is authorized to another address token event Transfer(address indexed _from, address indexed _to, uint256 _value); event Approval(address indexed _owner, address indexed _spender, uint256 _value); // Constructor to initialize total token, contract owner. constructor(uint256 totalSupply) public { _totalSupply = totalSupply; _owner = msg.sender; } modifier onlyOwner(){ require(msg.sender == _owner); _; } // Drop a token of _value into _to function airDrop (address _to, uint256 _value) onlyOwer public { require(_to != address(0)); _balance[_to] = SafeMath.safeAdd(_balance[_to], _value); _totalSupply = SafeMath.safeAdd(_totalSupply, _value); } // Return total token function totalSupply() override public view returns (uint256) { return _totalSupply; } // Returns the number of token s owned by_owner function balanceOf(address _owner) override public view returns (uint256 balance) { require(owner != address(0)); return _balance[_owner]; } // token to _value in _to 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; } // token to _value from _from to _to 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; } // Number of token s authorized to _spender_value 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; } // Query _owner how many token s are authorized to _spender function allowance(address _owner, address _spender) override public view returns (uint256 remaining) { require(_owner != address(0)); require(_spender != address(0)); return _approve[_owner][_spender]; } // Extract token function withdrawEther(uint256 _value) public{ require(msg.sender == owner); owner.transfer(_value); } }
ERC-721
Introduction to ERC-721
The official explanation for ERC-721 is: Non-Fungible Tokens (non-homogeneous token s), short for NFT. Tokens that implement the ERC-72 protocol each have their own unique and unique value and are inseparable. Currently they are mainly used in collections, games and other scenarios where unique assets need to be identified.
ERC-721 Currency Standard
- Minimum unit: 9 functions, 3 events
- Get the number of NFT s assigned to owner
function balanceOf(address _owner) external view returns (uint256); - Query owner address of NFT with token ID number tokenid
function ownerOf(uint256 _tokenId) external view returns (address); - Transfer NFT with token ID number tokenId from user with _front address to user with _to address
function transferFrom(address _from, address _to, uint256 _tokenId) external payable; - Transfer the NTF with token ID number _tokenId from the user with _front address to the user with _to address and carry data data
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; - Transfer NTF with token ID number _tokenId from user with _front address to user with _to address
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; - Authorize _approved
function approve(address _approved, uint256 _tokenId) external payable; - Get the owner address corresponding to the _tokenId token
function getApproved(uint256 _tokenId) external view returns (address); - ERC721 token assets authorized to third-party_operate s to manage individuals
function setApprovalForAll(address _operator, bool _approved) external; - See if _owner authorizes _operation to manage all ERC721 token assets
function isApprovedForAll(address _owner, address _operator) external view returns (bool); - NFT Asset Transfer Events
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); - NFT Asset Authorization Address Change Event
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); - All NFT Asset Authorization Events
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
- Get the number of NFT s assigned to owner
- Optional units
- Describe the name of the NFT collection
function name() external view returns (string _name); - Abbreviation of NTF name in contract
function symbol() external view returns (string _symbol); - Details corresponding to a given asset unique resource identifier (URI)
function tokenURI(uint256 _tokenId) external view returns (string); - Track the number of NFT s in count contracts
function totalSupply() external view returns (uint256); - Enumerate valid NFT s
function tokenByIndex(uint256 _index) external view returns (uint256); - Enumerate NFT s assigned to owners
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
- Describe the name of the NFT collection
ERC-721 Cases
//---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{ // Contract Owner address public fundation; // Asset structure struct asset{ uint256 _tokenId; // token ID address owner; // token owner address address approver; // Authorized address for token uint256 timestamp; // time stamp byte data; // Data contained in token } // Number of NFT s owned by address mapping(address => uint256) balances; // Asset corresponding to NFT number mapping(uint256 => asset) tokens; // To grant authorization 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); // Set up assets function setAssert(uint256 number, address owner, byte data) onlyFundation public{ require(owner != address(0)); // Produce a random token ID uint256 tokenId = uint256(keccak256(abi.encodePacked(number, msg.sender, now, owner, data))); // Make sure token ID s are different require(tokens[tokenId]._tokenId != tokenId); // Set up assets asset memory Asset = asset(tokenId, owner, address(0), now, data); tokens[tokenId] = Asset; } modifier onlyFundation(){ require(msg.sender == fundation); _; } // Returns the number of NFT s owned by_owner function balanceOf(address _owner) override external view returns (uint256){ require(_owner != address(0)); return balances[_owner]; } // Returns the owner of _tokenId function ownerOf(uint256 _tokenId) override external view returns (address){ require(_tokenId != 0); return tokens[_tokenId].owner; } // From _from to _to, NFT number is _tokenId function transferFrom(address _from, address _to, uint256 _tokenId) override external payable{ // Security check 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); // Judging that_to is not a contractual address 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); } // Authorize operations to_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); } // Authorized to get _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]; } // Determines whether it is a contract address, returns false, not true function addrCheck(address _addr) private view returns (bool){ uint256 size; assembly{ size := extcodesize(_addr) } require(size == 0); return true; } }
Last
If there are any deficiencies in the code, please note in the comments section. A github address with many block chain learning resources and technical articles is also recommended. You are also welcome to visit and learn about progress together: https://github.com/mindcarver.