ERC-721 – standard tokenów niewymiennych
Wprowadzenie
Czym jest niewymienny token (NFT)?
Niewymienne tokeny (NFT) służą do identyfikacji czegoś lub kogoś w unikalny sposób. Ten typ tokenu jest idealny do użycia na platformach, które oferują przedmioty kolekcjonerskie, klucze dostępu, bilety loteryjne, numerowane miejsca na koncerty i mecze sportowe itp. Ten specjalny rodzaj tokena ma niesamowite możliwości, dlatego zasługuje na odpowiedni standard, ERC-721 pojawił się, aby to rozwiązać!
Co to jest ERC-721?
ERC-721 wprowadza standard dla NFT, innymi słowy ten typ tokena jest unikalny i może mieć różną wartość niż inny token z tego samego inteligentnego kontraktu, być może ze względu na jego wiek, rzadkość, a nawet coś innego, jak jego wygląd. Czekaj, wizualnie?
Tak! Wszystkie NFT mają zmienną uint256
o nazwie tokenId
, więc dla każdeego kontraktu ERC-721, para contract address, uint256 tokenId
musi być unikatowa globalnie. Powiedział, że aplikacja zdecentralizowana może mieć „konwerter”, który używa tokenId
jako danych wejściowych i wyświetla obraz czegoś fajnego, takiego jak zombie, broń, umiejętności lub niesamowite kociaki!
Warunki wstępne
Treść
ERC-721 (Ethereum Request for Comments 721), zaproponowany przez Williama Entrikena, Dietera Shirleya, Jacoba Evansa, Nastassia Sachs w styczniu 2018 r. to standard tokenów niewymiennych, który implementuje interfejs API dla tokenów w ramach inteligentnych kontraktów.
Zapewnia funkcje, takie jak transfer tokenów z jednego konta na drugie, uzyskanie aktualnego salda tokenów na koncie, uzyskanie informacji o właścicielu określonego tokena, a także o całkowitej podaży tokena dostępnej w sieci. Poza tym ma również kilka innych funkcji, takich jak zatwierdzanie, że ilość tokenu z konta może być wydana przez konto osób trzecich.
Jeśli inteligentny kontrakt implementuje następujące metody i zdarzenia, można go nazwać kontraktem tokenów niewymiennych ERC-721 , a po wdrożeniu będzie odpowiedzialny za śledzenie utworzonych tokenów w Ethereum.
Od EIP-721:
Metody
1 function balanceOf(address _owner) external view returns (uint256);2 function ownerOf(uint256 _tokenId) external view returns (address);3 function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;4 function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;5 function transferFrom(address _from, address _to, uint256 _tokenId) external payable;6 function approve(address _approved, uint256 _tokenId) external payable;7 function setApprovalForAll(address _operator, bool _approved) external;8 function getApproved(uint256 _tokenId) external view returns (address);9 function isApprovedForAll(address _owner, address _operator) external view returns (bool);10Pokaż wszystkoKopiuj
Wydarzenia
1 event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);2 event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);3 event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);4Kopiuj
Przykłady
Zobaczmy, dlaczego standard jest tak ważny, aby ułatwić nam sprawdza kontraktów z tokenami ERC-721 na Ethereum. Potrzebujemy tylko interfejsu binarnego Umowy (ABI), aby utworzyć interfejs dla każdego tokenu ERC-721. Jak możesz zobaczyć poniżej, użyjemy uproszczonego ABI, aby zmniejszyć złożoność przykładu.
Przykład Web3.py
Najpierw upewnij się, że zainstalowałeś Web3.py bibliotekę Pythona:
1$ pip install web32
1from web3 import Web32from web3.utils.events import get_event_data345w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))67ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # CryptoKitties Contract89acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # CryptoKitties Sales Auction1011# To jest uproszczony interfejs ABI kontraktu ERC-721 NFT.12# It will expose only the methods: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply()13simplified_abi = [14 {15 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}],16 'name': 'balanceOf',17 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],18 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True19 },20 {21 'inputs': [],22 'name': 'name',23 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],24 'stateMutability': 'view', 'type': 'function', 'constant': True25 },26 {27 'inputs': [{'internalType': 'uint256', 'name': 'tokenId', 'type': 'uint256'}],28 'name': 'ownerOf',29 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}],30 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True31 },32 {33 'inputs': [],34 'name': 'symbol',35 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],36 'stateMutability': 'view', 'type': 'function', 'constant': True37 },38 {39 'inputs': [],40 'name': 'totalSupply',41 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],42 'stateMutability': 'view', 'type': 'function', 'constant': True43 },44]4546ck_extra_abi = [47 {48 'inputs': [],49 'name': 'pregnantKitties',50 'outputs': [{'name': '', 'type': 'uint256'}],51 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True52 },53 {54 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],55 'name': 'isPregnant',56 'outputs': [{'name': '', 'type': 'bool'}],57 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True58 }59]6061ck_contract = w3.eth.contract(address=w3.toChecksumAddress(ck_token_addr), abi=simplified_abi+ck_extra_abi)62name = ck_contract.functions.name().call()63symbol = ck_contract.functions.symbol().call()64kitties_auctions = ck_contract.functions.balanceOf(acc_address).call()65print(f"{name} [{symbol}] NFTs in Auctions: {kitties_auctions}")6667pregnant_kitties = ck_contract.functions.pregnantKitties().call()68print(f"{name} [{symbol}] NFTs Pregnants: {pregnant_kitties}")6970# Using the Transfer Event ABI to get info about transferred Kitties.71tx_event_abi = {72 'anonymous': False,73 'inputs': [74 {'indexed': False, 'name': 'from', 'type': 'address'},75 {'indexed': False, 'name': 'to', 'type': 'address'},76 {'indexed': False, 'name': 'tokenId', 'type': 'uint256'}],77 'name': 'Transfer',78 'type': 'event'79}8081# We need the event's signature to filter the logs82event_signature = w3.sha3(text="Transfer(address,address,uint256)").hex()8384logs = w3.eth.getLogs({85 "fromBlock": w3.eth.blockNumber - 120,86 "address": w3.toChecksumAddress(ck_token_addr),87 "topics": [event_signature]88})8990# Notes:91# - 120 blocks is the max range for CloudFlare Provider92# - If you didn't find any Transfer event you can also try to get a tokenId at:93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events94# Click to expand the event's logs and copy its "tokenId" argument9596recent_tx = [get_event_data(tx_event_abi, log)["args"] for log in logs]9798kitty_id = recent_tx[0]['tokenId'] # Paste the "tokenId" here from the link above99is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()100print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}")101Pokaż wszystkoKopiuj
Kontrakt CryptoKitties zawiera kilka ciekawych wydarzeń poza standardowymi.
Sprawdźmy dwa z nich, Pregnant
i Birth
.
1# Używanie ABI zdarzeń Pregnant i Birth w celu uzyskania informacji o nowych kociakach.23ck_extra_events_abi = [4 {5 'anonymous': False,6 'inputs': [7 {'indexed': False, 'name': 'owner', 'type': 'address'},8 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},9 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},10 {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}],11 'name': 'Pregnant',12 'type': 'event'13 },14 {15 'anonymous': False,16 'inputs': [17 {'indexed': False, 'name': 'owner', 'type': 'address'},18 {'indexed': False, 'name': 'kittyId', 'type': 'uint256'},19 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},20 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},21 {'indexed': False, 'name': 'genes', 'type': 'uint256'}],22 'name': 'Birth',23 'type': 'event'24 }]2526# We need the event's signature to filter the logs27ck_event_signatures = [28 w3.sha3(text="Pregnant(address,uint256,uint256,uint256)").hex(),29 w3.sha3(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),30]3132# Here is a Pregnant Event:33# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog34pregnant_logs = w3.eth.getLogs({35 "fromBlock": w3.eth.blockNumber - 120,36 "address": w3.toChecksumAddress(ck_token_addr),37 "topics": [ck_extra_events_abi[0]]38})3940recent_pregnants = [get_event_data(ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]4142# Here is a Birth Event:43# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a44birth_logs = w3.eth.getLogs({45 "fromBlock": w3.eth.blockNumber - 120,46 "address": w3.toChecksumAddress(ck_token_addr),47 "topics": [ck_extra_events_abi[1]]48})4950recent_births = [get_event_data(ck_extra_events_abi[1], log)["args"] for log in birth_logs]51Pokaż wszystkoKopiuj
Popularne NFT
- Etherscan NFT Tracker wyświetla listę najpopularniejszych NFT na Ethereum według wielkości transferów.
- CryptoKitties to gra skoncentrowana wokół rozmnażania, kolekcjonerskiego i słodkich stworzonek – CryptoKitties.
- Sorare to globalna gra piłkarska fantasy, w której możesz zbierać limitowane edycje przedmiotów kolekcjonerskich, zarządzać swoimi zespołami i konkurować o zdobycie nagród.
- Usługa Nazw Ethereum (ENS) oferuje bezpieczny i zdecentralizowany sposób na zajęcie się zasobami w i poza łańcuchem bloków przy użyciu prostych imiona czytelne dla człowieka.
- Unstoppable Domains jest to firma z San Francisco budująca domeny w blockchainach. Domeny blockchainu zastępują adresy kryptowalut nazwami czytelnymi dla człowieka i mogą być używane do włączenia stron odpornych na cenzurę.
- Gods Unchained Cards to TCG w blockchainie Ethereum, który używa NFT do zapewnienia rzeczywistego prawa własności w grze.
Dalsza lektura
- EIP-721: ERC-721 – standard tokenów niewymiennych
- OpenZeppelin – dokumentacja ERC-721
- OpenZeppelin – implementacja ERC-721