Ana içeriğe geç
Change page

Akıllı sözleşmelerin anatomisi

Sayfanın son güncellenmesi: 23 Şubat 2026

Bir akıllı sözleşme Ethereum üzerindeki bir adreste çalışan bir programdır. Bir işlem alındığında yürütülebilen fonksiyonlar ve verilerden oluşurlar. Burada bir akıllı sözleşmenin nelerden oluştuğu hakkında genel bir bakış bulunmaktadır.

Ön Koşullar

Önce akıllı sözleşmeler hakkında bilgi edindiğinizden emin olun. Bu belge, hâlihazırda JavaScript veya Python gibi programlama dillerine aşina olduğunuzu varsayar.

Veri

Herhangi bir sözleşme verisi bir konuma atanmalıdır: ya storage ya da memory. Bir akıllı sözleşmede depolamayı değiştirmek pahalıdır, bundan dolayı verinizin nerede yaşayacağını düşünmelisiniz.

Depolama

Kalıcı veriden depolama olarak bahsedilir ve durum değişkenleri tarafından temsil edilir. Bu değerler kalıcı olarak blok zincirinde depolanır. Sözleşmenin derlendiğinde blok zincirinde ne kadar depolama ihtiyacı duyacağını takip edebilmesi için türünü deklare etmelisiniz.

1// Solidity örneği
2contract SimpleStorage {
3 uint storedData; // Durum değişkeni
4 // ...
5}
1# Vyper örneği
2storedData: int128

Hâlihazırda nesne odaklı dillerde programlama yaptıysanız, büyük ihtimalle çoğu türe aşinasınızdır. Ancak, Ethereum geliştirmede yeniyseniz address sizin için yeni olmalıdır.

Bir address türü, 20 bayt veya 160 bite eşdeğer bir Ethereum adresi tutabilir. Önünde 0x olan onaltılık gösterim şeklinde döndürür.

Diğer türler:

  • boolean
  • tam sayı
  • sabit noktalı sayılar
  • sabit boyutlu bayt dizileri
  • dinamik olarak boyutlandırılmış bayt dizileri
  • rasyonel ve tam sayı değişmezleri
  • metin değişmezleri
  • onaltılık değişmezler
  • enum'lar

Daha fazla açıklama için belgelere göz atın:

Bellek

Sadece bir sözleşme fonksiyonunun yürütümü esnasında depolanan değerlere bellek değişkenleri denir. Bunlar blok zincirinde kalıcı şekilde depolanmadıkları için kullanımları çok daha ucuzdur.

EVM'nin verileri nasıl depoladığı (Depolama, Bellek ve Yığın) hakkında daha fazla bilgiyi Solidity belgelerinden (opens in a new tab) edinin.

Ortam değişkenleri

Sözleşmenizde tanımladığınız değişkenlere ek olarak, bazı özel global değişkenler bulunmaktadır. Başlıca blok zinciri veya mevcut işlem hakkında bilgi sağlamak için kullanılırlar.

Örnekler:

ÖzellikDurum değişkeniAçıklama
block.timestampuint256Mevcut blok dönemi zaman damgası
msg.senderadresMesajın göndericisi (mevcut çağrı)

Fonksiyonlar

En basit şekilde, fonksiyonlar gelen işlemlere yanıt olarak bilgi alabilir veya düzenleyebilir.

İki tip fonksiyon çağrısı bulunur:

  • internal – bunlar bir EVM çağrısı oluşturmaz
    • Dahili fonksiyonlara ve durum değişkenlerine yalnızca dahili olarak erişilebilir (yani mevcut sözleşmenin içinden veya ondan türetilen sözleşmelerden)
  • external – bunlar bir EVM çağrısı oluşturur
    • External fonksiyonlar sözleşme arayüzünün bir parçasıdır, bu da diğer sözleşmelerden ve işlemler aracılığıyla çağrılabilecekleri anlamına gelir. Harici bir f fonksiyonu dahili olarak çağrılamaz (yani f() çalışmaz, ancak this.f() çalışır).

Ayrıca public veya private olabilirler

  • public fonksiyonlar, sözleşme içinden dahili olarak veya mesajlar aracılığıyla harici olarak çağrılabilir
  • private fonksiyonlar yalnızca tanımlandıkları sözleşme için görünürdür ve türetilmiş sözleşmelerde görünmezler

Hem fonksiyonlar hem de durum değişkenleri public veya private yapılabilir

Burada bir sözleşmedeki bir durum değişkenini güncellemek için bir fonksiyon bulunmaktadır:

1// Solidity örneği
2function update_name(string value) public {
3 dapp_name = value;
4}
  • string türündeki value parametresi, update_name fonksiyonuna geçirilir
  • public olarak bildirilmiştir, yani herkes erişebilir
  • view olarak bildirilmemiştir, bu nedenle sözleşme durumunu değiştirebilir

Görünüm fonksiyonları

Bu fonksiyonlar sözleşmenin verisinin durumunu değiştirmemeye söz verirler. Yaygın örnekler "alıcı" fonksiyonlardır – örnek olarak bunu bir kullanıcının bakiyesini almak için kullanabilirsiniz.

1// Solidity örneği
2function balanceOf(address _owner) public view returns (uint256 _balance) {
3 return ownerPizzaCount[_owner];
4}
1dappName: public(string)
2
3@view
4@public
5def readName() -> string:
6 return dappName

Durumu değiştirme olarak sayılan şeyler:

  1. Değişkenlikleri belirtmek için yazma.
  2. Olayları yayma (opens in a new tab).
  3. Diğer sözleşmeleri oluşturma (opens in a new tab).
  4. selfdestruct kullanma.
  5. Çağrılar aracılığıyla ether gönderme.
  6. view veya pure olarak işaretlenmemiş herhangi bir fonksiyonu çağırma.
  7. Alt düzey çağrıları kullanma.
  8. Belirli işlem kodları içeren satır içi tümleşkeler kullanma.

Yapıcı fonksiyonlar

constructor fonksiyonları yalnızca sözleşme ilk kez dağıtıldığında bir kez yürütülür. Birçok sınıf tabanlı programlama dilindeki constructor gibi, bu fonksiyonlar da genellikle durum değişkenlerini belirtilen değerlere başlatır.

1// Solidity örneği
2// Sözleşmenin verilerini başlatır, `owner`'ı
3// sözleşmeyi oluşturanın adresine ayarlar.
4constructor() public {
5 // Tüm akıllı sözleşmeler, fonksiyonlarını tetiklemek için harici işlemlere güvenir.
6 // `msg`, gönderenin adresi ve işlemde yer alan ETH değeri gibi
7 // belirli bir işlemle ilgili verileri içeren genel bir değişkendir.
8 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
9 owner = msg.sender;
10}
Tümünü göster
1# Vyper örneği
2
3@external
4def __init__(_beneficiary: address, _bidding_time: uint256):
5 self.beneficiary = _beneficiary
6 self.auctionStart = block.timestamp
7 self.auctionEnd = self.auctionStart + _bidding_time

Yerleşik fonksiyonlar

Sözleşmenizde tanımladığınız değişkenler ve fonksiyonlara ek olarak, bazı özel yerleşik fonksiyonlar bulunmaktadır. En bariz örnek şudur:

  • address.send() – Solidity
  • send(address) – Vyper

Bunlar sözleşmelerin başka hesaplara ETH göndermesini sağlar.

Fonksiyon yazma

Fonksiyonunuz şunlara ihtiyaç duyar:

  • parametre değişkeni ve türü (eğer parametre kabul ediyorsa)
  • internal/external deklarasyonu
  • pure/view/payable deklarasyonu
  • dönüş türü (eğer bir değer döndürüyorsa)
1pragma solidity >=0.4.0 <=0.6.0;
2
3contract ExampleDapp {
4 string dapp_name; // durum değişkeni
5
6 // Sözleşme dağıtıldığında çağrılır ve değeri başlatır
7 constructor() public {
8 dapp_name = "My Example dapp";
9 }
10
11 // Get Fonksiyonu
12 function read_name() public view returns(string) {
13 return dapp_name;
14 }
15
16 // Set Fonksiyonu
17 function update_name(string value) public {
18 dapp_name = value;
19 }
20}
Tümünü göster

Tam bir sözleşme bu şekilde gözükebilir. Burada constructor fonksiyonu, dapp_name değişkeni için bir başlangıç değeri sağlar.

Olaylar ve günlükler

Olaylar, akıllı sözleşmelerinizin ön yüzünüz ya da diğer abonelik uygulamalarınızla iletişime geçebilmesini sağlar. Bir işlem doğrulandıktan ve bir bloğa eklendikten sonra akıllı sözleşmeler, ön ucun daha sonra işleyebileceği ve kullanabileceği olayları ve günlük bilgilerini yayabilir.

Açıklamalı örnekler

Bunlar Solidity ile yazılmış bazı örneklerdir. Kodla oynamak isterseniz, Remix (opens in a new tab) üzerinde onlarla etkileşime girebilirsiniz.

Merhaba dünya

1// Anlamsal sürüm oluşturmayı kullanarak Solidity sürümünü belirtir.
2// Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
3pragma solidity ^0.5.10;
4
5// `HelloWorld` adında bir sözleşme tanımlar.
6// Bir sözleşme, fonksiyonlar ve verilerden (durumundan) oluşan bir koleksiyondur.
7// Dağıtıldıktan sonra, bir sözleşme Ethereum blokzincirinde belirli bir adreste bulunur.
8// Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
9contract HelloWorld {
10
11 // `string` türünde bir `message` durum değişkeni bildirir.
12 // Durum değişkenleri, değerleri kalıcı olarak sözleşme depolama alanında saklanan değişkenlerdir.
13 // `public` anahtar kelimesi, değişkenleri bir sözleşmenin dışından erişilebilir hale getirir
14 // ve diğer sözleşmelerin veya istemcilerin değere erişmek için çağırabileceği bir fonksiyon oluşturur.
15 string public message;
16
17 // Birçok sınıf tabanlı nesne yönelimli dilde olduğu gibi, bir yapıcı
18 // yalnızca sözleşme oluşturulduğunda yürütülen özel bir fonksiyondur.
19 // Yapıcılar, sözleşmenin verilerini başlatmak için kullanılır.
20 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
21 constructor(string memory initMessage) public {
22 // Bir `initMessage` dize bağımsız değişkenini kabul eder ve değeri
23 // sözleşmenin `message` depolama değişkenine ayarlar).
24 message = initMessage;
25 }
26
27 // Bir dize bağımsız değişkenini kabul eden
28 // ve `message` depolama değişkenini güncelleyen genel bir fonksiyon.
29 function update(string memory newMessage) public {
30 message = newMessage;
31 }
32}
Tümünü göster

Jeton

1pragma solidity ^0.5.10;
2
3contract Token {
4 // Bir `address` bir e-posta adresine benzer; Ethereum'da bir hesabı tanımlamak için kullanılır.
5 // Adresler bir akıllı sözleşmeyi veya harici (kullanıcı) hesapları temsil edebilir.
6 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/types.html#address
7 address public owner;
8
9 // Bir `mapping` aslında bir karma tablo veri yapısıdır.
10 // Bu `mapping`, işaretsiz bir tam sayıyı (jeton bakiyesi) bir adrese (jeton sahibi) atar.
11 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types
12 mapping (address => uint) public balances;
13
14 // Olaylar, blokzincirindeki etkinliğin günlüğe kaydedilmesine olanak tanır.
15 // Ethereum istemcileri, sözleşme durumu değişikliklerine tepki vermek için olayları dinleyebilir.
16 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events
17 event Transfer(address from, address to, uint amount);
18
19 // Sözleşmenin verilerini başlatır, `owner`'ı
20 // sözleşmeyi oluşturanın adresine ayarlar.
21 constructor() public {
22 // Tüm akıllı sözleşmeler, fonksiyonlarını tetiklemek için harici işlemlere güvenir.
23 // `msg`, gönderenin adresi ve işlemde yer alan ETH değeri gibi
24 // belirli bir işlemle ilgili verileri içeren genel bir değişkendir.
25 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
26 owner = msg.sender;
27 }
28
29 // Yeni jetonlar oluşturur ve bunları bir adrese gönderir.
30 function mint(address receiver, uint amount) public {
31 // `require`, belirli koşulları zorlamak için kullanılan bir kontrol yapısıdır.
32 // Bir `require` ifadesi `false` olarak değerlendirilirse, bir istisna tetiklenir,
33 // bu da mevcut çağrı sırasında durumda yapılan tüm değişiklikleri geri alır.
34 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
35
36 // Bu fonksiyonu yalnızca sözleşme sahibi çağırabilir
37 require(msg.sender == owner, "Sahip siz değilsiniz.");
38
39 // Maksimum jeton miktarını zorlar
40 require(amount < 1e60, "Maksimum ihraç aşıldı");
41
42 // `receiver` bakiyesini `amount` kadar artırır
43 balances[receiver] += amount;
44 }
45
46 // Herhangi bir çağırandan bir adrese mevcut jeton miktarını gönderir.
47 function transfer(address receiver, uint amount) public {
48 // Gönderenin göndermek için yeterli jetonu olmalıdır
49 require(amount <= balances[msg.sender], "Yetersiz bakiye.");
50
51 // İki adresin jeton bakiyelerini ayarlar
52 balances[msg.sender] -= amount;
53 balances[receiver] += amount;
54
55 // Daha önce tanımlanan olayı yayar
56 emit Transfer(msg.sender, receiver, amount);
57 }
58}
Tümünü göster

Benzersiz dijital varlık

1pragma solidity ^0.5.10;
2
3// Diğer dosyalardan sembolleri mevcut sözleşmeye aktarır.
4// Bu durumda, OpenZeppelin'den bir dizi yardımcı sözleşme.
5// Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files
6
7import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
8import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
9import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";
10import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";
11
12// `is` anahtar kelimesi, harici sözleşmelerden fonksiyonları ve anahtar kelimeleri miras almak için kullanılır.
13// Bu durumda `CryptoPizza`, `IERC721` ve `ERC165` sözleşmelerinden miras alır.
14// Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance
15contract CryptoPizza is IERC721, ERC165 {
16 // Aritmetik işlemleri güvenli bir şekilde gerçekleştirmek için OpenZeppelin'in SafeMath kütüphanesini kullanır.
17 // Daha fazlasını öğrenin: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath
18 using SafeMath for uint256;
19
20 // Solidity'deki sabit durum değişkenleri diğer dillere benzer
21 // ancak derleme zamanında sabit olan bir ifadeden atama yapmanız gerekir.
22 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables
23 uint256 constant dnaDigits = 10;
24 uint256 constant dnaModulus = 10 ** dnaDigits;
25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
26
27 // Struct türleri kendi türünüzü tanımlamanızı sağlar
28 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs
29 struct Pizza {
30 string name;
31 uint256 dna;
32 }
33
34 // Pizza yapılarından oluşan boş bir dizi oluşturur
35 Pizza[] public pizzas;
36
37 // Pizza kimliğinden sahibinin adresine eşleme
38 mapping(uint256 => address) public pizzaToOwner;
39
40 // Sahibin adresinden sahip olunan jeton sayısına eşleme
41 mapping(address => uint256) public ownerPizzaCount;
42
43 // Jeton kimliğinden onaylanmış adrese eşleme
44 mapping(uint256 => address) pizzaApprovals;
45
46 // Eşlemeleri iç içe kullanabilirsiniz, bu örnek sahibi operatör onaylarıyla eşler
47 mapping(address => mapping(address => bool)) private operatorApprovals;
48
49 // Dizeden (ad) ve DNA'dan rastgele bir Pizza oluşturmak için dahili fonksiyon
50 function _createPizza(string memory _name, uint256 _dna)
51 // `internal` anahtar kelimesi, bu fonksiyonun yalnızca
52 // bu sözleşme ve bu sözleşmeyi türeten sözleşmeler içinde görünür olduğu anlamına gelir
53 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters
54 internal
55 // `isUnique`, pizzanın zaten var olup olmadığını kontrol eden bir fonksiyon değiştiricisidir
56 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers
57 isUnique(_name, _dna)
58 {
59 // Pizza'yı Pizza dizisine ekler ve kimliği alır
60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);
61
62 // Pizza sahibinin mevcut kullanıcıyla aynı olup olmadığını kontrol eder
63 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
64
65 // address(0)'ın sıfır adresi olduğunu unutmayın,
66 // pizza[id]'nin henüz belirli bir kullanıcıya atanmadığını gösterir.
67
68 assert(pizzaToOwner[id] == address(0));
69
70 // Pizza'yı sahibine eşler
71 pizzaToOwner[id] = msg.sender;
72 ownerPizzaCount[msg.sender] = SafeMath.add(
73 ownerPizzaCount[msg.sender],
74 1
75 );
76 }
77
78 // Dizeden (ad) rastgele bir Pizza oluşturur
79 function createRandomPizza(string memory _name) public {
80 uint256 randDna = generateRandomDna(_name, msg.sender);
81 _createPizza(_name, randDna);
82 }
83
84 // Dizeden (ad) ve sahibinin adresinden (oluşturan) rastgele DNA oluşturur
85 function generateRandomDna(string memory _str, address _owner)
86 public
87 // `pure` olarak işaretlenmiş fonksiyonlar durumu okumama veya değiştirmeme sözü verir
88 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions
89 pure
90 returns (uint256)
91 {
92 // Dizeden (ad) + adresten (sahip) rastgele uint oluşturur
93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +
94 uint256(_owner);
95 rand = rand % dnaModulus;
96 return rand;
97 }
98
99 // Sahibe göre bulunan Pizza dizisini döndürür
100 function getPizzasByOwner(address _owner)
101 public
102 // `view` olarak işaretlenmiş fonksiyonlar durumu değiştirmeme sözü verir
103 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions
104 view
105 returns (uint256[] memory)
106 {
107 // Değerleri yalnızca bu fonksiyon çağrısının
108 // yaşam döngüsü için saklamak üzere `memory` depolama konumunu kullanır.
109 // Daha fazlasını öğrenin: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack
110 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);
111 uint256 counter = 0;
112 for (uint256 i = 0; i < pizzas.length; i++) {
113 if (pizzaToOwner[i] == _owner) {
114 result[counter] = i;
115 counter++;
116 }
117 }
118 return result;
119 }
120
121 // Pizza'yı ve sahipliğini başka bir adrese aktarır
122 function transferFrom(address _from, address _to, uint256 _pizzaId) public {
123 require(_from != address(0) && _to != address(0), "Geçersiz adres.");
124 require(_exists(_pizzaId), "Pizza mevcut değil.");
125 require(_from != _to, "Aynı adrese transfer yapılamaz.");
126 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Adres onaylı değil.");
127
128 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);
129 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);
130 pizzaToOwner[_pizzaId] = _to;
131
132 // İçe aktarılan IERC721 sözleşmesinde tanımlanan olayı yayar
133 emit Transfer(_from, _to, _pizzaId);
134 _clearApproval(_to, _pizzaId);
135 }
136
137 /**
138 * Belirli bir jeton kimliğinin sahipliğini başka bir adrese güvenli bir şekilde aktarır
139 * Hedef adres bir sözleşme ise `onERC721Received` uygulamalıdır,
140 * bu, güvenli bir aktarım üzerine çağrılır ve sihirli değeri döndürür
141 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
142 * aksi takdirde, aktarım geri alınır.
143 */
144 function safeTransferFrom(address from, address to, uint256 pizzaId)
145 public
146 {
147 // solium-disable-next-line arg-overflow
148 this.safeTransferFrom(from, to, pizzaId, "");
149 }
150
151 /**
152 * Belirli bir jeton kimliğinin sahipliğini başka bir adrese güvenli bir şekilde aktarır
153 * Hedef adres bir sözleşme ise `onERC721Received` uygulamalıdır,
154 * bu, güvenli bir aktarım üzerine çağrılır ve sihirli değeri döndürür
155 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
156 * aksi takdirde, aktarım geri alınır.
157 */
158 function safeTransferFrom(
159 address from,
160 address to,
161 uint256 pizzaId,
162 bytes memory _data
163 ) public {
164 this.transferFrom(from, to, pizzaId);
165 require(_checkOnERC721Received(from, to, pizzaId, _data), "onERC721Received uygulanmalıdır.");
166 }
167
168 /**
169 * Hedef bir adreste `onERC721Received`'i çağırmak için dahili fonksiyon
170 * Hedef adres bir sözleşme değilse çağrı yürütülmez
171 */
172 function _checkOnERC721Received(
173 address from,
174 address to,
175 uint256 pizzaId,
176 bytes memory _data
177 ) internal returns (bool) {
178 if (!isContract(to)) {
179 return true;
180 }
181
182 bytes4 retval = IERC721Receiver(to).onERC721Received(
183 msg.sender,
184 from,
185 pizzaId,
186 _data
187 );
188 return (retval == _ERC721_RECEIVED);
189 }
190
191 // Bir Pizza'yı yakar - Jetonu tamamen yok eder
192 // `external` fonksiyon değiştiricisi, bu fonksiyonun
193 // sözleşme arayüzünün bir parçası olduğu ve diğer sözleşmelerin onu çağırabileceği anlamına gelir
194 function burn(uint256 _pizzaId) external {
195 require(msg.sender != address(0), "Geçersiz adres.");
196 require(_exists(_pizzaId), "Pizza mevcut değil.");
197 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Adres onaylı değil.");
198
199 ownerPizzaCount[msg.sender] = SafeMath.sub(
200 ownerPizzaCount[msg.sender],
201 1
202 );
203 pizzaToOwner[_pizzaId] = address(0);
204 }
205
206 // Adrese göre Pizza sayısını döndürür
207 function balanceOf(address _owner) public view returns (uint256 _balance) {
208 return ownerPizzaCount[_owner];
209 }
210
211 // Kimliğe göre bulunan Pizza'nın sahibini döndürür
212 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {
213 address owner = pizzaToOwner[_pizzaId];
214 require(owner != address(0), "Geçersiz Pizza Kimliği.");
215 return owner;
216 }
217
218 // Pizza sahipliğini devretmek için başka bir adresi onaylar
219 function approve(address _to, uint256 _pizzaId) public {
220 require(msg.sender == pizzaToOwner[_pizzaId], "Pizza sahibi olmalısınız.");
221 pizzaApprovals[_pizzaId] = _to;
222 emit Approval(msg.sender, _to, _pizzaId);
223 }
224
225 // Belirli Pizza için onaylanmış adresi döndürür
226 function getApproved(uint256 _pizzaId)
227 public
228 view
229 returns (address operator)
230 {
231 require(_exists(_pizzaId), "Pizza mevcut değil.");
232 return pizzaApprovals[_pizzaId];
233 }
234
235 /**
236 * Belirli bir jeton kimliğinin mevcut onayını temizlemek için özel fonksiyon
237 * Verilen adres gerçekten jetonun sahibi değilse geri alınır
238 */
239 function _clearApproval(address owner, uint256 _pizzaId) private {
240 require(pizzaToOwner[_pizzaId] == owner, "Pizza sahibi olmalısınız.");
241 require(_exists(_pizzaId), "Pizza mevcut değil.");
242 if (pizzaApprovals[_pizzaId] != address(0)) {
243 pizzaApprovals[_pizzaId] = address(0);
244 }
245 }
246
247 /*
248 * Belirli bir operatörün onayını ayarlar veya kaldırır
249 * Bir operatörün, gönderenin tüm jetonlarını kendi adına transfer etmesine izin verilir
250 */
251 function setApprovalForAll(address to, bool approved) public {
252 require(to != msg.sender, "Kendi adresinizi onaylayamazsınız");
253 operatorApprovals[msg.sender][to] = approved;
254 emit ApprovalForAll(msg.sender, to, approved);
255 }
256
257 // Bir operatörün belirli bir sahip tarafından onaylanıp onaylanmadığını söyler
258 function isApprovedForAll(address owner, address operator)
259 public
260 view
261 returns (bool)
262 {
263 return operatorApprovals[owner][operator];
264 }
265
266 // Pizza'nın sahipliğini alır - yalnızca onaylı kullanıcılar için
267 function takeOwnership(uint256 _pizzaId) public {
268 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Adres onaylı değil.");
269 address owner = this.ownerOf(_pizzaId);
270 this.transferFrom(owner, msg.sender, _pizzaId);
271 }
272
273 // Pizza'nın var olup olmadığını kontrol eder
274 function _exists(uint256 pizzaId) internal view returns (bool) {
275 address owner = pizzaToOwner[pizzaId];
276 return owner != address(0);
277 }
278
279 // Adresin sahip olup olmadığını veya Pizza'yı transfer etme yetkisi olup olmadığını kontrol eder
280 function _isApprovedOrOwner(address spender, uint256 pizzaId)
281 internal
282 view
283 returns (bool)
284 {
285 address owner = pizzaToOwner[pizzaId];
286 // Solium kontrolünü devre dışı bırak, çünkü
287 // https://github.com/duaraghav8/Solium/issues/175
288 // solium-disable-next-line operator-whitespace
289 return (spender == owner ||
290 this.getApproved(pizzaId) == spender ||
291 this.isApprovedForAll(owner, spender));
292 }
293
294 // Pizza'nın benzersiz olup olmadığını ve henüz mevcut olup olmadığını kontrol edin
295 modifier isUnique(string memory _name, uint256 _dna) {
296 bool result = true;
297 for (uint256 i = 0; i < pizzas.length; i++) {
298 if (
299 keccak256(abi.encodePacked(pizzas[i].name)) ==
300 keccak256(abi.encodePacked(_name)) &&
301 pizzas[i].dna == _dna
302 ) {
303 result = false;
304 }
305 }
306 require(result, "Bu isimde bir pizza zaten var.");
307 _;
308 }
309
310 // Hedef adresin bir sözleşme olup olmadığını döndürür
311 function isContract(address account) internal view returns (bool) {
312 uint256 size;
313 // Şu anda bir adreste sözleşme olup olmadığını kontrol etmenin, o adresteki kodun boyutunu kontrol etmekten daha iyi bir yolu yoktur.
314 // Bunun nasıl çalıştığı hakkında daha fazla ayrıntı için
315 // bkz. https://ethereum.stackexchange.com/a/14016/36603.
316 // TODO Serenity sürümünden önce bunu tekrar kontrol edin, çünkü o zaman tüm adresler
317 // sözleşme olacak.
318 // solium-disable-next-line security/no-inline-assembly
319 assembly {
320 size := extcodesize(account)
321 }
322 return size > 0;
323 }
324}
Tümünü göster

Daha fazla kaynak

Akıllı sözleşmelere daha detaylı bir genel bakış için Solidity ve Vyper'ın belgelerine bakın:

Bu makale yararlı oldu mu?