ARC721
#
AbstactARC-721 is a standard set of interfaces for issuing non-fungible tokens (NFT) on the Alaya network and is fully compatible with ERC-721.
#
ARC-721 Token StandardARC-721-compliant smart contracts must all implement the ARC721 and ARC165 interface, and can implement other extended interfaces according to business needs.
#
ARC-721 & ARC-165 Interfacesinterface ARC721 /* is ARC165 */ { //events 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);
//required function balanceOf(address _owner) external view returns (uint256); function ownerOf(uint256 _tokenId) external view returns (address); function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; function transferFrom(address _from, address _to, uint256 _tokenId) external payable; function approve(address _approved, uint256 _tokenId) external payable; function setApprovalForAll(address _operator, bool _approved) external; function getApproved(uint256 _tokenId) external view returns (address); function isApprovedForAll(address _owner, address _operator) external view returns (bool); interface ARC165 { function supportsInterface(bytes4 interfaceID) external view returns (bool); }
//optional interface ARC721TokenReceiver { function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4); }
interface ARC721Metadata { function name() external view returns (string _name); function symbol() external view returns (string _symbol); function tokenURI(uint256 _tokenId) external view returns (string); }
interface ARC721Enumerable { function totalSupply() external view returns (uint256); function tokenByIndex(uint256 _index) external view returns (uint256); function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); }}
#
Required interfacesbalanceOf
: Count all NFTs assigned to an owner.ownerOf
:Find the owner of an NFT.safeTransferFrom
:Transfers the ownership of an NFT from one address to another address.transferFrom
:Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE.approve
:Change or reaffirm the approved address for an NFT.setApprovalForAll
:Enable or disable approval for a third party ("operator") to manage.getApproved
:Get the approved address for a single NFT.isApprovedForAll
:Query if an address is an authorized operator for another address.supportsInterface
:Query if a contract implements an interface.
#
Optionally interfacesonERC721Received
:Handle the receipt of an NFT. If you need to make a secure transfer inside the contract, you must implement the ARC721TokenReceiver interface.name
:A descriptive name for a collection of NFTs in this contract.symbol
:An abbreviated name for NFTs in this contract.tokenURI
:A distinct Uniform Resource Identifier (URI) for a given asset. The URI may point to a JSON file that conforms to the "ERC721 Metadata JSON Schema". This is the “ERC721 Metadata JSON Schema” referenced above.:{ "title": "Asset Metadata", "type": "object", "properties": { "name": { "type": "string", "description": "Identifies the asset to which this NFT represents" }, "description": { "type": "string", "description": "Describes the asset to which this NFT represents" }, "image": { "type": "string", "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive." } }}
totalSupply
:Count NFTs tracked by this contract.tokenByIndex
:Enumerate valid NFTs.tokenOfOwnerByIndex
:Enumerate NFTs assigned to an owner.
#
Event- Transfer:This emits when ownership of any NFT changes by any mechanism.
- Approval:This emits when the approved address for an NFT is changed or.
- ApprovalForAll:This emits when an operator is enabled or disabled for an owner.
#
ExampleARC-721 standard is fully compatible with ERC-721, examples are available here.
#
View TokenYou can view ARC20 Token and transaction history in Alaya Explorer and ATON Wallet.
#
Contract DeploymentPlease refer to Solidity Getting started.
#
Method callHere's an example of how to call a contract method using the Python SDK.
#
Install the dependenciesUse the following command to install the python library
, Python version 3.7.5+ is recommended:
pip install client-sdk-python
During the installation process, some dependency packages will require c++14
compilation, please download cppbuildtools after you see the relevant prompt, use the default value to install it, and then re-execute the pip install command.
#
Instantiationfrom client_sdk_python import Web3, HTTPProvider
rpc, chain_id, hrp = 'http://127.0.0.1:6789', 201030, 'ATP'w3 = Web3(HTTPProvider(rpc), chain_id=chain_id, hrp_type=hrp)abi = [ { "inputs": [ {"internalType": "string", "name": "_name", "type": "string"}, {"internalType": "string", "name": "_symbol", "type": "string"} ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [ {"internalType": "address", "name": "_to", "type": "address"}, {"internalType": "uint256", "name": "_tokenId", "type": "uint256"}, {"internalType": "string", "name": "_uri", "type": "string"} ], "name": "mint", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{"internalType": "address", "name": "_owner", "type": "address"}], "name": "balanceOf", "outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}], "stateMutability": "view", "type": "function" }, { "inputs": [{"internalType": "uint256", "name": "_tokenId", "type": "uint256"}], "name": "ownerOf", "outputs": [{"internalType": "address", "name": "_owner", "type": "address"}], "stateMutability": "view", "type": "function" }, { "inputs": [ {"internalType": "address", "name": "_from", "type": "address"}, {"internalType": "address", "name": "_to", "type": "address"}, {"internalType": "uint256", "name": "_tokenId", "type": "uint256"} ], "name": "safeTransferFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ {"indexed": true, "internalType": "address", "name": "_from", "type": "address"}, {"indexed": true, "internalType": "address", "name": "_to", "type": "address"}, {"indexed": true, "internalType": "uint256", "name": "_tokenId", "type": "uint256"} ], "name": "Transfer", "type": "event" },]arc721 = w3.eth.contract(address='contract address', abi=abi)print([func for func in arc721.functions])print([event for event in arc721.events])
#
Query Contract InformationThe following is an example of totalSupply
, balanceOf
, other query methods are similar to this.
# Count all NFTs assigned to an ownerarc721.functions.balanceOf('your address').call()# Find the owner of an NFTarc721.functions.ownerOf('your token id').call()
#
Sending a contract transactionThe following is an example of a safeTransferFrom
call.
# Transferring ownership of NFT from one address to anothertx = { 'chainId': w3.chain_id, 'nonce': w3.eth.getTransactionCount('your address'), 'gas': 4012388, 'value': 0, 'gasPrice': 1000000000,}txn = arc721.functions.safeTransferFrom(_from='your address', _to='to address', _tokenId='your token id').buildTransaction(tx)signed_txn = w3.eth.account.signTransaction(txn, private_key='your private key')tx_hash = w3.eth.sendRawTransaction(signed_txn.rawTransaction).hex()receipt = w3.eth.waitForTransactionReceipt(tx_hash)
#
Get contract eventsAs an example of a transfer transaction event.
events = arc721.events.Transfer().processReceipt(receipt)
#
Upload Metadata to IPFS networkMetadata
is the details of the NFT token, whis is stored under the chain. We usually need to specify a URI path as the Metadata data for an NFT token when we issue it.
#
1. Install IPFSPlease refer to the IPFS documentation installation and startup.
#
2. Upload the FileUpload an picture with the name Alaya.jpeg
to the ipfs node.
$ ipfs add Alaya.jpeg
If the above command runs successfully it will output the file ID, as follows.
added QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy Alaya.jpeg
#
3. Verify that the picture can be downloadedOpen the following link of the picture in the browser, you can see the picture indicating that the picture can be downloaded successfully: https://ipfs.io/ipfs/QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy?filename=Alaya.jpeg
#
4. Construct the NFT metadata fileNext you can use the image link above to construct Metadata
for NFT.
Create a JSON file according to the metadata example in the ARC-721 document and name it alaya.json, and replace the description value in the image field with the BTFS download link of the image above, as shown in the figure:
{ "name":"Alaya.jpg", "author":"Alaya", "description":"use for arc721", "image":"https://ipfs.io/ipfs/QmZtmD2qt6fJot32nabSP3CUjicnypEBz7bHVDhPQt9aAy?filename=Alaya.jpeg"}
Run the following command to upload alaya.json
$ ipfs add alaya.json
You can get the file ID after uploading, as follows:
added QmQXqTVCb1w7CmdsYxHWR1T1qyaCHHgWwiPmoZDcQL39Px alaya.json
Open the URI of the metadata file in the browser: https://ipfs.io/ipfs/QmQXqTVCb1w7CmdsYxHWR1T1qyaCHHgWwiPmoZDcQL39Px?filename=alaya.json
If the Metadata information is displayed in the browser, it means the file was uploaded successfully.