Ana içeriğe geç
Change page

ERC-721 Değiştirilemez Token Standardı

Son düzenleme: @kaanmetu(opens in a new tab), 19 Kasım 2023

Giriş

Değiştirilemeyen Token nedir?

Bir Değiştirilemez Token (NFT), bir şeyi veya bir kimseyi eşsiz bir yolla tanımlamak için kullanılır. Bu Token türü; koleksiyon öğeleri, erişim anahtarları, çekiliş biletleri, konserler ve spor maçları için numaralı koltuklar vb. sunan platformlarda kullanılmak için mükemmeldir. Bu özel Token türü, inanılmaz olanaklara sahip olduğu için uygun bir Standardı hak ediyor: ERC-721 bunu çözmek için geldi!

ERC-721 nedir?

ERC-721, NFT için bir standart getirir, başka bir deyişle, bu Token türü benzersizdir ve örneğin yaşı, nadirliği ve hatta görseli gibi başka bir şey nedeniyle aynı Akıllı Sözleşmedeki başka bir Token'dan farklı değere sahip olabilir. Görsel mi?

Evet! Tüm NFT'ler tokenId denilen bir uint256 değişkenine sahiptir, yani herhangi bir ERC-721 sözleşmesi için, sözleşme adresi, uint256 tokenId çifti küresel olarak eşsiz olmalıdır. Bununla birlikte, bir dapp girdi olarak tokenId kullanan ve çıktı olarak da zombiler, silahlar, yetenekler ya da muhteşem kedicikler gibi havalı bir şeyin görüntüsünü veren bir "dönüştürücüye" sahip olabilir!

Ön Koşullar

  • Hesaplar
  • Akıllı Sözleşmeler
  • Token standartları

Şablon

William Entriken, Dieter Shirley, Jacob Evans ve Nastassia Sachs tarafından Ocak 2018'de önerilen ERC-721 (Ethereum Yorum Talebi 721), Akıllı Sözleşmeler içindeki token'lar için bir API uygulayan bir Değiştirilebilir Token Standardıdır.

Token'ları bir hesaptan diğerine aktarmak, bir hesabın mevcut token bakiyesini almak, belirli bir token'ın sahibini almak ve ayrıca ağda mevcut olan token'ın toplam arzını almak gibi işlevler sağlar. Bunların yanı sıra, bir hesaptan bir miktar token'ın üçüncü taraf bir hesap tarafından taşınabileceğini onaylamak gibi başka işlevleri de vardır.

Bir Akıllı Sözleşme aşağıdaki yöntemleri ve olayları uygularsa, ERC-721 Değiştirilemez Token Sözleşmesi olarak adlandırılabilir ve dağıtıldıktan sonra, Ethereum üzerinde oluşturulan token'ları takip etmekten sorumlu olur.

EIP-721(opens in a new tab)'den:

Yöntemler

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);
Tümünü göster
Kopyala

Olaylar

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

Örnekler

Ethereum'daki herhangi bir ERC-721 Token Sözleşmesini incelememizi basitleştirmek için bir Standart'ın ne kadar önemli olduğunu görelim. Herhangi bir ERC-721 token'a arayüz oluşturmak için sadece sözleşmenin Uygulama İkili Arayüzü'ne (ABI) ihtiyacımız var. Aşağıda görebileceğiniz gibi az sürtünmeli bir örnek olması için basitleştirilmiş bir ABI kullanacağız.

Web3.py Örneği

İlk olarak, Web3.py(opens in a new tab) Python kütüphanesini kurduğunuzdan emin olun:

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# 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': 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.to_checksum_address(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# 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}
80
81# We need the event's signature to filter the logs
82event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex()
83
84logs = w3.eth.get_logs({
85 "fromBlock": w3.eth.block_number - 120,
86 "address": w3.to_checksum_address(ck_token_addr),
87 "topics": [event_signature]
88})
89
90# Notes:
91# - Increase the number of blocks up from 120 if no Transfer event is returned.
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
95recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs]
96
97if recent_tx:
98 kitty_id = recent_tx[0]['tokenId'] # Paste the "tokenId" here from the link above
99 is_pregnant = ck_contract.functions.isPregnant(kitty_id).call()
100 print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}")
Tümünü göster
Kopyala

CryptoKitties Sözleşmesi, Standart olanlar dışında bazı ilginç Olaylara sahiptir.

Hadi ikisine bakalım, Pregnant ve Birth.

1# Using the Pregnant and Birth Events ABI to get info about new Kitties.
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.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(),
28 w3.keccak(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.get_logs({
34 "fromBlock": w3.eth.block_number - 120,
35 "address": w3.to_checksum_address(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.get_logs({
44 "fromBlock": w3.eth.block_number - 120,
45 "address": w3.to_checksum_address(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]
Tümünü göster
Kopyala

Daha fazla bilgi

Bu makale yararlı oldu mu?