Weiter zum Hauptinhalt
Change page

ERC-721 Nicht-fungibler Token-Standard

Letzte Änderung: @rxchard(opens in a new tab), 19. November 2023

Einführung

Was ist ein nicht-fungibler Token?

Ein nicht-fungibler Token (NFT) wird verwendet, um etwas oder jemanden auf eine einzigartige Weise zu identifizieren. Diese Art von Token ist perfekt, um auf Plattformen verwendet zu werden, die Sammelartikel anbieten, Zugang zu Schlüsseln, Lotteriekarten, nummerierten Plätzen für Konzerte und Sportspiele, etc. Diese spezielle Art von Token hat erstaunliche Möglichkeiten, so dass er einen angemessenen Standard verdient. Der ERC-721 hat dies gelöst!

Was ist ERC-721?

Der ERC-721 führt eine Norm für NFT ein, mit anderen Worten, diese Art von Token ist einzigartig und kann einen anderen Wert haben als ein anderer Token des gleichen Smart Contract, vielleicht wegen seines Alters, seiner Seltenheit oder auch so etwas wie sein visuelles Bild. Moment mal, visuell?

Ja! Alle NFTs haben eine uint256 Variable namens TokenId und bei jedem ERC-721 Contract muss das Paar aus Kontaktadresse uint256 TokenId global eindeutig sein. Eine dApp kann einen „Konverter" haben, der die TokenId als Eingabe verwendet und ein Bild von etwas Coolem ausgibt, wie Zombies, Waffen, Fertigkeiten oder Krypto-Kitties!

Voraussetzungen

  • Konten
  • Smart Contracts
  • Token-Standards

Hauptteil

Der ERC-721 (Ethereum Request for Comments 721), im Januar 2018 von William Entriken, Dieter Shirley, Jacob Evans und Nastassia Sachs vorgeschlagen, ist ein nicht-fungibler Token-Standard, der eine API für Tokens innerhalb von Smart Contracts implementiert.

Er bietet Funktionen wie die Übertragung von Token von einem Konto auf ein anderes, um den aktuellen Token-Saldo eines Kontos, den Eigentümer eines spezifischen Tokens sowie den Gesamtbestand der im Netzwerk verfügbaren Token abzurufen. Daneben gibt es auch einige andere Funktionalitäten wie zum Beispiel zu genehmigen, dass eine gewisse Menge an Token von einem Konto von einem Drittkonto verschoben werden kann.

Wenn ein Smart Contract folgende Methoden und Ereignisse implementiert, kann er als ERC-721 nicht-fungibler Token-Vertrag bezeichnet werden. Einmal implementiert, werden mit ihm die erstellten Token auf Ethereum verfolgt.

Aus EIP-721(opens in a new tab):

Methoden

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);
Alles anzeigen
Kopieren

Events

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);
Kopieren

Beispiele

Lassen Sie uns sehen, wie wichtig ein Standard ist, um es uns einfach zu machen, jeden ERC-721 Token-Vertrag auf Ethereum zu inspizieren. Wir benötigen nur das Application Binary Interface (ABI) des Vertrags, um eine Schnittstelle zu jedem ERC-721 Token zu erstellen. Wie Sie unten sehen können, werden wir ein vereinfachtes ABI verwenden, um es zu einem Beispiel mit geringer Reibung zu machen.

Web3.py Beispiel

Stellen Sie zuerst sicher, dass Sie Web3.py(opens in a new tab) Python-Bibliothek installiert haben:

1pip install web3
1from web3 import Web3
2from web3._utils.events import get_event_data
3
4
5w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com"))
6
7ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # CryptoKitties Contract
8
9acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # CryptoKitties Sales Auction
10
11# This is a simplified Contract Application Binary Interface (ABI) of an ERC-721 NFT Contract.
12# Es werden nur folgende Methoden betrachtet: 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': True
19 },
20 {
21 'inputs': [],
22 'name': 'name',
23 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
24 'stateMutability': 'view', 'type': 'function', 'constant': True
25 },
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': True
31 },
32 {
33 'inputs': [],
34 'name': 'symbol',
35 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}],
36 'stateMutability': 'view', 'type': 'function', 'constant': True
37 },
38 {
39 'inputs': [],
40 'name': 'totalSupply',
41 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}],
42 'stateMutability': 'view', 'type': 'function', 'constant': True
43 },
44]
45
46ck_extra_abi = [
47 {
48 'inputs': [],
49 'name': 'pregnantKitties',
50 'outputs': [{'name': '', 'type': 'uint256'}],
51 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
52 },
53 {
54 'inputs': [{'name': '_kittyId', 'type': 'uint256'}],
55 'name': 'isPregnant',
56 'outputs': [{'name': '', 'type': 'bool'}],
57 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True
58 }
59]
60
61ck_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}")
66
67pregnant_kitties = ck_contract.functions.pregnantKitties().call()
68print(f"{name} [{symbol}] NFTs Pregnants: {pregnant_kitties}")
69
70# Nutzung des Transfer Event ABI um Informationen über übertragene Kitties zu erhalten.
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}
80
81# We need the event's signature to filter the logs
82event_signature = w3.sha3(text="Transfer(address,address,uint256)").hex()
83
84logs = w3.eth.getLogs({
85 "fromBlock": w3.eth.blockNumber - 120,
86 "address": w3.toChecksumAddress(ck_token_addr),
87 "topics": [event_signature]
88})
89
90# Notes:
91# - 120 blocks is the max range for CloudFlare Provider
92# - If you didn't find any Transfer event you can also try to get a tokenId at:
93# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events
94# Click to expand the event's logs and copy its "tokenId" argument
95
96recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]
97
98kitty_id = recent_tx[0]['tokenId'] # Paste the "tokenId" here from the link above
99is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()
100print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}")
Alles anzeigen
Kopieren

Der Krypto-Kitties-Vertrag hat neben den Standard-Events noch einige weitere interessante Events.

Lassen Sie uns zwei dieser Events genauer ansehen, Schwanger und Geburt.

1# Verwendung des Pregnant und Birth Events ABI um Informationen über neue Kitties zu erhalten.
2ck_extra_events_abi = [
3 {
4 'anonymous': False,
5 'inputs': [
6 {'indexed': False, 'name': 'owner', 'type': 'address'},
7 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
8 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
9 {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}],
10 'name': 'Pregnant',
11 'type': 'event'
12 },
13 {
14 'anonymous': False,
15 'inputs': [
16 {'indexed': False, 'name': 'owner', 'type': 'address'},
17 {'indexed': False, 'name': 'kittyId', 'type': 'uint256'},
18 {'indexed': False, 'name': 'matronId', 'type': 'uint256'},
19 {'indexed': False, 'name': 'sireId', 'type': 'uint256'},
20 {'indexed': False, 'name': 'genes', 'type': 'uint256'}],
21 'name': 'Birth',
22 'type': 'event'
23 }]
24
25# We need the event's signature to filter the logs
26ck_event_signatures = [
27 w3.sha3(text="Pregnant(address,uint256,uint256,uint256)").hex(),
28 w3.sha3(text="Birth(address,uint256,uint256,uint256,uint256)").hex(),
29]
30
31# Here is a Pregnant Event:
32# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog
33pregnant_logs = w3.eth.getLogs({
34 "fromBlock": w3.eth.blockNumber - 120,
35 "address": w3.toChecksumAddress(ck_token_addr),
36 "topics": [ck_event_signatures[0]]
37})
38
39recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs]
40
41# Here is a Birth Event:
42# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a
43birth_logs = w3.eth.getLogs({
44 "fromBlock": w3.eth.blockNumber - 120,
45 "address": w3.toChecksumAddress(ck_token_addr),
46 "topics": [ck_event_signatures[1]]
47})
48
49recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs]
Alles anzeigen
Kopieren

Weiterführende Informationen

War dieser Artikel hilfreich?