Ruka kwenda kwenye maudhui makuu
Change page

Anatomy ya mikataba smart

Ukurasa ulihaririwa mwisho: 23 Februari 2026

Mkataba mzuri ni mpango unaoendeshwa kwenye anwani kwenye Ethereum. Zinajumuisha data na vipengele vinavyoweza kutekeleza unapopokea muamala. Huu hapa ni muhtasari wa kile kinachounda mkataba mzuri.

Mahitaji ya awali

Hakikisha umesoma kuhusu mikataba-erevu kwanza. Hati hii inadhania kuwa tayari unajua lugha za programu kama vile JavaScript au Python.

Data

Data yoyote ya mkataba lazima ipewe eneo: ama kwa storage au memory. Ni gharama kubwa kurekebisha hifadhi katika mkataba mahiri kwa hivyo unahitaji kuzingatia mahali data yako inapaswa kuishi.

Ghala

Data endelevu inajulikana kama hifadhi na inawakilishwa na vigeu vya hali. Thamani hizi huhifadhiwa kabisa kwenye Kiambajengo. Unahitaji kutangaza aina ili mkataba uweze kufuatilia ni kiasi gani cha hifadhi kwenye Kiambajengo inahitaji wakati inapoundwa.

1// Mfano wa Solidity
2contract SimpleStorage {
3 uint storedData; // Kigezo cha Hali
4 // ...
5}
1# Mfano wa Vyper
2storedData: int128

Ikiwa tayari umepanga lugha zinazoelekezwa kwa kitu, kuna uwezekano kwamba utafahamu aina nyingi. Hata hivyo, address inapaswa kuwa mpya kwako ikiwa wewe ni mgeni katika uendelezaji wa Ethereum.

Aina ya address inaweza kushikilia anwani ya Ethereum ambayo ni sawa na baiti 20 au biti 160. Inarudi katika nukuu ya hexadecimal na 0x inayoongoza.

Aina zingine ni pamoja na:

  • boolean
  • nambari kamili
  • nambari za uhakika
  • safu za baiti za ukubwa usiobadilika
  • safu za baiti zenye ukubwa unaobadilika
  • maandishi halisi ya kimantiki na nambari kamili
  • maandishi halisi ya string
  • maandishi halisi ya heksadesimali
  • enums

Kwa maelezo zaidi, angalia hati:

Kumbukumbu

Thamani ambazo huhifadhiwa kwa muda wote wa utendakazi wa kazi ya mkataba huitwa vigeu vya kumbukumbu. Kwa kuwa hizi hazihifadhiwa kwa kudumu kwenye Kiambajengo, ni nafuu sana kutumia.

Jifunze zaidi kuhusu jinsi EVM inavyohifadhi data (Hifadhi, Kumbukumbu, na Stack) katika nyaraka za Solidity (opens in a new tab).

Vigezo vya mazingira

Mbali na vigezo unavyobainisha kwenye mkataba wako, kuna baadhi ya vigezo maalum vya kimataifa. Zinatumika kimsingi kutoa habari kuhusu blockchain au shughuli ya sasa.

Mifano:

SifaKigezo cha HaliMaelezo
block.timestampuint256Muhuri wa wakati wa kipindi cha kizuizi cha sasa
msg.senderanuaniMtumaji wa ujumbe (simu ya sasa)

Kazi

Kwa maneno rahisi zaidi, chaguo za kukokotoa zinaweza kupata taarifa au kuweka taarifa kujibu miamala inayoingia.

Kuna aina mbili za simu za kazi:

  • internal – hizi hazitengenezi simu ya EVM
    • Kazi za ndani na vigezo vya hali vinaweza kufikiwa tu ndani (yaani, kutoka ndani ya mkataba wa sasa au mikataba inayotokana nayo)
  • external – hizi hutengeneza simu ya EVM
    • Kazi za nje ni sehemu ya kiolesura cha mkataba, ambayo ina maana kwamba zinaweza kuitwa kutoka kwa mikataba mingine na kupitia miamala. Kazi ya nje f haiwezi kuitwa ndani (yaani, f() haifanyi kazi, lakini this.f() inafanya kazi).

Pia zinaweza kuwa za umma au faragha

  • kazi za umma zinaweza kuitwa ndani kutoka ndani ya mkataba au nje kupitia ujumbe
  • kazi za faragha zinaonekana tu kwa mkataba ambapo zimefafanuliwa na si katika mikataba inayotokana

Vipengele vyote viwili vya kukokotoa na vigezo vya hali vinaweza kuwekwa hadharani au kwa faragha

Hapa kuna kazi ya kubadilisha utofauti wa hali kwenye mkataba:

1// Mfano wa Solidity
2function update_name(string value) public {
3 dapp_name = value;
4}
  • Kigezo value cha aina ya string kinapitishwa kwenye kazi: update_name
  • Imetangazwa kuwa ya umma, ikimaanisha mtu yeyote anaweza kuifikia
  • Haijatangazwa view, hivyo inaweza kurekebisha hali ya mkataba

Kazi za kutazama

Kazi hizi zinaahidi kutorekebisha hali ya data ya mkataba. Mifano ya kawaida ni vitendaji vya "pata" - unaweza kutumia hii kupokea salio la mtumiaji kwa mfano.

1// Mfano wa Solidity
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

Ni nini kinachozingatiwa hali ya kurekebisha:

  1. Kuandika vigezo kwa hali.
  2. Kutoa matukio (opens in a new tab).
  3. Kuunda mikataba mingine (opens in a new tab).
  4. Kutumia selfdestruct.
  5. Inatuma etha kupitia simu.
  6. Kuita kazi yoyote ambayo haijawekwa alama ya view au pure.
  7. Kutumia simu za kiwango cha chini.
  8. Kutumia mkusanyiko wa ndani ambao una opcodes fulani.

Kazi za kiunda

kazi za kiunda hutekelezwa mara moja tu wakati mkataba unapelekwa kwa mara ya kwanza. Kama constructor katika lugha nyingi za programu za msingi wa darasa, kazi hizi mara nyingi huanzisha vigezo vya hali kwa thamani zake zilizoainishwa.

1// Mfano wa Solidity
2// Huanzisha data ya mkataba, ikiweka `owner`
3// kwa anwani ya muundaji wa mkataba.
4constructor() public {
5 // Mikataba-erevu yote hutegemea miamala ya nje ili kuanzisha kazi zake.
6 // `msg` ni kigezo cha kimataifa ambacho kinajumuisha data husika kwenye muamala uliopewa,
7 // kama vile anwani ya mtumaji na thamani ya ETH iliyojumuishwa kwenye muamala.
8 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
9 owner = msg.sender;
10}
Onyesha yote
1# Mfano wa Vyper
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

Kazi zilizojengewa ndani

Kando na vigezo na chaguo za kukokotoa unazofafanua kwenye mkataba wako, kuna vitendaji maalum vilivyojumuishwa. Mfano dhahiri zaidi ni:

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

Hizi huruhusu kandarasi kutuma ETH kwa akaunti zingine.

Kuandika kazi

Utendaji wako unahitaji:

  • kutofautisha kwa paramu na aina (ikiwa inakubali vigezo)
  • tamko la ndani/nje
  • tamko la mtazamo safi/unaoweza kulipwa
  • inarudisha aina (ikiwa inarudisha thamani)
1pragma solidity >=0.4.0 <=0.6.0;
2
3contract ExampleDapp {
4 string dapp_name; // kigezo cha hali
5
6 // Inaitwa wakati mkataba unapelekwa na kuanzisha thamani
7 constructor() public {
8 dapp_name = "Mfumo wangu mtawanyo wa kimamlaka wa mfano";
9 }
10
11 // Kazi ya Kupata
12 function read_name() public view returns(string) {
13 return dapp_name;
14 }
15
16 // Kazi ya Kuweka
17 function update_name(string value) public {
18 dapp_name = value;
19 }
20}
Onyesha yote

Mkataba kamili unaweza kuonekana kama hii. Hapa kazi ya constructor inatoa thamani ya awali kwa kigezo cha dapp_name.

Matukio na kumbukumbu

Matukio huwezesha mkataba wako mahiri kuwasiliana na eneo lako la mbele au programu zingine za kujisajili. Baada ya muamala kuthibitishwa na kuongezwa kwenye kizuizi, mikataba mahiri inaweza kutoa matukio na kuweka taarifa, ambayo sehemu ya mbele inaweza kuchakata na kutumia.

Mifano yenye maelezo

Hii ni baadhi ya mifano iliyoandikwa katika Solidity. Ikiwa ungependa kucheza na msimbo, unaweza kuingiliana nao katika Remix (opens in a new tab).

Habari dunia

1// Inabainisha toleo la Solidity, kwa kutumia matoleo ya kimantiki.
2// Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
3pragma solidity ^0.5.10;
4
5// Inafafanua mkataba unaoitwa `HelloWorld`.
6// Mkataba ni mkusanyiko wa kazi na data (hali yake).
7// Baada ya kupelekwa, mkataba hukaa kwenye anwani maalum kwenye mnyororo wa bloku wa Ethereum.
8// Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
9contract HelloWorld {
10
11 // Inatangaza kigezo cha hali `message` cha aina ya `string`.
12 // Vigezo vya hali ni vigezo ambavyo thamani zake huhifadhiwa kabisa katika hifadhi ya mkataba.
13 // Neno muhimu `public` hufanya vigezo viweze kufikiwa kutoka nje ya mkataba
14 // na huunda kazi ambayo mikataba mingine au wateja wanaweza kuita ili kufikia thamani.
15 string public message;
16
17 // Sawa na lugha nyingi za programu za kuelekeza-vitu zenye msingi wa darasa, kiunda ni
18 // kazi maalum ambayo inatekelezwa tu wakati wa uundaji wa mkataba.
19 // Viunda hutumika kuanzisha data ya mkataba.
20 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
21 constructor(string memory initMessage) public {
22 // Inakubali hoja ya string `initMessage` na kuweka thamani
23 // kwenye kigezo cha hifadhi cha `message` cha mkataba).
24 message = initMessage;
25 }
26
27 // Kazi ya umma inayokubali hoja ya string
28 // na inasasisha kigezo cha hifadhi cha `message`.
29 function update(string memory newMessage) public {
30 message = newMessage;
31 }
32}
Onyesha yote

Token

1pragma solidity ^0.5.10;
2
3contract Token {
4 // `Anwani` inalinganishwa na anwani ya barua pepe - inatumika kutambua akaunti kwenye Ethereum.
5 // Anwani zinaweza kuwakilisha mkataba-erevu au akaunti za nje (mtumiaji).
6 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/types.html#address
7 address public owner;
8
9 // `mapping` kimsingi ni muundo wa data wa jedwali la hashi.
10 // `mapping` hii inapeana nambari kamili isiyo na alama (salio la tokeni) kwa anwani (mmiliki wa tokeni).
11 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types
12 mapping (address => uint) public balances;
13
14 // Matukio huruhusu uwekaji kumbukumbu wa shughuli kwenye mnyororo wa bloku.
15 // Wateja wa Ethereum wanaweza kusikiliza matukio ili kujibu mabadiliko ya hali ya mkataba.
16 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events
17 event Transfer(address from, address to, uint amount);
18
19 // Huanzisha data ya mkataba, ikiweka `owner`
20 // kwa anwani ya muundaji wa mkataba.
21 constructor() public {
22 // Mikataba-erevu yote hutegemea miamala ya nje ili kuanzisha kazi zake.
23 // `msg` ni kigezo cha kimataifa ambacho kinajumuisha data husika kwenye muamala uliopewa,
24 // kama vile anwani ya mtumaji na thamani ya ETH iliyojumuishwa kwenye muamala.
25 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
26 owner = msg.sender;
27 }
28
29 // Huunda kiasi cha tokeni mpya na kuzituma kwa anwani.
30 function mint(address receiver, uint amount) public {
31 // `require` ni muundo wa udhibiti unaotumika kutekeleza masharti fulani.
32 // Ikiwa taarifa ya `require` itatathminiwa kuwa `false`, ubaguzi husababishwa,
33 // ambayo hubatilisha mabadiliko yote yaliyofanywa kwa hali wakati wa wito wa sasa.
34 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
35
36 // Mmiliki wa mkataba pekee ndiye anayeweza kuita kazi hii
37 require(msg.sender == owner, "Wewe si mmiliki.");
38
39 // Inatekeleza kiasi cha juu cha tokeni
40 require(amount < 1e60, "Utoaji wa juu umezidi");
41
42 // Huongeza salio la `receiver` kwa `amount`
43 balances[receiver] += amount;
44 }
45
46 // Hutuma kiasi cha tokeni zilizopo kutoka kwa mpigaji simu yeyote kwenda kwa anwani.
47 function transfer(address receiver, uint amount) public {
48 // Mtumaji lazima awe na tokeni za kutosha kutuma
49 require(amount <= balances[msg.sender], "Salio halitoshi.");
50
51 // Hurekebisha salio la tokeni za anwani mbili
52 balances[msg.sender] -= amount;
53 balances[receiver] += amount;
54
55 // Hutoa tukio lililofafanuliwa mapema
56 emit Transfer(msg.sender, receiver, amount);
57 }
58}
Onyesha yote

Mali ya kipekee ya kidijitali

1pragma solidity ^0.5.10;
2
3// Huingiza alama kutoka faili zingine kwenye mkataba wa sasa.
4// Katika kesi hii, mfululizo wa mikataba msaidizi kutoka OpenZeppelin.
5// Jifunze zaidi: 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// Neno muhimu `is` hutumika kurithi kazi na maneno muhimu kutoka kwa mikataba ya nje.
13// Katika kesi hii, `CryptoPizza` inarithi kutoka kwa mikataba ya `IERC721` na `ERC165`.
14// Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance
15contract CryptoPizza is IERC721, ERC165 {
16 // Hutumia maktaba ya SafeMath ya OpenZeppelin kufanya shughuli za hesabu kwa usalama.
17 // Jifunze zaidi: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath
18 using SafeMath for uint256;
19
20 // Vigezo vya hali vya kudumu katika Solidity ni sawa na lugha zingine
21 // lakini lazima upeane kutoka kwa usemi ambao ni wa kudumu wakati wa kukusanya.
22 // Jifunze zaidi: 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 // Aina za muundo hukuruhusu kufafanua aina yako mwenyewe
28 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs
29 struct Pizza {
30 string name;
31 uint256 dna;
32 }
33
34 // Huunda safu tupu ya miundo ya Pizza
35 Pizza[] public pizzas;
36
37 // Upangaji kutoka ID ya pizza hadi anwani ya mmiliki wake
38 mapping(uint256 => address) public pizzaToOwner;
39
40 // Upangaji kutoka anwani ya mmiliki hadi idadi ya tokeni inayomilikiwa
41 mapping(address => uint256) public ownerPizzaCount;
42
43 // Upangaji kutoka ID ya tokeni hadi anwani iliyoidhinishwa
44 mapping(uint256 => address) pizzaApprovals;
45
46 // Unaweza kuweka upangaji, mfano huu unapanga mmiliki kwa idhini za mendeshaji
47 mapping(address => mapping(address => bool)) private operatorApprovals;
48
49 // Kazi ya ndani ya kuunda Pizza nasibu kutoka kwa string (jina) na DNA
50 function _createPizza(string memory _name, uint256 _dna)
51 // Neno muhimu `internal` linamaanisha kazi hii inaonekana tu
52 // ndani ya mkataba huu na mikataba inayotokana na mkataba huu
53 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters
54 internal
55 // `isUnique` ni kirekebishaji cha kazi kinachokagua ikiwa pizza tayari ipo
56 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers
57 isUnique(_name, _dna)
58 {
59 // Huongeza Pizza kwenye safu ya Piza na kupata id
60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);
61
62 // Hukagua kwamba mmiliki wa Pizza ni sawa na mtumiaji wa sasa
63 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
64
65 // kumbuka kuwa address(0) ni anwani sifuri,
66 // ikionyesha kuwa pizza[id] bado haijatengewa mtumiaji fulani.
67
68 assert(pizzaToOwner[id] == address(0));
69
70 // Inapanga Pizza kwa mmiliki
71 pizzaToOwner[id] = msg.sender;
72 ownerPizzaCount[msg.sender] = SafeMath.add(
73 ownerPizzaCount[msg.sender],
74 1
75 );
76 }
77
78 // Huunda Pizza nasibu kutoka kwa string (jina)
79 function createRandomPizza(string memory _name) public {
80 uint256 randDna = generateRandomDna(_name, msg.sender);
81 _createPizza(_name, randDna);
82 }
83
84 // Huzalisha DNA nasibu kutoka kwa string (jina) na anwani ya mmiliki (muundaji)
85 function generateRandomDna(string memory _str, address _owner)
86 public
87 // Kazi zilizo na alama ya `pure` huahidi kutosoma au kurekebisha hali
88 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions
89 pure
90 returns (uint256)
91 {
92 // Huzalisha uint nasibu kutoka kwa string (jina) + anwani (mmiliki)
93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +
94 uint256(_owner);
95 rand = rand % dnaModulus;
96 return rand;
97 }
98
99 // Hurudisha safu ya Piza zilizopatikana na mmiliki
100 function getPizzasByOwner(address _owner)
101 public
102 // Kazi zilizo na alama ya `view` huahidi kurekebisha hali
103 // Jifunze zaidi: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions
104 view
105 returns (uint256[] memory)
106 {
107 // Hutumia eneo la hifadhi la `memory` kuhifadhi thamani tu kwa
108 // mzunguko wa maisha wa wito huu wa kazi.
109 // Jifunze zaidi: 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 // Huhamisha Pizza na umiliki kwa anwani nyingine
122 function transferFrom(address _from, address _to, uint256 _pizzaId) public {
123 require(_from != address(0) && _to != address(0), "Anwani batili.");
124 require(_exists(_pizzaId), "Pizza haipo.");
125 require(_from != _to, "Haiwezi kuhamisha kwa anwani ileile.");
126 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Anwani haijaidhinishwa.");
127
128 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);
129 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);
130 pizzaToOwner[_pizzaId] = _to;
131
132 // Hutoa tukio lililofafanuliwa katika mkataba wa IERC721 ulioingizwa
133 emit Transfer(_from, _to, _pizzaId);
134 _clearApproval(_to, _pizzaId);
135 }
136
137 /**
138 * Huhamisha umiliki wa ID ya tokeni fulani kwa usalama kwenda kwa anwani nyingine
139 * Ikiwa anwani lengwa ni mkataba, lazima itekeleze `onERC721Received`,
140 * ambayo inaitwa wakati wa uhamisho salama, na kurudisha thamani ya kichawi
141 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
142 * vinginevyo, uhamisho unabatilishwa.
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 * Huhamisha umiliki wa ID ya tokeni fulani kwa usalama kwenda kwa anwani nyingine
153 * Ikiwa anwani lengwa ni mkataba, lazima itekeleze `onERC721Received`,
154 * ambayo inaitwa wakati wa uhamisho salama, na kurudisha thamani ya kichawi
155 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
156 * vinginevyo, uhamisho unabatilishwa.
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), "Lazima utekeleze onERC721Received.");
166 }
167
168 /**
169 * Kazi ya ndani ya kuita `onERC721Received` kwenye anwani lengwa
170 * Wito hautekelezwi ikiwa anwani lengwa si mkataba
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 // Huchoma Pizza - huharibu Tokeni kabisa
192 // Kirekebishaji cha kazi cha `external` kinamaanisha kazi hii ni
193 // sehemu ya kiolesura cha mkataba na mikataba mingine inaweza kuiita
194 function burn(uint256 _pizzaId) external {
195 require(msg.sender != address(0), "Anwani batili.");
196 require(_exists(_pizzaId), "Pizza haipo.");
197 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Anwani haijaidhinishwa.");
198
199 ownerPizzaCount[msg.sender] = SafeMath.sub(
200 ownerPizzaCount[msg.sender],
201 1
202 );
203 pizzaToOwner[_pizzaId] = address(0);
204 }
205
206 // Hurudisha hesabu ya Piza kwa anwani
207 function balanceOf(address _owner) public view returns (uint256 _balance) {
208 return ownerPizzaCount[_owner];
209 }
210
211 // Hurudisha mmiliki wa Pizza iliyopatikana kwa id
212 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {
213 address owner = pizzaToOwner[_pizzaId];
214 require(owner != address(0), "ID ya Pizza batili.");
215 return owner;
216 }
217
218 // Huidhinisha anwani nyingine kuhamisha umiliki wa Pizza
219 function approve(address _to, uint256 _pizzaId) public {
220 require(msg.sender == pizzaToOwner[_pizzaId], "Lazima uwe mmiliki wa Pizza.");
221 pizzaApprovals[_pizzaId] = _to;
222 emit Approval(msg.sender, _to, _pizzaId);
223 }
224
225 // Hurudisha anwani iliyoidhinishwa kwa Pizza maalum
226 function getApproved(uint256 _pizzaId)
227 public
228 view
229 returns (address operator)
230 {
231 require(_exists(_pizzaId), "Pizza haipo.");
232 return pizzaApprovals[_pizzaId];
233 }
234
235 /**
236 * Kazi ya faragha ya kufuta idhini ya sasa ya ID ya tokeni fulani
237 * Hubatilisha ikiwa anwani iliyotolewa si kweli mmiliki wa tokeni
238 */
239 function _clearApproval(address owner, uint256 _pizzaId) private {
240 require(pizzaToOwner[_pizzaId] == owner, "Lazima uwe mmiliki wa pizza.");
241 require(_exists(_pizzaId), "Pizza haipo.");
242 if (pizzaApprovals[_pizzaId] != address(0)) {
243 pizzaApprovals[_pizzaId] = address(0);
244 }
245 }
246
247 /*
248 * Huweka au huondoa idhini ya mendeshaji fulani
249 * Mendeshaji anaruhusiwa kuhamisha tokeni zote za mtumaji kwa niaba yake
250 */
251 function setApprovalForAll(address to, bool approved) public {
252 require(to != msg.sender, "Haiwezi kuidhinisha anwani mwenyewe");
253 operatorApprovals[msg.sender][to] = approved;
254 emit ApprovalForAll(msg.sender, to, approved);
255 }
256
257 // Husema ikiwa mendeshaji ameidhinishwa na mmiliki fulani
258 function isApprovedForAll(address owner, address operator)
259 public
260 view
261 returns (bool)
262 {
263 return operatorApprovals[owner][operator];
264 }
265
266 // Huchukua umiliki wa Pizza - kwa watumiaji walioidhinishwa pekee
267 function takeOwnership(uint256 _pizzaId) public {
268 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Anwani haijaidhinishwa.");
269 address owner = this.ownerOf(_pizzaId);
270 this.transferFrom(owner, msg.sender, _pizzaId);
271 }
272
273 // Hukagua ikiwa Pizza ipo
274 function _exists(uint256 pizzaId) internal view returns (bool) {
275 address owner = pizzaToOwner[pizzaId];
276 return owner != address(0);
277 }
278
279 // Hukagua ikiwa anwani ni mmiliki au imeidhinishwa kuhamisha Pizza
280 function _isApprovedOrOwner(address spender, uint256 pizzaId)
281 internal
282 view
283 returns (bool)
284 {
285 address owner = pizzaToOwner[pizzaId];
286 // Lemaza ukaguzi wa solium kwa sababu ya
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 // Kagua ikiwa Pizza ni ya kipekee na bado haipo
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, "Pizza yenye jina kama hilo tayari ipo.");
307 _;
308 }
309
310 // Hurudisha ikiwa anwani lengwa ni mkataba
311 function isContract(address account) internal view returns (bool) {
312 uint256 size;
313 // Kwa sasa hakuna njia bora ya kuangalia kama kuna mkataba katika anwani
314 // kuliko kuangalia ukubwa wa msimbo kwenye anwani hiyo.
315 // Tazama https://ethereum.stackexchange.com/a/14016/36603
316 // kwa maelezo zaidi kuhusu jinsi hii inavyofanya kazi.
317 // TODO Kagua hili tena kabla ya toleo la Serenity, kwa sababu anwani zote zitakuwa
318 // mikataba basi.
319 // solium-disable-next-line security/no-inline-assembly
320 assembly {
321 size := extcodesize(account)
322 }
323 return size > 0;
324 }
325}
Onyesha yote

Masomo zaidi

Angalia nyaraka za Solidity na Vyper kwa muhtasari kamili zaidi wa mikataba mahiri:

Je! makala haya yamekusaidia?