Anatomi kontrak pintar
Terakhir diedit: , Invalid DateTime
Kontrak pintar adalah program yang dijalankan pada sebuah alamat di Ethereum. Kontrak pintar terbuat dari data dan fungsi yang bisa dieksekusi saat menerima sebuah transaksi. Berikut adalah gambaran umum dari komponen yang menyusun sebuah kontrak pintar.
Prasyarat
Pastikan Anda telah membaca tentang kontrak pintar terlebih dahulu. Dokumen ini menganggap Anda telah terbiasa dengan bahasa pemrograman seperti JavaScript atau Python.
Data
Setiap data kontrak harus ditetapkan ke suatu lokasi: baik ke storage
atau memory
. Untuk memodifikasi penyimpanan di sebuah kontrak pintar biayanya mahal, jadi Anda perlu mempertimbangkan tempat untuk menyimpan data Anda.
Penyimpanan
Data yang persisten dirujuk sebagai penyimpanan dan diwakilkan oleh variabel state. Nilai-nilai ini disimpan secara permanen di blockchain. Anda perlu mendeklarasikan jenisnya sehingga kontrak bisa tetap melacak kapasitas penyimpanan pada blockchain yang diperlukan kontrak ketika dikompilasi.
1// Contoh Solidity2contract SimpleStorage {3 uint storedData; // State variable4 // ...5}6Salin
1# Vyper example2storedData: int1283Salin
Jika Anda telah memprogram bahasa yang berorientasi objek, Anda mungkin akan lebih mengenal sebagian besar jenisnya. Namun address
mungkin terdengar asing jika Anda seorang pengembang pemula di Ethereum.
Suatu jenis address
bisa menampung alamat Ethereum yang setara dengan 20 bita atau 160 bit. Alamat kembali dalam notasi heksadesimal dengan awalan 0x.
Jenis lainnya meliputi:
- boolean
- bilangan bulat
- angka poin tetap
- array bita berukuran tetap
- array bita berukuran dinamis
- Literal rasional dan bilangan bulat
- Literal string
- Literal heksadesimal
- Enum
Untuk penjelasan lebih lanjut, lihat dokumen:
Memori
Nilai yang hanya disimpan selama masa eksekusi fungsi kontrak disebut variabel memori. Karena nilai ini tidak disimpan secara permanen di blockchain, lebih murah untuk digunakan.
Pelajari selengkapnya tentang cara EVM menyimpan data (Penyimpanan, Memori, dan Tumpukan) di dokumen Solidity(opens in a new tab).
Variabel lingkungan
Selain variabel yang Anda tetapkan pada kontrak, ada beberapa variabel global khusus. Variabel ini terutama digunakan untuk memberikan informasi tentang blockchain atau transaksi saat ini.
Contoh:
Prop | Variabel state | Deskripsi |
---|---|---|
block.timestamp | uint256 | Stempel waktu epoch blok saat ini |
msg.sender | alamat | Pengirim pesan (pemanggilan saat ini) |
Fungsi
Dalam istilah yang paling sederhana, fungsi bisa mendapatkan informasi atau mengatur informasi dalam menanggapi transaksi yang masuk.
Ada dua jenis pemanggilan fungsi:
internal
- ini tidak menghasilkan pemanggilan EVM- Fungsi internal dan variabel state hanya bisa diakses secara internal (yaitu dari dalam kontrak saat ini atau kontrak yang diturunkan darinya)
external
- ini menghasilkan pemanggilan EVM- Fungsi eksternal adalah bagian dari antarmuka kontrak, yang berarti bisa dipanggil dari kontrak lain dan melalui transaksi. Fungsi eksternal
f
tidak bisa dipanggil secara internal (yaituf()
tidak berfungsi, tapithis.f()
dapat berfungsi).
- Fungsi eksternal adalah bagian dari antarmuka kontrak, yang berarti bisa dipanggil dari kontrak lain dan melalui transaksi. Fungsi eksternal
Fungsi pemanggilan juga bisa bersifat public
atau private
- Fungsi
public
bisa dipanggil secara internal dari dalam kontrak atau secara eksternal melalui message - Fungsi
private
hanya terlihat untuk kontrak yang ditetapkan di dalam dan bukan dalam kontrak turunan
Kedua fungsi dan variabel state ini bisa dibuat menjadi publik atau privat
Berikut adalah fungsi untuk memperbarui variabel state dalam sebuah kontrak:
1// Contoh Solidity2function update_name(string value) public {3 dapp_name = value;4}5Salin
value
parameter daristring
jenis diteruskan ke dalam fungsi:update_name
- Fungsi dideklarasikan sebagai
public
, berarti siapa pun bisa mengaksesnya - Fungsi tidak dideklarasikan sebagai
view
, sehingga bisa memodifikasi state kontrak
Fungsi view
Fungsi ini berjanji untuk tidak memodifikasi state dari data kontrak. Contoh umumnya adalah fungsi "pengambil" – Anda mungkin menggunakan ini untuk mendapatkan saldo pengguna sebagai contohnya.
1// Contoh Solidity2function balanceOf(address _owner) public view returns (uint256 _balance) {3 return ownerPizzaCount[_owner];4}5Salin
1dappName: public(string)23@view4@public5def readName() -> string:6 return dappName7Salin
Apa yang dianggap sebagai memodifikasi state:
- Menulis ke dalam variabel state.
- Menerbitkan aksi(opens in a new tab).
- Membuat kontrak lain(opens in a new tab).
- Menggunakan
selfdestruct
. - Mengirim eter melalui panggilan.
- Memanggil fungsi apa pun yang tidak bertanda
view
ataupure
. - Menggunakan pemanggilan level rendah.
- Menggunakan perakitan sebaris yang berisi opcode tertentu.
Fungsi pembangun
Fungsi constructor
hanya dijalankan sekali saat kontrak digunakan untuk pertama kalinya. Seperti constructor
di banyak bahasa pemrograman berbasis kelas, fungsi ini sering menjalankan variabel state sesuai dengan nilai yang telah ditentukan.
1// Contoh Solidity2// Jalankan data kontrak, siapkan `owner`3// sesuai dengan alamat dari pembuat kontrak.4constructor() public {5 // Semua kontrak pintar bergantung pada transaksi eksternal untuk memicu fungsinya.6 // `msg` adalah sebuah variabel global yang mencakup data relevan sesuai dengan transaksi yang telah disiapkan,7 // seperti alamat dari pengirim dan nilai ETH yang termasuk dalam transaksi.8 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties9 owner = msg.sender;10}11Tampilkan semuaSalin
1# contoh Vyper23@external4def __init__(_beneficiary: address, _bidding_time: uint256):5 self.beneficiary = _beneficiary6 self.auctionStart = block.timestamp7 self.auctionEnd = self.auctionStart + _bidding_time8Salin
Fungsi bawaan
Selain dari variabel dan fungsi yang Anda tetapkan pada kontrak Anda, ada beberapa fungsi bawaan spesial. Contoh paling jelas adalah:
address.send()
– Soliditysend(address)
– Vyper
Ini memungkinkan kontrak untuk mengirim ETH ke akun lain.
Menulis fungsi
Fungsi Anda memerlukan:
- variabel dan tipe parameter (jika fungsi menerima parameter)
- deklarasi internal/eksternal
- deklarasi pure/view/payable
- tipe pengembalian (jika fungsi mengembalikan nilai)
1pragma solidity >=0.4.0 <=0.6.0;23kontrak ExampleDapp {4 string dapp_name; // state variable56 // Dipanggil saat kontrak disebarkan dan jalankan nilai7 constructor() public {8 dapp_name = "My Example dapp";9 }1011 // Fungsi Get12 function read_name() public view returns(string) {13 return dapp_name;14 }1516 // Tetapkan Fungsi17 function update_name(string value) public {18 dapp_name = value;19 }20}21Tampilkan semuaSalin
Sebuah kontrak lengkap mungkin tampak seperti ini. Di sini, fungsi constructor
menyediakan nilai awal untuk variabel dapp_name
.
Aksi dan log
Aksi memungkinkan Anda berkomunikasi dengan kontrak pintar dari frontend Anda atau aplikasi berbayar lainnya. Ketika sebuah transaksi ditambang, kontrak pintar bisa menerbitkan aksi dan menulis log pada blockchain yang kemudian dapat diproses frontend.
Contoh dengan anotasi
Ini adalah beberapa contoh yang ditulis dalam Solidity. Jika Anda ingin bermain dengan kode tersebut, Anda dapat berinteraksi dengannya di Remix(opens in a new tab).
Hello world
1// Tentukan versi Solidity, gunakan pembuatan versi semantik.2// Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma3pragma solidity ^0.5.10;45// Tentukan sebuah kontak bernama `HaloDunia`.6// Satu kontrak adalah koleksi dari fungsi dan data (statenya).7// Setelah disebarkan, sebuah kontrak tinggal di alamat spesifik pada blockchain Ethereum.8// Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html9contract HelloWorld {1011 // Deklarasikan `message` variabel state dari `string` tipe.12 // Variabel state adalah variabel yang nilainya secara permanen disimpan dalam penyimpanan kontrak.13 // Kata kunci `public` membuat variabel dapat diakses dari luar kontrak14 //dan menciptakan fungsi yang dengannya kontrak atau klien lain bisa memanggil untuk mengakses nilai.15 string public message;1617 // Sama seperti banyak bahasa berorientasi objek yang berbasis kelas, sebuah pembangun adalah18 // sebuah fungsi spesial yang hanya dieksekusi saat pembuatan kontrak.19 // Pembangun digunakan untuk menjalankan data kontrak.20 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors21 constructor(string memory initMessage) public {22 // Menerima satu argumen string `initMessage` dan tetapkan nilai23 // ke dalam variabel penyimpanan `message` kontrak).24 message = initMessage;25 }2627 // Sebuah fungsi publik yang menerima argumen string28 // dan memperbarui variabel penyimpanan `message`.29 function update(string memory newMessage) public {30 message = newMessage;31 }32}33Tampilkan semuaSalin
Token
1pragma solidity ^0.5.10;23contract Token {4 //Sebuah `address` dapat disamakan dengan sebuah alamat email - ia digunakan untuk mengidentifikasi sebuah akun di Ethereum.5 // Alamat bisa mewakilkan sebuah kontrak pintar atau satu akun (pengguna) eksternal.6 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/types.html#address7 address public owner;89 // Sebuah `mapping` adalah satu struktur data tabel hash.10 // `mapping` ini menetapkan sebuah integer yang tidak ditentukan (saldo token) pada sebuah alamat (pemilik token).11 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types12 mapping (address => uint) public balances;1314 // Aksi memungkinkan logging aktivitas pada blockchain.15 // Klien Ethereum bisa mendengarkan aksi untuk bereaksi dengan perubahan state kontrak.16 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events17 event Transfer(address from, address to, uint amount);1819 // Jalankan data kontrak, siapkan `owner`20 // di alamat dari pembuat kontrak.21 constructor() public {22 // Semua kontrak pintar bergantung pada transaksi eksternal untuk memicu fungsinya.23 // `msg` adalah sebuah variabel global yang telah mencakup data relevan sesuai dengan transaksi yang telah disiapkan,24 // seperti alamat dari pengirim dan nilai ETH yang termasuk dalam transaksi.25 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties26 owner = msg.sender;27 }2829 // Membuat sejumlah token baru dan mengirimkan mereka ke satu alamat.30 function mint(address receiver, uint amount) public {31 // `require` is struktur kontrol yang digunakan untuk melaksanakan kondisi tertentu.32 // Jika sebuah pernyataan `require` mengevaluasi ke `false`, satu pengecualian terpicu,33 // yang membalikkan semua perubahan yang dibuat pada state selama pemanggilan saat ini.34 //Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions3536 // Hanya pemilik kontrak yang bisa memanggil fungsi ini37 require(msg.sender == owner, "You are not the owner.");3839 // Melaksanakan sejumlah maksimum token40 require(amount < 1e60, "Maximum issuance exceeded");4142 // Meningkatkan saldo dari `receiver` dalam `amount`43 balances[receiver] += amount;44 }4546 // Mengirim sejumlah token yang ada dari pemanggil manapun ke satu alamat.47 function transfer(address receiver, uint amount) public {48 // Pengirim harus punya token cukup untuk mengirim49 require(amount <= balances[msg.sender], "Insufficient balance.");5051 // Sesuaikan saldo token dari dua alamat52 balances[msg.sender] -= amount;53 balances[receiver] += amount;5455 // Terbitkan aksi yang telah ditentukan sebelumnya56 emit Transfer(msg.sender, receiver, amount);57 }58}59Tampilkan semuaSalin
Aset digital unik
1pragma solidity ^0.5.10;23// Impor simbol dari berkas lain ke dalam kontrak saat ini.4// Dalam kasus ini, sejumlah kontrak penolong dari OpenZeppelin.5// Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files67import "../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";1112// Kata kunci `is` digunakan untuk mewarisi fungsi dan kata kunci dari kontrak eksternal.13// Dalam kasus ini, `CryptoPizza` mewarisi dari kontrak `IERC721` dan `ERC165`.14// Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance15contract CryptoPizza is IERC721, ERC165 {16 // Gunakan pustaka Safe Math OpenZeppelin untuk melakukan operasi aritmatika dengan aman.17 // Pelajari lebih banyak: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath18 using SafeMath for uint256;1920 // Variabel state konstan di Solidity sama dengan bahasa lainnya21 // tapi Anda harus menetapkan satu ekpresi yang konstan pada waktu pengompilasian.22 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables23 uint256 constant dnaDigits = 10;24 uint256 constant dnaModulus = 10 ** dnaDigits;25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;2627 // Tipe Struct memungkinkan Anda menentukan tipe Anda28 //Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs29 struct Pizza {30 string name;31 uint256 dna;32 }3334 // Buat satu array kosong dari struct Pizza35 Pizza[] public pizzas;3637 // Mapping dari ID pizza ke alamat pemiliknya38 mapping(uint256 => address) public pizzaToOwner;3940 // Mapping dari alamat pemilik ke nomor dari token yang dimiliki41 mapping(address => uint256) public ownerPizzaCount;4243 // Mapping dari ID token ke alamat yang disetujui44 mapping(uint256 => address) pizzaApprovals;4546 // Anda bisa melakukan nest pada mapping, contoh ini melakukan map ke persetujuan operator47 mapping(address => mapping(address => bool)) private operatorApprovals;4849 // Fungsi internal untuk membentuk satu Pizza acak dari (nama) string dan DNA50 function _createPizza(string memory _name, uint256 _dna)51 // Kata kunci `internal` berarti fungsi ini hanya terlihat52 // dalam kontrak ini dan kontrak yang diturunkan dari kontrak ini53 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters54 internal55 // `isUnique` adalah satu fungsi modifier yang memeriksa apakah pizza sudah ada56 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers57 isUnique(_name, _dna)58 {59 // Menambahkan Pizza ke array dari Pizza dan mendapatkan id60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);6162 // Periksa pemilik Pizza sama dengan pengguna saat ini63 // Learn more: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions64 assert(pizzaToOwner[id] == address(0));6566 // Lakukan map pada Pizza ke pemiliknya67 pizzaToOwner[id] = msg.sender;68 ownerPizzaCount[msg.sender] = SafeMath.add(69 ownerPizzaCount[msg.sender],70 171 );72 }7374 // Buat satu Pizza acak dari (nama) string75 function createRandomPizza(string memory _name) public {76 uint256 randDna = generateRandomDna(_name, msg.sender);77 _createPizza(_name, randDna);78 }7980 // Hasilkan DNA acak dari (nama) string dan alamat dari pemilik (pembuat)81 function generateRandomDna(string memory _str, address _owner)82 public83 // Fungsi yang ditandai `pure` berjanji tidak membaca dari atau memodifikasi state84 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions85 pure86 returns (uint256)87 {88 // Buat uint acak dari (nama) string + (pemilik) alamat89 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +90 uint256(_owner);91 rand = rand % dnaModulus;92 return rand;93 }9495 // Kembalikan array Pizza yang ditemukan pemilik96 function getPizzasByOwner(address _owner)97 public98 // Fungsi yang ditandai `view` berjanji tidak memodifikasi state99 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions100 view101 returns (uint256[] memory)102 {103 // Gunakan lokasi penyimpanan `memory` untuk menyimpan nilai hanya untuk104 // siklus hidup dari pemanggilan fungsi ini.105 // Pelajari lebih banyak: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack106 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);107 uint256 counter = 0;108 for (uint256 i = 0; i < pizzas.length; i++) {109 if (pizzaToOwner[i] == _owner) {110 result[counter] = i;111 counter++;112 }113 }114 return result;115 }116117 // Mentransfer Pizza dan kepemilikan ke alamat lain118 function transferFrom(address _from, address _to, uint256 _pizzaId) public {119 require(_from != address(0) && _to != address(0), "Invalid address.");120 require(_exists(_pizzaId), "Pizza does not exist.");121 require(_from != _to, "Cannot transfer to the same address.");122 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");123124 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);125 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);126 pizzaToOwner[_pizzaId] = _to;127128 // Terbitkan aksi yang ditentukan di kontrak IERC721 yang diimpor129 emit Transfer(_from, _to, _pizzaId);130 _clearApproval(_to, _pizzaId);131 }132133 /**134 * Transfer dengan aman kepemilikan dari ID token yang disediakan ke alamat lain135 * Jika alamat target adalah sebuah kontrak, ia harus mengimplementasi ``onERC721Received`,136 * yang dipanggil saat satu transfer aman, dan mengembalikan nilai ajaib137 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;138 * jika tidak, transfer dibalikkan.139 */140 function safeTransferFrom(address from, address to, uint256 pizzaId)141 public142 {143 // solium-disable-next-line arg-overflow144 this.safeTransferFrom(from, to, pizzaId, "");145 }146147 /**148 * Transfer dengan aman kepemilikan dari ID token yang disediakan ke alamat lain149 * Jika alamat target adalah satu kontrak, ia harus mengimplementasi `onERC721Received`,150 * yang dipanggil saat satu transfer aman, dan mengembalikan nilai ajaib151 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;152 * jika tidak, transfer dibalikkan.153 */154 function safeTransferFrom(155 address from,156 address to,157 uint256 pizzaId,158 bytes memory _data159 ) public {160 this.transferFrom(from, to, pizzaId);161 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implmement onERC721Received.");162 }163164 /**165 * Fungsi internal untuk memohon `onERC721Received` pada satu alamat target166 * Pemanggilan tidak dieksekusi jika alamat target bukan sebuah kontrak167 */168 function _checkOnERC721Received(169 address from,170 address to,171 uint256 pizzaId,172 bytes memory _data173 ) internal returns (bool) {174 if (!isContract(to)) {175 return true;176 }177178 bytes4 retval = IERC721Receiver(to).onERC721Received(179 msg.sender,180 from,181 pizzaId,182 _data183 );184 return (retval == _ERC721_RECEIVED);185 }186187 // Bakar satu Pizza - hancurkan Token secara total188 // Modifier fungsi `external` berarti fungsi ini adalah189 // bagian dari antarmuka kontrak dan kontrak lain bisa memanggilnya190 function burn(uint256 _pizzaId) external {191 require(msg.sender != address(0), "Invalid address.");192 require(_exists(_pizzaId), "Pizza does not exist.");193 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");194195 ownerPizzaCount[msg.sender] = SafeMath.sub(196 ownerPizzaCount[msg.sender],197 1198 );199 pizzaToOwner[_pizzaId] = address(0);200 }201202 // Kembalikan penghitungan Pizza lewat alamat203 function balanceOf(address _owner) public view returns (uint256 _balance) {204 return ownerPizzaCount[_owner];205 }206207 // Kembalikan pemilik Pizza yang ditemukan id208 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {209 address owner = pizzaToOwner[_pizzaId];210 require(owner != address(0), "Invalid Pizza ID.");211 return owner;212 }213214 // Setujui alamat lain untuk mentransfer kepemilikan Pizza215 function approve(address _to, uint256 _pizzaId) public {216 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");217 pizzaApprovals[_pizzaId] = _to;218 emit Approval(msg.sender, _to, _pizzaId);219 }220221 // Kembalikan alamat yang disetujui untuk Pizza spesifik222 function getApproved(uint256 _pizzaId)223 public224 view225 returns (address operator)226 {227 require(_exists(_pizzaId), "Pizza does not exist.");228 return pizzaApprovals[_pizzaId];229 }230231 /**232 * Fungsi privat untuk menghapus persetujuan saat ini dari ID token yang disediakan233 * Balikkan jika alamat yang disediakan memang bukan pemilik token234 */235 function _clearApproval(address owner, uint256 _pizzaId) private {236 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");237 require(_exists(_pizzaId), "Pizza does not exist.");238 if (pizzaApprovals[_pizzaId] != address(0)) {239 pizzaApprovals[_pizzaId] = address(0);240 }241 }242243 /*244 * Siapkan atau batalkan persetujuan untuk operator yang disediakan245 * Seorang operator diizinkan untuk mentransfer semua token dari pengirim atas nama mereka246 */247 function setApprovalForAll(address to, bool approved) public {248 require(to != msg.sender, "Cannot approve own address");249 operatorApprovals[msg.sender][to] = approved;250 emit ApprovalForAll(msg.sender, to, approved);251 }252253 // Beritahu apakah seorang operator disetujui oleh seorang pemilik yang disediakan254 function isApprovedForAll(address owner, address operator)255 public256 view257 returns (bool)258 {259 return operatorApprovals[owner][operator];260 }261262 // Ambil kepemilikan Pizza - hanya untuk pengguna yang disetujui263 function takeOwnership(uint256 _pizzaId) public {264 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");265 address owner = this.ownerOf(_pizzaId);266 this.transferFrom(owner, msg.sender, _pizzaId);267 }268269 // Periksa apakah Pizza ada270 function _exists(uint256 pizzaId) internal view returns (bool) {271 address owner = pizzaToOwner[pizzaId];272 return owner != address(0);273 }274275 // Periksa apakah alamat adalah pemilik atau disetujui untuk mentransfer Pizza276 function _isApprovedOrOwner(address spender, uint256 pizzaId)277 internal278 view279 returns (bool)280 {281 address owner = pizzaToOwner[pizzaId];282 // Disable solium check because of283 // https://github.com/duaraghav8/Solium/issues/175284 // solium-disable-next-line operator-whitespace285 return (spender == owner ||286 this.getApproved(pizzaId) == spender ||287 this.isApprovedForAll(owner, spender));288 }289290 // Periksa apakah Pizza unik dan belum ada sama sekali291 modifier isUnique(string memory _name, uint256 _dna) {292 bool result = true;293 for (uint256 i = 0; i < pizzas.length; i++) {294 if (295 keccak256(abi.encodePacked(pizzas[i].name)) ==296 keccak256(abi.encodePacked(_name)) &&297 pizzas[i].dna == _dna298 ) {299 result = false;300 }301 }302 require(result, "Pizza with such name already exists.");303 _;304 }305306 // Kembalikan apakah alamat target adalah sebuah kontrak307 function isContract(address account) internal view returns (bool) {308 uint256 size;309 // Currently there is no better way to check if there is a contract in an address310 // than to check the size of the code at that address.311 // Kunjungi https://ethereum.stackexchange.com/a/14016/36603312 // untuk lebih banyak detail tentang bagaimana ini bekerja.313 // UNTUK DILAKUKAN Periksa ini lagi sebelum pelepasan Serenity, karena semua alamat akan menjadi314 // kontrak kemudian.315 // solium-disable-next-line security/no-inline-assembly316 assembly {317 size := extcodesize(account)318 }319 return size > 0;320 }321}322Tampilkan semuaSalin
Bacaan lebih lanjut
Lihat dokumentasi Solidity dan Vyper untuk gambaran umum yang lebih lengkap tentang kontrak pintar:
Topik terkait
Tutorial terkait
- Memperkecil kontrak untuk mengatasi batas ukuran kontrak – Beberapa tips praktis untuk mengurangi ukuran kontrak pintar Anda.
- Pembuatan log data dari kontrak pintar dengan aksi – Pengantar aksi kontrak pintar dan cara menggunakannya untuk log data.
- Berinteraksi dengan kontrak lain dari Solidity – Cara menggunakan kontrak pintar dari kontrak yang sudah ada dan berinteraksi dengan kontrak pintar tersebut.