Solidity - Panduan Cepat
Solidity adalah bahasa pemrograman tingkat tinggi yang berorientasi pada kontrak untuk menerapkan kontrak pintar. Soliditas sangat dipengaruhi oleh C ++, Python, dan JavaScript, dan telah dirancang untuk menargetkan Ethereum Virtual Machine (EVM).
Soliditas diketik secara statis, mendukung pewarisan, pustaka, dan bahasa pemrograman jenis yang ditentukan pengguna yang kompleks.
Anda dapat menggunakan Solidity untuk membuat kontrak untuk penggunaan seperti pemungutan suara, crowdfunding, lelang buta, dan dompet multi-tanda tangan.
Apa itu Ethereum?
Ethereum adalah mis. Terdesentralisasi. platform blockchain yang menjalankan kontrak pintar yaitu aplikasi yang berjalan persis seperti yang diprogram tanpa kemungkinan downtime, sensor, penipuan, atau campur tangan pihak ketiga.
Mesin Virtual Ethereum (EVM)
Mesin Virtual Ethereum, juga dikenal sebagai EVM, adalah lingkungan runtime untuk kontrak pintar di Ethereum. Mesin Virtual Ethereum berfokus pada penyediaan keamanan dan mengeksekusi kode yang tidak tepercaya oleh komputer di seluruh dunia.
EVM mengkhususkan diri dalam mencegah serangan Denial-of-service dan memastikan bahwa program tidak memiliki akses ke status masing-masing, memastikan komunikasi dapat terjalin tanpa potensi gangguan.
Mesin Virtual Ethereum telah dirancang untuk berfungsi sebagai lingkungan runtime untuk kontrak pintar berdasarkan Ethereum.
Apa itu Kontrak Cerdas?
Kontrak pintar adalah protokol komputer yang dimaksudkan untuk memfasilitasi, memverifikasi, atau menegakkan negosiasi atau kinerja kontrak secara digital. Kontrak pintar memungkinkan kinerja transaksi yang kredibel tanpa pihak ketiga. Transaksi ini dapat dilacak dan tidak dapat diubah.
Konsep kontrak pintar pertama kali diusulkan oleh Nick Szabo pada tahun 1994. Szabo adalah seorang sarjana hukum dan kriptografer yang dikenal karena meletakkan dasar untuk mata uang digital.
Tidak apa-apa jika Anda tidak memahami Kontrak Cerdas saat ini, kami akan membahas lebih detail nanti.
Bab ini menjelaskan bagaimana kita dapat mengatur kompiler Soliditas pada mesin CentOS. Jika Anda tidak memiliki mesin Linux, Anda dapat menggunakan Kompiler Online kami untuk kontrak kecil dan untuk mempelajari Soliditas dengan cepat.
Metode 1 - npm / Node.js
Ini adalah cara tercepat untuk menginstal kompiler Solidity di Mesin CentoS Anda. Kami memiliki langkah-langkah berikut untuk menginstal Solidity Compiler -
Instal Node.js
Pertama, pastikan Anda memiliki node.js yang tersedia di mesin CentOS Anda. Jika tidak tersedia, instal menggunakan perintah berikut -
# First install epel-release
$sudo yum install epel-release
# Now install nodejs
$sudo yum install nodejs
# Next install npm (Nodejs Package Manager )
$sudo yum install npm
# Finally verify installation
$npm --version
Jika semuanya telah diinstal maka Anda akan melihat output seperti ini -
3.10.10
Instal solc
Setelah Anda menginstal manajer paket Node.js, Anda dapat melanjutkan untuk menginstal kompiler Solidity seperti di bawah ini -
$sudonpm install -g solc
Perintah di atas akan menginstal program solcjs dan membuatnya tersedia secara global di seluruh sistem. Sekarang Anda dapat menguji kompiler Solidity Anda dengan mengeluarkan perintah berikut -
$solcjs-version
Jika semuanya berjalan dengan baik, maka ini akan mencetak sesuatu sebagai berikut -
0.5.2+commit.1df8f40c.Emscripten.clang
Sekarang Anda siap menggunakan solcjs yang memiliki fitur lebih sedikit daripada kompiler Solidity standar tetapi ini akan memberi Anda titik awal yang baik.
Metode 2 - Gambar Docker
Anda dapat menarik image Docker dan mulai menggunakannya untuk memulai dengan pemrograman Solidity. Berikut langkah-langkah sederhananya. Berikut adalah perintah untuk menarik Solidity Docker Image.
$docker pull ethereum/solc:stable
Setelah gambar buruh pelabuhan diunduh, kita dapat memverifikasinya menggunakan perintah berikut.
$docker run ethereum/solc:stable-version
Ini akan mencetak sesuatu sebagai berikut -
$ docker run ethereum/solc:stable -version
solc, the solidity compiler commandlineinterfaceVersion: 0.5.2+commit.1df8f40c.Linux.g++
Metode 3: Instalasi Paket Biner
Jika Anda ingin menginstal kompilator lengkap di mesin Linux Anda, silakan periksa situs web resmi Menginstal Kompilator Soliditas.
File sumber Solidity dapat berisi sejumlah definisi kontrak, arahan impor, dan arahan pragma.
Mari kita mulai dengan file sumber Solidity sederhana. Berikut adalah contoh file Solidity -
pragma solidity >=0.4.0 <0.6.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
Pragma
Baris pertama adalah petunjuk pragma yang memberi tahu bahwa kode sumber ditulis untuk Solidity versi 0.4.0 atau yang lebih baru yang tidak merusak fungsionalitas hingga, tetapi tidak termasuk, versi 0.6.0.
Arahan pragma selalu lokal ke file sumber dan jika Anda mengimpor file lain, pragma dari file itu tidak akan secara otomatis diterapkan ke file yang mengimpor.
Jadi pragma untuk file yang tidak akan dikompilasi lebih awal dari versi 0.4.0 dan juga tidak akan bekerja pada kompiler mulai dari versi 0.5.0 akan ditulis sebagai berikut -
pragma solidity ^0.4.0;
Di sini kondisi kedua ditambahkan dengan menggunakan ^.
Kontrak
Kontrak Soliditas adalah kumpulan kode (fungsinya) dan data (statusnya) yang berada di alamat tertentu di Ethereumblockchain.
Baris uintstoredData mendeklarasikan variabel status yang disebut storedData bertipe uint dan fungsi yang disetel serta get dapat digunakan untuk mengubah atau mengambil nilai variabel.
Mengimpor File
Meskipun contoh di atas tidak memiliki pernyataan impor tetapi Soliditas mendukung pernyataan impor yang sangat mirip dengan yang tersedia di JavaScript.
Pernyataan berikut mengimpor semua simbol global dari "nama file".
import "filename";
Contoh berikut membuat symbolName simbol global baru yang anggotanya semua simbol global dari "filename".
import * as symbolName from "filename";
Untuk mengimpor file x dari direktori yang sama dengan file saat ini, gunakan import "./x" sebagai x ;. Jika Anda menggunakan import "x" sebagai x; sebaliknya, file yang berbeda dapat direferensikan dalam "direktori penyertaan" global.
Kata Kunci yang Dicadangkan
Berikut adalah kata kunci yang dipesan di Solidity -
abstrak | setelah | alias | menerapkan |
mobil | kasus | menangkap | salinan dari |
default | menetapkan | terakhir | kekal |
mengimplementasikan | di | Di barisan | membiarkan |
makro | pertandingan | yg mungkin berubah | batal |
dari | mengesampingkan | sebagian | janji |
referensi | bisa direlokasi | tertutup | ukuran dari |
statis | mendukung | beralih | mencoba |
typedef | jenis | tidak dicentang |
Kami menggunakan Remix IDE untuk Mengkompilasi dan Menjalankan basis Kode Soliditas kami.
Step 1 - Salin kode yang diberikan di Bagian Kode IDE Remix.
Contoh
pragma solidity ^0.5.0;
contract SolidityTest {
constructor() public{
}
function getResult() public view returns(uint){
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}
}
Step 2 - Di bawah Tab Kompilasi, klik Start to Compile tombol.
Step 3 - Di bawah Run Tab, klik Deploy tombol.
Step 4 - Di bawah Run Tab, Pilih SolidityTest at 0x... di drop-down.
Step 5 - Klik getResult Tombol untuk menampilkan hasilnya.
Keluaran
0: uint256: 3
Soliditas mendukung komentar bergaya C dan gaya C ++, Jadi -
Teks apa pun antara // dan akhir baris diperlakukan sebagai komentar dan diabaikan oleh Solidity Compiler.
Teks apa pun di antara karakter / * dan * / diperlakukan sebagai komentar. Ini mungkin mencakup beberapa baris.
Contoh
Contoh berikut memperlihatkan bagaimana menggunakan komentar di Solidity.
function getResult() public view returns(uint){
// This is a comment. It is similar to comments in C++
/*
* This is a multi-line comment in solidity
* It is very similar to comments in C Programming
*/
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}
Saat menulis program dalam bahasa apa pun, Anda perlu menggunakan berbagai variabel untuk menyimpan berbagai informasi. Variabel hanyalah lokasi memori yang dicadangkan untuk menyimpan nilai. Ini berarti bahwa ketika Anda membuat variabel, Anda menyediakan beberapa ruang di memori.
Anda mungkin ingin menyimpan informasi dari berbagai tipe data seperti karakter, karakter lebar, integer, floating point, double floating point, boolean dll. Berdasarkan tipe data variabel, sistem operasi mengalokasikan memori dan memutuskan apa yang dapat disimpan di memori yang dipesan.
Jenis Nilai
Solidity menawarkan programmer beragam tipe data bawaan serta yang ditentukan pengguna. Tabel berikut mencantumkan tujuh tipe data C ++ dasar -
Tipe | Kata kunci | Nilai |
---|---|---|
Boolean | bool | benar salah |
Bilangan bulat | int / uint | Bilangan bulat bertanda tangan dan tak bertanda tangan dengan berbagai ukuran. |
Bilangan bulat | int8 sampai int256 | Ditandatangani int dari 8 bit menjadi 256 bit. int256 sama dengan int. |
Bilangan bulat | uint8 hingga uint256 | Int unsigned dari 8 bit hingga 256 bit. uint256 sama dengan uint. |
Nomor Poin Tetap | tetap / tidak tetap | Nomor titik tetap bertanda tangan dan tidak bertanda tangan dengan berbagai ukuran. |
Nomor Poin Tetap | tetap / tidak tetap | Nomor titik tetap bertanda tangan dan tidak bertanda tangan dengan berbagai ukuran. |
Nomor Poin Tetap | fixedMxN | Nomor titik tetap yang ditandatangani di mana M mewakili jumlah bit yang diambil berdasarkan jenis dan N mewakili titik desimal. M harus habis dibagi 8 dan berubah dari 8 menjadi 256. N bisa dari 0 sampai 80. tetap sama seperti tetap128x18. |
Nomor Poin Tetap | ufixedMxN | Nomor titik tetap tak bertanda di mana M mewakili jumlah bit yang diambil berdasarkan jenis dan N mewakili titik desimal. M harus habis dibagi 8 dan berubah dari 8 menjadi 256. N bisa dari 0 sampai 80. ufixed sama dengan ufixed128x18. |
alamat
alamat memegang nilai 20 byte yang mewakili ukuran alamat Ethereum. Sebuah alamat dapat digunakan untuk mendapatkan saldo menggunakan metode .balance dan dapat digunakan untuk mentransfer saldo ke alamat lain menggunakan metode .transfer.
address x = 0x212;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
Soliditas mendukung tiga jenis variabel.
State Variables - Variabel yang nilainya disimpan secara permanen dalam penyimpanan kontrak.
Local Variables - Variabel yang nilainya ada hingga fungsi dijalankan.
Global Variables - Variabel khusus ada di namespace global yang digunakan untuk mendapatkan informasi tentang blockchain.
Soliditas adalah bahasa yang diketik secara statis, yang berarti bahwa tipe variabel negara bagian atau lokal perlu ditentukan selama deklarasi. Setiap variabel yang dideklarasikan selalu memiliki nilai default berdasarkan tipenya. Tidak ada konsep "tidak ditentukan" atau "nol".
Variabel Status
Variabel yang nilainya disimpan secara permanen dalam penyimpanan kontrak.
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10; // Using State variable
}
}
Variabel Lokal
Variabel yang nilainya hanya tersedia dalam fungsi yang ditentukan. Parameter fungsi selalu lokal untuk fungsi itu.
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return result; //access the local variable
}
}
Contoh
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return storedData; //access the state variable
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: uint256: 10
Variabel Global
Ini adalah variabel khusus yang ada di ruang kerja global dan memberikan informasi tentang blockchain dan properti transaksi.
Nama | Kembali |
---|---|
blockhash (uint blockNumber) kembali (bytes32) | Hash dari blok yang diberikan - hanya berfungsi untuk 256 blok terbaru, tidak termasuk blok saat ini |
block.coinbase (alamat dibayarkan) | Alamat blok penambang saat ini |
block.difficulty (uint) | Kesulitan blok saat ini |
block.gaslimit (uint) | Batasan gas saat ini |
block.number (uint) | Nomor blok saat ini |
block.timestamp (uint) | Stempel waktu blok saat ini sebagai detik sejak unix epoch |
gasleft () kembali (uint256) | Sisa gas |
msg.data (byte calldata) | Data panggilan lengkap |
msg.sender (alamat yang harus dibayar) | Pengirim pesan (penelepon saat ini) |
msg.sig (byte4) | Empat byte pertama dari calldata (pengenal fungsi) |
nilai pesan (uint) | Jumlah wei yang dikirim dengan pesan tersebut |
sekarang (uint) | Stempel waktu blok saat ini |
tx.gasprice (uint) | Harga gas dari transaksi |
tx.origin (alamat yang harus dibayar) | Pengirim transaksi |
Nama Variabel Soliditas
Saat menamai variabel Anda dalam Solidity, perhatikan aturan berikut.
Anda tidak boleh menggunakan salah satu kata kunci Solidity yang dipesan sebagai nama variabel. Kata kunci ini disebutkan di bagian selanjutnya. Misalnya, nama variabel break atau boolean tidak valid.
Nama variabel soliditas tidak boleh dimulai dengan angka (0-9). Mereka harus dimulai dengan huruf atau karakter garis bawah. Misalnya, 123test adalah nama variabel yang tidak valid, tetapi _123test adalah nama yang valid.
Nama variabel soliditas peka huruf besar kecil. Misalnya, Nama dan nama adalah dua variabel berbeda.
Cakupan variabel lokal terbatas pada fungsi di mana mereka didefinisikan, tetapi variabel Status dapat memiliki tiga jenis cakupan.
Public- Variabel status publik dapat diakses secara internal maupun melalui pesan. Untuk variabel status publik, fungsi pengambil otomatis dihasilkan.
Internal - Variabel status internal hanya dapat diakses secara internal dari kontrak saat ini atau kontrak yang diturunkan darinya tanpa menggunakan ini.
Private - Variabel status privat hanya dapat diakses secara internal dari kontrak saat ini, variabel tersebut didefinisikan bukan dalam kontrak turunan darinya.
Contoh
pragma solidity ^0.5.0;
contract C {
uint public data = 30;
uint internal iData= 10;
function x() public returns (uint) {
data = 3; // internal access
return data;
}
}
contract Caller {
C c = new C();
function f() public view returns (uint) {
return c.data(); //external access
}
}
contract D is C {
function y() public returns (uint) {
iData = 3; // internal access
return iData;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return storedData; //access the state variable
}
}
Apa itu Operator?
Mari kita ambil ungkapan sederhana 4 + 5 is equal to 9. Di sini 4 dan 5 dipanggiloperands dan '+' disebut operator. Soliditas mendukung jenis operator berikut.
- Operator Aritmatika
- Operator Perbandingan
- Operator Logis (atau Relasional)
- Operator Penugasan
- Operator Bersyarat (atau terner)
Mari kita lihat semua operator satu per satu.
Operator Aritmatika
Soliditas mendukung operator aritmatika berikut -
Asumsikan variabel A memiliki 10 dan variabel B memiliki 20, maka -
Tunjukkan Contoh
Sr.No. | Operator & Deskripsi |
---|---|
1 | + (Addition) Menambahkan dua operan Ex: A + B akan menghasilkan 30 |
2 | - (Subtraction) Mengurangi operan kedua dari yang pertama Ex: A - B akan memberi -10 |
3 | * (Multiplication) Kalikan kedua operan Ex: A * B akan memberi 200 |
4 | / (Division) Bagilah pembilangnya dengan penyebutnya Ex: B / A akan memberi 2 |
5 | % (Modulus) Menghasilkan sisa dari pembagian integer Ex: B% A akan memberi 0 |
6 | ++ (Increment) Meningkatkan nilai integer satu Ex: A ++ akan memberikan 11 |
7 | -- (Decrement) Mengurangi nilai integer satu Ex: A-- akan memberi 9 |
Operator Perbandingan
Soliditas mendukung operator perbandingan berikut -
Asumsikan variabel A memiliki 10 dan variabel B memiliki 20, maka -
Tunjukkan Contoh
Sr.No. | Operator & Deskripsi |
---|---|
1 | = = (Equal) Memeriksa apakah nilai dua operan sama atau tidak, jika ya, maka kondisinya menjadi benar. Ex: (A == B) tidak benar. |
2 | != (Not Equal) Memeriksa apakah nilai dua operan sama atau tidak, jika nilainya tidak sama, maka kondisinya menjadi benar. Ex: (A! = B) benar. |
3 | > (Greater than) Memeriksa apakah nilai operan kiri lebih besar dari nilai operan kanan, jika ya, maka kondisinya menjadi benar. Ex: (A> B) tidak benar. |
4 | < (Less than) Memeriksa apakah nilai operan kiri kurang dari nilai operan kanan, jika ya, maka kondisinya menjadi benar. Ex: (A <B) benar. |
5 | >= (Greater than or Equal to) Memeriksa apakah nilai operan kiri lebih besar dari atau sama dengan nilai operan kanan, jika ya, maka kondisinya menjadi benar. Ex: (A> = B) tidak benar. |
6 | <= (Less than or Equal to) Memeriksa apakah nilai operan kiri kurang dari atau sama dengan nilai operan kanan, jika ya, maka kondisinya menjadi benar. Ex: (A <= B) benar. |
Operator Logis
Soliditas mendukung operator logika berikut -
Asumsikan variabel A memiliki 10 dan variabel B memiliki 20, maka -
Tunjukkan Contoh
Sr.No. | Operator & Deskripsi |
---|---|
1 | && (Logical AND) Jika kedua operan bukan nol, maka kondisinya menjadi benar. Ex: (A && B) benar. |
2 | || (Logical OR) Jika salah satu dari dua operan bukan nol, maka kondisinya menjadi benar. Ex: (A || B) itu benar. |
3 | ! (Logical NOT) Membalik keadaan logis dari operannya. Jika kondisinya benar, maka operator NOT Logical akan membuatnya salah. Ex:! (A && B) salah. |
Operator Bitwise
Soliditas mendukung operator bitwise berikut -
Asumsikan variabel A memiliki 2 dan variabel B memiliki 3, maka -
Tunjukkan Contoh
Sr.No. | Operator & Deskripsi |
---|---|
1 | & (Bitwise AND) Ia melakukan operasi Boolean AND pada setiap bit argumen integernya. Ex: (A & B) adalah 2. |
2 | | (BitWise OR) Ia melakukan operasi Boolean OR pada setiap bit argumen integernya. Ex: (A | B) adalah 3. |
3 | ^ (Bitwise XOR) Ia melakukan operasi Boolean eksklusif OR pada setiap bit argumen integernya. Eksklusif OR berarti salah satu operan satu benar atau operan dua benar, tetapi tidak keduanya. Ex: (A ^ B) adalah 1. |
4 | ~ (Bitwise Not) Ini adalah operator unary dan beroperasi dengan membalik semua bit di operan. Ex: (~ B) adalah -4. |
5 | << (Left Shift) Ini memindahkan semua bit di operan pertamanya ke kiri dengan jumlah tempat yang ditentukan di operan kedua. Bit baru diisi dengan nol. Menggeser nilai ke kiri dengan satu posisi sama dengan mengalikannya dengan 2, menggeser dua posisi sama dengan mengalikannya dengan 4, dan seterusnya. Ex: (A << 1) adalah 4. |
6 | >> (Right Shift) Operator Pergeseran Kanan Biner. Nilai operan kiri dipindahkan ke kanan dengan jumlah bit yang ditentukan oleh operan kanan. Ex: (A >> 1) adalah 1. |
7 | >>> (Right shift with Zero) Operator ini seperti operator >>, kecuali bit yang digeser di kiri selalu nol. Ex: (A >>> 1) adalah 1. |
Operator Penugasan
Soliditas mendukung operator penugasan berikut -
Tunjukkan Contoh
Sr.No. | Operator & Deskripsi |
---|---|
1 | = (Simple Assignment ) Menetapkan nilai dari operan sisi kanan ke operan sisi kiri Ex: C = A + B akan menetapkan nilai A + B ke dalam C |
2 | += (Add and Assignment) Ini menambahkan operan kanan ke operan kiri dan memberikan hasilnya ke operan kiri. Ex: C + = A ekivalen dengan C = C + A |
3 | −= (Subtract and Assignment) Ini mengurangi operan kanan dari operan kiri dan memberikan hasilnya ke operan kiri. Ex: C - = A ekivalen dengan C = C - A |
4 | *= (Multiply and Assignment) Ini mengalikan operan kanan dengan operan kiri dan memberikan hasilnya ke operan kiri. Ex: C * = A setara dengan C = C * A |
5 | /= (Divide and Assignment) Ini membagi operan kiri dengan operan kanan dan memberikan hasilnya ke operan kiri. Ex: C / = A ekivalen dengan C = C / A |
6 | %= (Modules and Assignment) Dibutuhkan modulus menggunakan dua operan dan memberikan hasilnya ke operan kiri. Ex: C% = A setara dengan C = C% A |
Note - Logika yang sama berlaku untuk operator Bitwise sehingga akan menjadi seperti << =, >> =, >> =, & =, | = dan ^ =.
Operator Bersyarat (? :)
Operator kondisional pertama-tama mengevaluasi ekspresi untuk nilai benar atau salah dan kemudian mengeksekusi salah satu dari dua pernyataan yang diberikan bergantung pada hasil evaluasi.
Tunjukkan Contoh
Sr.No. | Operator dan Deskripsi |
---|---|
1 | ? : (Conditional ) Jika Kondisi benar? Kemudian nilai X: Jika tidak, nilai Y |
Saat menulis kontrak, Anda mungkin menghadapi situasi di mana Anda perlu melakukan tindakan berulang kali. Dalam situasi seperti itu, Anda perlu menulis pernyataan loop untuk mengurangi jumlah baris.
Soliditas mendukung semua loop yang diperlukan untuk mengurangi tekanan pemrograman.
Sr Tidak | Loop & Deskripsi |
---|---|
1 | Sedangkan Loop Loop paling dasar dalam Solidity adalah loop sementara yang akan dibahas dalam bab ini. |
2 | lakukan ... saat Loop Perulangan do ... while mirip dengan perulangan while kecuali bahwa pemeriksaan kondisi terjadi di akhir pengulangan. |
3 | Untuk Loop Perulangan for adalah bentuk perulangan yang paling ringkas. Ini mencakup tiga bagian penting berikut. |
4 | Kontrol Loop Soliditas menyediakan kontrol penuh untuk menangani loop dan pernyataan sakelar. |
Saat menulis program, mungkin ada situasi ketika Anda perlu mengadopsi salah satu dari sekumpulan jalur tertentu. Dalam kasus seperti itu, Anda perlu menggunakan pernyataan bersyarat yang memungkinkan program Anda membuat keputusan yang benar dan melakukan tindakan yang benar.
Soliditas mendukung pernyataan bersyarat yang digunakan untuk melakukan tindakan berbeda berdasarkan kondisi yang berbeda. Di sini kami akan menjelaskanif..else pernyataan.
Diagram Alir dari if-else
Diagram alir berikut menunjukkan cara kerja pernyataan if-else.
Soliditas mendukung bentuk-bentuk berikut if..else pernyataan -
Sr Tidak | Pernyataan & Deskripsi |
---|---|
1 | jika pernyataan Pernyataan if adalah pernyataan kontrol fundamental yang memungkinkan Soliditas untuk membuat keputusan dan mengeksekusi pernyataan secara bersyarat. |
2 | jika ... pernyataan lain Pernyataan 'if ... else' adalah bentuk berikutnya dari pernyataan kontrol yang memungkinkan Soliditas untuk mengeksekusi pernyataan dengan cara yang lebih terkontrol. |
3 | jika ... lain jika ... pernyataan. Pernyataan if ... else if ... adalah bentuk lanjutan dari if ... else yang memungkinkan Solidity membuat keputusan yang tepat dari beberapa kondisi. |
Soliditas mendukung literal String menggunakan petik ganda (") dan petik tunggal ('). Soliditas menyediakan string sebagai tipe data untuk mendeklarasikan variabel berjenis String.
pragma solidity ^0.5.0;
contract SolidityTest {
string data = "test";
}
Dalam contoh di atas, "test" adalah literal string dan data adalah variabel string. Cara yang lebih disukai adalah dengan menggunakan tipe byte daripada String karena operasi string membutuhkan lebih banyak gas dibandingkan dengan operasi byte. Soliditas menyediakan konversi bawaan antara byte ke string dan sebaliknya. Dalam Solidity kita dapat menetapkan String literal ke variabel tipe byte32 dengan mudah. Solidity menganggapnya sebagai byte32 literal.
pragma solidity ^0.5.0;
contract SolidityTest {
bytes32 data = "test";
}
Karakter Escape
Sr.No. | Deskripsi karakter |
---|---|
1 | \n Memulai baris baru. |
2 | \\ Garis miring terbalik |
3 | \' Kutipan Tunggal |
4 | \" Kutipan Ganda |
5 | \b Menghapus |
6 | \f Formulir Pakan |
7 | \r Kereta kembali |
8 | \t Tab |
9 | \v Tab Vertikal |
10 | \xNN Mewakili nilai Hex dan menyisipkan byte yang sesuai. |
11 | \uNNNN Merupakan nilai Unicode dan menyisipkan urutan UTF-8. |
Konversi Byte ke String
Byte dapat diubah menjadi String menggunakan konstruktor string ().
bytes memory bstr = new bytes(10);
string message = string(bstr);
Contoh
Coba kode berikut untuk memahami cara kerja string di Solidity.
pragma solidity ^0.5.0;
contract SolidityTest {
constructor() public{
}
function getResult() public view returns(string memory){
uint a = 1;
uint b = 2;
uint result = a + b;
return integerToString(result);
}
function integerToString(uint _i) internal pure
returns (string memory) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: string: 3
Array adalah struktur data, yang menyimpan kumpulan elemen berurutan dengan ukuran tetap dari tipe yang sama. Sebuah array digunakan untuk menyimpan kumpulan data, tetapi seringkali lebih berguna untuk menganggap array sebagai kumpulan variabel dari tipe yang sama.
Daripada mendeklarasikan variabel individual, seperti number0, number1, ..., dan number99, Anda mendeklarasikan satu variabel array seperti angka dan menggunakan angka [0], angka [1], dan ..., angka [99] untuk mewakili variabel individu. Elemen tertentu dalam array diakses oleh indeks.
Dalam Solidity, sebuah array dapat berupa ukuran tetap waktu kompilasi atau ukuran dinamis. Untuk array penyimpanan, ia dapat memiliki berbagai jenis elemen juga. Dalam kasus larik memori, jenis elemen tidak dapat dipetakan dan jika akan digunakan sebagai parameter fungsi maka jenis elemen haruslah tipe ABI.
Semua array terdiri dari lokasi memori yang berdekatan. Alamat terendah sesuai dengan elemen pertama dan alamat tertinggi untuk elemen terakhir.
Mendeklarasikan Array
Untuk mendeklarasikan sebuah array dengan ukuran tetap dalam Solidity, programmer menentukan jenis elemen dan jumlah elemen yang dibutuhkan oleh sebuah array sebagai berikut:
type arrayName [ arraySize ];
Ini disebut larik berdimensi tunggal. ItuarraySize harus berupa konstanta bilangan bulat yang lebih besar dari nol dan typedapat berupa tipe data Soliditas apa pun yang valid. Misalnya, untuk mendeklarasikan array 10 elemen yang disebut balance of type uint, gunakan pernyataan ini -
uint balance[10];
Untuk mendeklarasikan array ukuran dinamis dalam Solidity, programmer menentukan jenis elemen sebagai berikut -
type[] arrayName;
Menginisialisasi Array
Anda dapat menginisialisasi elemen array Solidity baik satu per satu atau menggunakan satu pernyataan sebagai berikut -
uint balance[3] = [1, 2, 3];
Jumlah nilai di antara tanda kurung kurawal [] tidak boleh lebih besar dari jumlah elemen yang kita nyatakan untuk larik di antara tanda kurung siku []. Berikut adalah contoh untuk menetapkan satu elemen dari array -
Jika Anda menghilangkan ukuran array, array yang cukup besar untuk menampung inisialisasi akan dibuat. Karena itu, jika Anda menulis -
uint balance[] = [1, 2, 3];
Anda akan membuat larik yang persis sama seperti yang Anda lakukan di contoh sebelumnya.
balance[2] = 5;
Di atas wakilnya pernyataan sejumlah elemen 3 rd dalam array nilai 5.
Membuat array memori dinamis
Array memori dinamis dibuat menggunakan kata kunci baru.
uint size = 3;
uint balance[] = new uint[](size);
Mengakses Elemen Array
Sebuah elemen diakses dengan mengindeks nama array. Ini dilakukan dengan menempatkan indeks elemen dalam tanda kurung siku setelah nama larik. Misalnya -
uint salary = balance[2];
Pernyataan di atas akan mengambil 3 rd elemen dari array dan menetapkan nilai variabel gaji. Berikut ini adalah contoh, yang akan menggunakan semua tiga konsep yang disebutkan di atas yaitu. deklarasi, tugas dan mengakses array -
Anggota
length- length mengembalikan ukuran array. length dapat digunakan untuk mengubah ukuran array dinamis menjadi pengaturannya.
push- push memungkinkan untuk menambahkan elemen ke array penyimpanan dinamis di bagian akhir. Ini mengembalikan panjang baru dari array.
Contoh
Coba kode berikut untuk memahami bagaimana array bekerja di Solidity.
pragma solidity ^0.5.0;
contract test {
function testArray() public pure{
uint len = 7;
//dynamic array
uint[] memory a = new uint[](7);
//bytes is same as byte[]
bytes memory b = new bytes(len);
assert(a.length == 7);
assert(b.length == len);
//access array variable
a[6] = 8;
//test array variable
assert(a[6] == 8);
//static array
uint[3] memory c = [uint(1) , 2, 3];
assert(c.length == 3);
}
}
Enum membatasi variabel untuk memiliki salah satu dari sedikit nilai yang telah ditentukan. Nilai-nilai dalam daftar yang disebutkan ini disebut enum.
Dengan penggunaan enum, dimungkinkan untuk mengurangi jumlah bug dalam kode Anda.
Sebagai contoh, jika kita mempertimbangkan aplikasi untuk toko jus segar, akan mungkin membatasi ukuran gelas menjadi kecil, sedang, dan besar. Ini akan memastikan bahwa itu tidak akan memungkinkan siapa pun untuk memesan ukuran apa pun selain kecil, sedang, atau besar.
Contoh
Coba kode berikut untuk memahami cara kerja enum di Solidity.
pragma solidity ^0.5.0;
contract test {
enum FreshJuiceSize{ SMALL, MEDIUM, LARGE }
FreshJuiceSize choice;
FreshJuiceSize constant defaultChoice = FreshJuiceSize.MEDIUM;
function setLarge() public {
choice = FreshJuiceSize.LARGE;
}
function getChoice() public view returns (FreshJuiceSize) {
return choice;
}
function getDefaultChoice() public pure returns (uint) {
return uint(defaultChoice);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik Pertama setLarge Tombol untuk menyetel nilai sebagai BESAR lalu klik getChoice untuk mendapatkan pilihan yang dipilih.
Keluaran
uint8: 2
Klik getDefaultChoice Tombol untuk mendapatkan pilihan default.
Keluaran
uint256: 1
Tipe struktur digunakan untuk merepresentasikan record. Misalkan Anda ingin melacak buku Anda di perpustakaan. Anda mungkin ingin melacak atribut berikut tentang setiap buku -
- Title
- Author
- Subject
- ID Buku
Mendefinisikan Struct
Untuk menentukan Struct, Anda harus menggunakan structkata kunci. Kata kunci struct mendefinisikan tipe data baru, dengan lebih dari satu anggota. Format pernyataan struct adalah sebagai berikut -
struct struct_name {
type1 type_name_1;
type2 type_name_2;
type3 type_name_3;
}
Contoh
struct Book {
string title;
string author;
uint book_id;
}
Mengakses Struktur dan variabelnya
Untuk mengakses anggota suatu struktur, kami menggunakan operator akses anggota (.). Operator akses anggota dikodekan sebagai periode antara nama variabel struktur dan anggota struktur yang ingin kita akses. Anda akan menggunakan struct untuk mendefinisikan variabel tipe struktur. Contoh berikut menunjukkan bagaimana menggunakan struktur dalam sebuah program.
Contoh
Coba kode berikut untuk memahami cara kerja struct di Solidity.
pragma solidity ^0.5.0;
contract test {
struct Book {
string title;
string author;
uint book_id;
}
Book book;
function setBook() public {
book = Book('Learn Java', 'TP', 1);
}
function getBookId() public view returns (uint) {
return book.book_id;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik Pertama setBook Tombol untuk menyetel nilai sebagai BESAR lalu klik getBookId untuk mendapatkan id buku yang dipilih.
Keluaran
uint256: 1
Pemetaan adalah jenis referensi sebagai array dan struct. Berikut sintaks untuk mendeklarasikan tipe pemetaan.
mapping(_KeyType => _ValueType)
Dimana
_KeyType- dapat berupa tipe bawaan apa pun ditambah byte dan string. Tidak ada tipe referensi atau objek kompleks yang diperbolehkan.
_ValueType - bisa tipe apapun.
Pertimbangan
Pemetaan hanya dapat memiliki jenis storage dan umumnya digunakan untuk variabel status.
Pemetaan dapat ditandai publik. Soliditas secara otomatis menciptakan pengambil untuk itu.
Contoh
Coba kode berikut untuk memahami cara kerja jenis pemetaan di Solidity.
pragma solidity ^0.5.0;
contract LedgerBalance {
mapping(address => uint) public balances;
function updateBalance(uint newBalance) public {
balances[msg.sender] = newBalance;
}
}
contract Updater {
function updateBalance() public returns (uint) {
LedgerBalance ledgerBalance = new LedgerBalance();
ledgerBalance.updateBalance(10);
return ledgerBalance.balances(address(this));
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik Pertama updateBalance Tombol untuk mengatur nilai sebagai 10 lalu lihat ke dalam log yang akan menampilkan keluaran yang didekodekan sebagai -
Keluaran
{
"0": "uint256: 10"
}
Soliditas memungkinkan konversi implisit maupun eksplisit. Kompilator soliditas memungkinkan konversi implisit antara dua tipe data asalkan tidak ada konversi implisit yang dimungkinkan dan tidak ada informasi yang hilang. Misalnya uint8 dapat dikonversi ke uint16 tetapi int8 dapat dikonversi menjadi uint256 karena int8 dapat berisi nilai negatif yang tidak diizinkan di uint256.
Konversi Eksplisit
Kita dapat secara eksplisit mengonversi tipe data ke yang lain menggunakan sintaks konstruktor.
int8 y = -3;
uint x = uint(y);
//Now x = 0xfffff..fd == two complement representation of -3 in 256 bit format.
Konversi ke tipe yang lebih kecil membutuhkan bit pesanan yang lebih tinggi.
uint32 a = 0x12345678;
uint16 b = uint16(a); // b = 0x5678
Konversi ke tipe yang lebih tinggi menambahkan bit padding ke kiri.
uint16 a = 0x1234;
uint32 b = uint32(a); // b = 0x00001234
Konversi ke byte yang lebih kecil membutuhkan data pesanan yang lebih tinggi.
bytes2 a = 0x1234;
bytes1 b = bytes1(a); // b = 0x12
Konversi ke byte yang lebih besar menambahkan bit padding ke kanan.
bytes2 a = 0x1234;
bytes4 b = bytes4(a); // b = 0x12340000
Konversi antara byte ukuran tetap dan int hanya mungkin jika keduanya berukuran sama.
bytes2 a = 0x1234;
uint32 b = uint16(a); // b = 0x00001234
uint32 c = uint32(bytes4(a)); // c = 0x12340000
uint8 d = uint8(uint16(a)); // d = 0x34
uint8 e = uint8(bytes1(a)); // e = 0x12
Bilangan heksadesimal dapat ditetapkan ke tipe bilangan bulat apa pun jika tidak diperlukan pemotongan.
uint8 a = 12; // no error
uint32 b = 1234; // no error
uint16 c = 0x123456; // error, as truncation required to 0x3456
Dalam soliditas kita dapat menggunakan wei, finney, szabo atau ether sebagai sufiks ke literal yang akan digunakan untuk mengubah berbagai denominasi berbasis eter. Satuan terendah adalah wei dan 1e12 mewakili 1 x 10 12 .
assert(1 wei == 1);
assert(1 szabo == 1e12);
assert(1 finney == 1e15);
assert(1 ether == 1e18);
assert(2 ether == 2000 fenny);
Satuan Waktu
Mirip dengan mata uang, Soliditas memiliki satuan waktu di mana satuan terendah adalah detik dan kita dapat menggunakan detik, menit, jam, hari, dan minggu sebagai sufiks untuk menunjukkan waktu.
assert(1 seconds == 1);
assert(1 minutes == 60 seconds);
assert(1 hours == 60 minutes);
assert(1 day == 24 hours);
assert(1 week == 7 days);
Variabel khusus adalah variabel yang tersedia secara global dan memberikan informasi tentang blockchain. Berikut adalah daftar variabel khusus -
Sr.No. | Variabel & Deskripsi Khusus |
---|---|
1 | blockhash(uint blockNumber) returns (bytes32) Hash dari blok yang diberikan - hanya berfungsi untuk 256 blok terbaru, tidak termasuk blok saat ini. |
2 | block.coinbase (address payable) Alamat blok penambang saat ini. |
3 | block.difficulty (uint) kesulitan blok saat ini. |
4 | block.gaslimit (uint) Batasan gas saat ini. |
5 | block.number (uint) Nomor blok saat ini. |
6 | block.timestamp Stempel waktu blok saat ini sebagai detik sejak unix epoch. |
7 | gasleft() returns (uint256) Sisa gas. |
8 | msg.data (bytes calldata) Data panggilan lengkap. |
9 | msg.sender (address payable) Pengirim pesan (panggilan saat ini). |
10 | msg.sig (bytes4) Empat byte pertama dari calldata (yaitu pengenal fungsi) |
11 | msg.value (uint) Jumlah wei yang dikirim dengan pesan tersebut. |
12 | now (uint) Stempel waktu blok saat ini (alias untuk block.timestamp). |
13 | tx.gasprice (uint) Harga gas dari transaksi tersebut. |
14 | tx.origin (address payable) Pengirim transaksi (rantai panggilan penuh). |
Contoh
Coba kode berikut untuk melihat penggunaan msg, variabel khusus untuk mendapatkan alamat pengirim di Solidity.
pragma solidity ^0.5.0;
contract LedgerBalance {
mapping(address => uint) public balances;
function updateBalance(uint newBalance) public {
balances[msg.sender] = newBalance;
}
}
contract Updater {
function updateBalance() public returns (uint) {
LedgerBalance ledgerBalance = new LedgerBalance();
ledgerBalance.updateBalance(10);
return ledgerBalance.balances(address(this));
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik Pertama updateBalance Tombol untuk mengatur nilai sebagai 10 lalu lihat ke dalam log yang akan menampilkan keluaran yang didekodekan sebagai -
Keluaran
{
"0": "uint256: 10"
}
Style Guide membantu menjaga konsistensi tata letak kode dan membuat kode lebih mudah dibaca. Berikut adalah praktik terbaik berikut saat menulis kontrak dengan Solidity.
Tata Letak Kode
Indentation- Gunakan 4 spasi sebagai ganti tab untuk mempertahankan tingkat indentasi. Hindari mencampur spasi dengan tab.
Two Blank Lines Rule - Gunakan 2 baris kosong antara dua definisi kontrak.
pragma solidity ^0.5.0;
contract LedgerBalance {
//...
}
contract Updater {
//...
}
One Blank Line Rule- Gunakan 1 baris kosong di antara dua fungsi. Dalam kasus hanya deklarasi, tidak perlu memiliki baris kosong.
pragma solidity ^0.5.0;
contract A {
function balance() public pure;
function account() public pure;
}
contract B is A {
function balance() public pure {
// ...
}
function account() public pure {
// ...
}
}
Maximum Line Length - Satu baris tidak boleh melewati 79 karakter sehingga pembaca dapat dengan mudah mengurai kode.
Wrapping rules- Argumen pertama berada di baris baru tanpa membuka tanda kurung. Gunakan indentasi tunggal per argumen. Elemen pemutusan); harus menjadi yang terakhir.
function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
variable = function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
event multipleArguments(
address sender,
address recipient,
uint256 publicKey,
uint256 amount,
bytes32[] options
);
MultipleArguments(
sender,
recipient,
publicKey,
amount,
options
);
Source Code Encoding - Pengkodean UTF-8 atau ASCII sebaiknya digunakan.
Imports - Pernyataan impor harus ditempatkan di bagian atas file tepat setelah deklarasi pragma.
Order of Functions - Fungsi harus dikelompokkan sesuai visibilitasnya.
pragma solidity ^0.5.0;
contract A {
constructor() public {
// ...
}
function() external {
// ...
}
// External functions
// ...
// External view functions
// ...
// External pure functions
// ...
// Public functions
// ...
// Internal functions
// ...
// Private functions
// ...
}
Avoid extra whitespaces - Hindari spasi langsung di dalam tanda kurung, tanda kurung atau kawat gigi.
Control structures- Braces harus terbuka pada baris yang sama dengan deklarasi. Tutup barisnya sendiri dengan mempertahankan lekukan yang sama. Gunakan spasi dengan kurung kurawal buka.
pragma solidity ^0.5.0;
contract Coin {
struct Bank {
address owner;
uint balance;
}
}
if (x < 3) {
x += 1;
} else if (x > 7) {
x -= 1;
} else {
x = 5;
}
if (x < 3)
x += 1;
else
x -= 1;
Function Declaration- Gunakan aturan di atas untuk kawat gigi. Selalu tambahkan label visibilitas. Label visibilitas harus diutamakan sebelum pengubah kustom apa pun.
function kill() public onlyowner {
selfdestruct(owner);
}
Mappings - Hindari spasi saat mendeklarasikan variabel pemetaan.
mapping(uint => uint) map;
mapping(address => bool) registeredAddresses;
mapping(uint => mapping(bool => Data[])) public data;
mapping(uint => mapping(uint => s)) data;
Variable declaration - Hindari spasi putih saat mendeklarasikan variabel array.
uint[] x; // not unit [] x;
String declaration - Gunakan tanda kutip ganda untuk mendeklarasikan string, bukan tanda kutip tunggal.
str = "foo";
str = "Hamlet says, 'To be or not to be...'";
Urutan Tata Letak
Elemen harus diatur dalam urutan berikut.
Pernyataan Pragma
Pernyataan impor
Interfaces
Libraries
Contracts
Dalam Interfaces, pustaka atau kontrak, urutannya harus sebagai -
Ketik deklarasi
Variabel status
Events
Functions
Konvensi penamaan
Kontrak dan Perpustakaan harus diberi nama menggunakan CapWords Style. Misalnya, SmartContract, Owner dll.
Nama kontrak dan perpustakaan harus sesuai dengan nama file mereka.
Jika ada beberapa kontrak / pustaka dalam satu file, gunakan nama kontrak / pustaka inti.
Owned.sol
pragma solidity ^0.5.0;
// Owned.sol
contract Owned {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
//....
}
function transferOwnership(address newOwner) public onlyOwner {
//...
}
}
Congress.sol
pragma solidity ^0.5.0;
// Congress.sol
import "./Owned.sol";
contract Congress is Owned, TokenRecipient {
//...
}
Nama Struct
- Gunakan CapWords Style seperti SmartCoin.Nama Acara
- Gunakan CapWords Style seperti Deposit, AfterTransfer.Nama Fungsi
- Gunakan gaya mixedCase seperti inisiateSupply.Variabel Lokal dan Negara Bagian
- Gunakan Style mixedCase seperti creatorAddress, supply.Konstanta
- Gunakan semua huruf kapital dengan garis bawah untuk memisahkan kata-kata seperti MAX_BLOCKS.Nama Pengubah
- Gunakan Style mixCase seperti onlyAfter.Nama Enum
- Gunakan CapWords Style seperti TokenGroup.
Fungsi adalah sekelompok kode yang dapat digunakan kembali yang dapat dipanggil di mana saja dalam program Anda. Ini menghilangkan kebutuhan untuk menulis kode yang sama berulang kali. Ini membantu programmer dalam menulis kode modular. Fungsi memungkinkan programmer untuk membagi program besar menjadi sejumlah fungsi kecil dan dapat diatur.
Seperti bahasa pemrograman tingkat lanjut lainnya, Solidity juga mendukung semua fitur yang diperlukan untuk menulis kode modular menggunakan fungsi. Bagian ini menjelaskan cara menulis fungsi Anda sendiri di Solidity.
Definisi Fungsi
Sebelum kita menggunakan suatu fungsi, kita perlu mendefinisikannya. Cara paling umum untuk mendefinisikan fungsi dalam Soliditas adalah dengan menggunakanfunction kata kunci, diikuti dengan nama fungsi unik, daftar parameter (yang mungkin kosong), dan blok pernyataan yang dikelilingi oleh tanda kurung kurawal.
Sintaksis
Sintaks dasar ditampilkan di sini.
function function-name(parameter-list) scope returns() {
//statements
}
Contoh
Coba contoh berikut. Ini mendefinisikan fungsi yang disebut getResult yang tidak mengambil parameter -
pragma solidity ^0.5.0;
contract Test {
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return result;
}
}
Memanggil Fungsi
Untuk memanggil suatu fungsi di suatu tempat nanti dalam Kontrak, Anda hanya perlu menulis nama fungsi itu seperti yang ditunjukkan pada kode berikut.
Coba kode berikut untuk memahami cara kerja string di Solidity.
pragma solidity ^0.5.0;
contract SolidityTest {
constructor() public{
}
function getResult() public view returns(string memory){
uint a = 1;
uint b = 2;
uint result = a + b;
return integerToString(result);
}
function integerToString(uint _i) internal pure
returns (string memory) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);//access local variable
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: string: 3
Parameter Fungsi
Hingga saat ini, kami telah melihat fungsi tanpa parameter. Tetapi ada fasilitas untuk melewatkan parameter yang berbeda saat memanggil suatu fungsi. Parameter yang diteruskan ini dapat ditangkap di dalam fungsi dan manipulasi apa pun dapat dilakukan atas parameter tersebut. Suatu fungsi dapat mengambil beberapa parameter yang dipisahkan dengan koma.
Contoh
Coba contoh berikut. Kami telah menggunakan fileuint2strberfungsi di sini. Ini membutuhkan satu parameter.
pragma solidity ^0.5.0;
contract SolidityTest {
constructor() public{
}
function getResult() public view returns(string memory){
uint a = 1;
uint b = 2;
uint result = a + b;
return integerToString(result);
}
function integerToString(uint _i) internal pure
returns (string memory) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);//access local variable
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: string: 3
Pernyataan pengembalian
Fungsi Solidity dapat memiliki opsional returnpernyataan. Ini diperlukan jika Anda ingin mengembalikan nilai dari suatu fungsi. Pernyataan ini harus menjadi pernyataan terakhir dalam suatu fungsi.
Seperti pada contoh di atas, kami menggunakan fungsi uint2str untuk mengembalikan string.
Dalam Solidity, suatu fungsi dapat mengembalikan banyak nilai juga. Lihat contoh di bawah ini -
pragma solidity ^0.5.0;
contract Test {
function getResult() public view returns(uint product, uint sum){
uint a = 1; // local variable
uint b = 2;
product = a * b;
sum = a + b;
//alternative return statement to return
//multiple values
//return(a*b, a+b);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: uint256: product 2
1: uint256: sum 3
Pengubah Fungsi digunakan untuk mengubah perilaku suatu fungsi. Misalnya untuk menambahkan prasyarat ke suatu fungsi.
Pertama kita membuat pengubah dengan atau tanpa parameter.
contract Owner {
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier costs(uint price) {
if (msg.value >= price) {
_;
}
}
}
Badan fungsi disisipkan di mana simbol khusus "_;" muncul dalam definisi pengubah. Jadi jika kondisi pengubah terpenuhi saat memanggil fungsi ini, fungsi dijalankan dan jika tidak, pengecualian akan dilemparkan.
Lihat contoh di bawah ini -
pragma solidity ^0.5.0;
contract Owner {
address owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier costs(uint price) {
if (msg.value >= price) {
_;
}
}
}
contract Register is Owner {
mapping (address => bool) registeredAddresses;
uint price;
constructor(uint initialPrice) public { price = initialPrice; }
function register() public payable costs(price) {
registeredAddresses[msg.sender] = true;
}
function changePrice(uint _price) public onlyOwner {
price = _price;
}
}
Fungsi View memastikan bahwa mereka tidak akan mengubah status. Suatu fungsi dapat dideklarasikan sebagaiview. Pernyataan berikut jika ada dalam fungsi dianggap mengubah status dan compiler akan memberikan peringatan dalam kasus seperti itu.
Mengubah variabel negara.
Acara pemancar.
Membuat kontrak lain.
Menggunakan selfdestruct.
Mengirim Ether melalui panggilan.
Memanggil fungsi apa pun yang tidak ditandai tampilan atau murni.
Menggunakan panggilan tingkat rendah.
Menggunakan perakitan inline yang berisi opcode tertentu.
Metode pengambil secara default adalah fungsi tampilan.
Lihat contoh di bawah ini menggunakan fungsi tampilan.
Contoh
pragma solidity ^0.5.0;
contract Test {
function getResult() public view returns(uint product, uint sum){
uint a = 1; // local variable
uint b = 2;
product = a * b;
sum = a + b;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: uint256: product 2
1: uint256: sum 3
Fungsi murni memastikan bahwa mereka tidak membaca atau mengubah status. Suatu fungsi dapat dideklarasikan sebagaipure. Pernyataan berikut jika ada dalam fungsi dianggap membaca status dan compiler akan memberikan peringatan dalam kasus seperti itu.
Membaca variabel status.
Mengakses address (this) .balance or <address> .balance.
Mengakses variabel khusus blok, tx, msg (msg.sig dan msg.data dapat dibaca).
Memanggil fungsi apa pun tidak ditandai murni.
Menggunakan perakitan inline yang berisi opcode tertentu.
Fungsi murni dapat menggunakan fungsi revert () dan require () untuk mengembalikan potensi perubahan status jika terjadi kesalahan.
Lihat contoh di bawah ini menggunakan fungsi tampilan.
Contoh
pragma solidity ^0.5.0;
contract Test {
function getResult() public pure returns(uint product, uint sum){
uint a = 1;
uint b = 2;
product = a * b;
sum = a + b;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: uint256: product 2
1: uint256: sum 3
Fungsi fallback adalah fungsi khusus yang tersedia untuk kontrak. Ini memiliki fitur berikut -
Ini dipanggil ketika fungsi yang tidak ada dipanggil dalam kontrak.
Itu harus ditandai eksternal.
Tidak ada nama.
Tidak ada argumen
Itu tidak bisa mengembalikan apapun.
Ini dapat ditentukan satu per kontrak.
Jika tidak ditandai sebagai hutang, itu akan membuang pengecualian jika kontrak menerima eter biasa tanpa data.
Contoh berikut menunjukkan konsep fungsi fallback per kontrak.
Contoh
pragma solidity ^0.5.0;
contract Test {
uint public x ;
function() external { x = 1; }
}
contract Sink {
function() external payable { }
}
contract Caller {
function callTest(Test test) public returns (bool) {
(bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
require(success);
// test.x is now 1
address payable testPayable = address(uint160(address(test)));
// Sending ether to Test contract,
// the transfer will fail, i.e. this returns false here.
return (testPayable.send(2 ether));
}
function callSink(Sink sink) public returns (bool) {
address payable sinkPayable = address(sink);
return (sinkPayable.send(2 ether));
}
}
Anda dapat memiliki beberapa definisi untuk nama fungsi yang sama dalam lingkup yang sama. Definisi fungsi harus berbeda satu sama lain dengan jenis dan / atau jumlah argumen dalam daftar argumen. Anda tidak bisa membebani deklarasi fungsi yang hanya berbeda menurut tipe kembalian.
Contoh berikut menunjukkan konsep fungsi overloading di Solidity.
Contoh
pragma solidity ^0.5.0;
contract Test {
function getSum(uint a, uint b) public pure returns(uint){
return a + b;
}
function getSum(uint a, uint b, uint c) public pure returns(uint){
return a + b + c;
}
function callSumWithTwoArguments() public pure returns(uint){
return getSum(1,2);
}
function callSumWithThreeArguments() public pure returns(uint){
return getSum(1,2,3);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik tombol callSumWithTwoArguments terlebih dahulu lalu tombol callSumWithThreeArguments untuk melihat hasilnya.
Keluaran
0: uint256: 3
0: uint256: 6
Soliditas juga menyediakan fungsi matematika yang terintegrasi. Berikut ini adalah metode yang banyak digunakan -
addmod(uint x, uint y, uint k) returns (uint)- menghitung (x + y)% k di mana penambahan dilakukan dengan presisi sewenang-wenang dan tidak membungkus sekitar 2 256 .
mulmod(uint x, uint y, uint k) returns (uint)- menghitung (x * y)% k di mana penambahan dilakukan dengan presisi sewenang-wenang dan tidak membungkus sekitar 2 256 .
Contoh berikut menunjukkan penggunaan fungsi matematika di Solidity.
Contoh
pragma solidity ^0.5.0;
contract Test {
function callAddMod() public pure returns(uint){
return addmod(4, 5, 3);
}
function callMulMod() public pure returns(uint){
return mulmod(4, 5, 3);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Klik tombol callAddMod terlebih dahulu lalu tombol callMulMod untuk melihat hasilnya.
Keluaran
0: uint256: 0
0: uint256: 2
Soliditas juga menyediakan fungsi kriptografi bawaan. Berikut adalah metode penting -
keccak256(bytes memory) returns (bytes32) - menghitung hash Keccak-256 dari input.
sha256(bytes memory) returns (bytes32) - menghitung hash SHA-256 dari input.
ripemd160(bytes memory) returns (bytes20) - hitung hash RIPEMD-160 dari input.
sha256(bytes memory) returns (bytes32) - menghitung hash SHA-256 dari input.
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)- memulihkan alamat yang terkait dengan kunci publik dari tanda tangan kurva elips atau mengembalikan nol pada kesalahan. Parameter fungsi sesuai dengan nilai ECDSA dari tanda tangan: r - 32 byte pertama tanda tangan; s: 32 byte tanda tangan kedua; v: 1 byte terakhir dari tanda tangan. Metode ini mengembalikan alamat.
Contoh berikut menunjukkan penggunaan fungsi kriptografi di Solidity.
Contoh
pragma solidity ^0.5.0;
contract Test {
function callKeccak256() public pure returns(bytes32 result){
return keccak256("ABC");
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: bytes32: result 0xe1629b9dda060bb30c7908346f6af189c16773fa148d3366701fbaa35d54f3c8
Pola penarikan memastikan bahwa panggilan transfer langsung tidak dilakukan yang menimbulkan ancaman keamanan. Kontrak berikut menunjukkan penggunaan transfer call yang tidak aman untuk mengirim Ether.
pragma solidity ^0.5.0;
contract Test {
address payable public richest;
uint public mostSent;
constructor() public payable {
richest = msg.sender;
mostSent = msg.value;
}
function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) {
// Insecure practice
richest.transfer(msg.value);
richest = msg.sender;
mostSent = msg.value;
return true;
} else {
return false;
}
}
}
Kontrak di atas dapat dibuat dalam keadaan tidak dapat digunakan dengan menyebabkan yang terkaya menjadi kontrak dengan fungsi fallback yang gagal. Saat fungsi fallback gagal, fungsi beRichest () juga gagal dan kontrak akan macet selamanya. Untuk mengatasi masalah ini, kita bisa menggunakan Pola Penarikan.
Dalam pola penarikan, kami akan mengatur ulang jumlah yang tertunda sebelum setiap transfer. Ini akan memastikan bahwa hanya kontrak penelepon yang gagal.
pragma solidity ^0.5.0;
contract Test {
address public richest;
uint public mostSent;
mapping (address => uint) pendingWithdrawals;
constructor() public payable {
richest = msg.sender;
mostSent = msg.value;
}
function becomeRichest() public payable returns (bool) {
if (msg.value > mostSent) {
pendingWithdrawals[richest] += msg.value;
richest = msg.sender;
mostSent = msg.value;
return true;
} else {
return false;
}
}
function withdraw() public {
uint amount = pendingWithdrawals[msg.sender];
pendingWithdrawals[msg.sender] = 0;
msg.sender.transfer(amount);
}
}
Akses Terbatas ke Kontrak adalah praktik umum. Secara default, status kontrak bersifat hanya-baca kecuali ditentukan sebagai publik.
Kami dapat membatasi siapa yang dapat mengubah status kontrak atau memanggil fungsi kontrak menggunakan pengubah. Kami akan membuat dan menggunakan beberapa pengubah seperti yang dijelaskan di bawah ini -
onlyBy - sekali digunakan pada suatu fungsi maka hanya pemanggil yang disebutkan yang dapat memanggil fungsi ini.
onlyAfter - sekali digunakan pada suatu fungsi maka fungsi itu dapat dipanggil setelah jangka waktu tertentu.
costs - sekali digunakan pada suatu fungsi maka pemanggil dapat memanggil fungsi ini hanya jika nilai tertentu diberikan.
Contoh
pragma solidity ^0.5.0;
contract Test {
address public owner = msg.sender;
uint public creationTime = now;
modifier onlyBy(address _account) {
require(
msg.sender == _account,
"Sender not authorized."
);
_;
}
function changeOwner(address _newOwner) public onlyBy(owner) {
owner = _newOwner;
}
modifier onlyAfter(uint _time) {
require(
now >= _time,
"Function called too early."
);
_;
}
function disown() public onlyBy(owner) onlyAfter(creationTime + 6 weeks) {
delete owner;
}
modifier costs(uint _amount) {
require(
msg.value >= _amount,
"Not enough Ether provided."
);
_;
if (msg.value > _amount)
msg.sender.transfer(msg.value - _amount);
}
function forceOwnerChange(address _newOwner) public payable costs(200 ether) {
owner = _newOwner;
if (uint(owner) & 0 == 1) return;
}
}
Kontrak dalam Soliditas mirip dengan Kelas di C ++. Kontrak memiliki properti berikut.
Constructor - Sebuah fungsi khusus dideklarasikan dengan kata kunci konstruktor yang akan dijalankan satu kali per kontrak dan dipanggil saat kontrak dibuat.
State Variables - Variabel per Kontrak untuk menyimpan status kontrak.
Functions - Fungsi per Kontrak yang dapat mengubah variabel status untuk mengubah status kontrak.
Pengukur Visibilitas
Berikut adalah berbagai bilangan visibilitas untuk fungsi / variabel status kontrak.
external- Fungsi eksternal dimaksudkan untuk dipanggil oleh kontrak lain. Mereka tidak dapat digunakan untuk panggilan internal. Untuk memanggil fungsi eksternal dalam kontrak panggilan ini.function_name () diperlukan. Variabel status tidak dapat ditandai sebagai eksternal.
public- Fungsi / Variabel publik dapat digunakan baik secara eksternal maupun internal. Untuk variabel keadaan publik, Soliditas secara otomatis membuat fungsi pengambil.
internal - Fungsi / Variabel internal hanya dapat digunakan secara internal atau dengan kontrak turunan.
private - Fungsi / Variabel pribadi hanya dapat digunakan secara internal dan bahkan tidak oleh kontrak turunan.
Contoh
pragma solidity ^0.5.0;
contract C {
//private state variable
uint private data;
//public state variable
uint public info;
//constructor
constructor() public {
info = 10;
}
//private function
function increment(uint a) private pure returns(uint) { return a + 1; }
//public function
function updateData(uint a) public { data = a; }
function getData() public view returns(uint) { return data; }
function compute(uint a, uint b) internal pure returns (uint) { return a + b; }
}
//External Contract
contract D {
function readData() public returns(uint) {
C c = new C();
c.updateData(7);
return c.getData();
}
}
//Derived Contract
contract E is C {
uint private result;
C private c;
constructor() public {
c = new C();
}
function getComputedResult() public {
result = compute(3, 5);
}
function getResult() public view returns(uint) { return result; }
function getData() public view returns(uint) { return c.info(); }
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First . Jalankan berbagai metode Kontrak. Untuk acara E. getComputedResult () diikuti oleh E.getResult () -
Keluaran
0: uint256: 8
Warisan adalah cara untuk memperluas fungsionalitas kontrak. Soliditas mendukung pewarisan tunggal maupun ganda. Berikut ini adalah sorotan utama.
Kontrak turunan dapat mengakses semua anggota non-privat termasuk metode internal dan variabel status. Tetapi menggunakan ini tidak diperbolehkan.
Penggantian fungsi diperbolehkan asalkan tanda tangan fungsi tetap sama. Jika ada perbedaan parameter keluaran, kompilasi akan gagal.
Kita bisa memanggil fungsi kontrak super menggunakan kata kunci super atau menggunakan nama kontrak super.
Dalam kasus beberapa warisan, pemanggilan fungsi menggunakan super memberikan preferensi ke sebagian besar kontrak turunan.
Contoh
pragma solidity ^0.5.0;
contract C {
//private state variable
uint private data;
//public state variable
uint public info;
//constructor
constructor() public {
info = 10;
}
//private function
function increment(uint a) private pure returns(uint) { return a + 1; }
//public function
function updateData(uint a) public { data = a; }
function getData() public view returns(uint) { return data; }
function compute(uint a, uint b) internal pure returns (uint) { return a + b; }
}
//Derived Contract
contract E is C {
uint private result;
C private c;
constructor() public {
c = new C();
}
function getComputedResult() public {
result = compute(3, 5);
}
function getResult() public view returns(uint) { return result; }
function getData() public view returns(uint) { return c.info(); }
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First . Jalankan berbagai metode Kontrak. Untuk acara E. getComputedResult () diikuti oleh E.getResult () -
Keluaran
0: uint256: 8
Pembuat adalah fungsi khusus yang dideklarasikan menggunakan constructorkata kunci. Ini adalah fungsi opsional dan digunakan untuk menginisialisasi variabel status kontrak. Berikut adalah karakteristik utama dari seorang konstruktor.
Sebuah kontrak hanya dapat memiliki satu konstruktor.
Kode konstruktor dijalankan satu kali saat kontrak dibuat dan digunakan untuk menginisialisasi status kontrak.
Setelah kode konstruktor dijalankan, kode terakhir diterapkan ke blockchain. Kode ini mencakup fungsi publik dan kode yang dapat dijangkau melalui fungsi publik. Kode pembuat atau metode internal apa pun yang hanya digunakan oleh konstruktor tidak termasuk dalam kode akhir.
Konstruktor dapat bersifat publik atau internal.
Seorang konstruktor internal menandai kontrak sebagai abstrak.
Dalam kasus, tidak ada konstruktor yang ditentukan, konstruktor default ada dalam kontrak.
pragma solidity ^0.5.0;
contract Test {
constructor() public {}
}
Dalam kasus, kontrak dasar memiliki konstruktor dengan argumen, setiap kontrak turunan harus melewatinya.
Konstruktor basis dapat diinisialisasi secara langsung menggunakan cara berikut -
pragma solidity ^0.5.0;
contract Base {
uint data;
constructor(uint _data) public {
data = _data;
}
}
contract Derived is Base (5) {
constructor() public {}
}
Konstruktor basis dapat diinisialisasi secara tidak langsung menggunakan cara berikut -
pragma solidity ^0.5.0;
contract Base {
uint data;
constructor(uint _data) public {
data = _data;
}
}
contract Derived is Base {
constructor(uint _info) Base(_info * _info) public {}
}
Cara langsung dan tidak langsung untuk menginisialisasi kontraktor kontrak dasar tidak diperbolehkan.
Jika kontrak turunan tidak memberikan argumen kepada kontraktor kontrak dasar maka kontrak turunan akan menjadi abstrak.
Kontrak Abstrak adalah salah satu yang berisi setidaknya satu fungsi tanpa implementasi apa pun. Kontrak tersebut digunakan sebagai kontrak dasar. Umumnya kontrak abstrak berisi fungsi yang diterapkan dan juga fungsi abstrak. Kontrak turunan akan mengimplementasikan fungsi abstrak dan menggunakan fungsi yang ada jika diperlukan.
Jika kontrak turunan tidak menerapkan fungsi abstrak maka kontrak turunan ini akan ditandai sebagai abstrak.
Contoh
Coba kode berikut untuk memahami bagaimana kontrak abstrak bekerja di Solidity.
pragma solidity ^0.5.0;
contract Calculator {
function getResult() public view returns(uint);
}
contract Test is Calculator {
function getResult() public view returns(uint) {
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Keluaran
0: uint256: 3
Antarmuka mirip dengan kontrak abstrak dan dibuat menggunakan interfacekata kunci. Berikut ini adalah karakteristik utama dari sebuah antarmuka.
Antarmuka tidak dapat memiliki fungsi apa pun dengan implementasi.
Fungsi antarmuka hanya dapat berupa jenis eksternal.
Antarmuka tidak boleh memiliki konstruktor.
Antarmuka tidak boleh memiliki variabel status.
Antarmuka dapat memiliki enum, struct yang dapat diakses menggunakan notasi titik nama antarmuka.
Contoh
Coba kode berikut untuk memahami cara kerja antarmuka di Solidity.
pragma solidity ^0.5.0;
interface Calculator {
function getResult() external view returns(uint);
}
contract Test is Calculator {
constructor() public {}
function getResult() external view returns(uint){
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Note - Pilih Test dari dropdown sebelum mengklik tombol deploy.
Keluaran
0: uint256: 3
Perpustakaan mirip dengan Kontrak tetapi terutama dimaksudkan untuk digunakan kembali. Pustaka berisi fungsi yang dapat dipanggil oleh kontrak lain. Soliditas memiliki batasan tertentu dalam penggunaan Perpustakaan. Berikut adalah karakteristik utama dari Perpustakaan Soliditas.
Fungsi pustaka dapat dipanggil secara langsung jika tidak mengubah status. Itu berarti fungsi murni atau tampilan hanya bisa dipanggil dari luar perpustakaan.
Library tidak dapat dihancurkan karena dianggap tidak berkewarganegaraan.
Perpustakaan tidak dapat memiliki variabel status.
Perpustakaan tidak dapat mewarisi elemen apa pun.
Perpustakaan tidak dapat diwariskan.
Contoh
Coba kode berikut untuk memahami bagaimana Perpustakaan bekerja di Solidity.
pragma solidity ^0.5.0;
library Search {
function indexOf(uint[] storage self, uint value) public view returns (uint) {
for (uint i = 0; i < self.length; i++) if (self[i] == value) return i;
return uint(-1);
}
}
contract Test {
uint[] data;
constructor() public {
data.push(1);
data.push(2);
data.push(3);
data.push(4);
data.push(5);
}
function isValuePresent() external view returns(uint){
uint value = 4;
//search if value is present in the array using Library function
uint index = Search.indexOf(data, value);
return index;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Note - Pilih Test dari dropdown sebelum mengklik tombol deploy.
Keluaran
0: uint256: 3
Menggunakan Untuk
Arahan using A for B; dapat digunakan untuk melampirkan fungsi perpustakaan perpustakaan A ke tipe tertentu B. Fungsi ini akan menggunakan jenis pemanggil sebagai parameter pertama mereka (diidentifikasi menggunakan diri).
Contoh
Coba kode berikut untuk memahami bagaimana Perpustakaan bekerja di Solidity.
pragma solidity ^0.5.0;
library Search {
function indexOf(uint[] storage self, uint value) public view returns (uint) {
for (uint i = 0; i < self.length; i++)if (self[i] == value) return i;
return uint(-1);
}
}
contract Test {
using Search for uint[];
uint[] data;
constructor() public {
data.push(1);
data.push(2);
data.push(3);
data.push(4);
data.push(5);
}
function isValuePresent() external view returns(uint){
uint value = 4;
//Now data is representing the Library
uint index = data.indexOf(value);
return index;
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Note - Pilih Test dari dropdown sebelum mengklik tombol deploy.
Keluaran
0: uint256: 3
Solidity menyediakan opsi untuk menggunakan bahasa assembly untuk menulis perakitan inline dalam kode sumber Solidity. Kita juga dapat menulis kode assembly mandiri yang kemudian diubah menjadi bytecode. Perakitan Standalone adalah bahasa perantara untuk kompiler Soliditas dan itu mengubah kode Soliditas menjadi Majelis Mandiri dan kemudian ke kode byte. Kami dapat menggunakan bahasa yang sama dengan yang digunakan dalam Rakitan Inline untuk menulis kode dalam rakitan Standalone.
Majelis Inline
Kode perakitan sebaris dapat disisipkan dalam basis kode Soliditas untuk memiliki kontrol yang lebih halus atas EVM dan digunakan terutama saat menulis fungsi perpustakaan.
Kode perakitan ditulis di bawah assembly { ... } blok.
Contoh
Coba kode berikut untuk memahami bagaimana Perpustakaan bekerja di Solidity.
pragma solidity ^0.5.0;
library Sum {
function sumUsingInlineAssembly(uint[] memory _data) public pure returns (uint o_sum) {
for (uint i = 0; i < _data.length; ++i) {
assembly {
o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
}
}
}
}
contract Test {
uint[] data;
constructor() public {
data.push(1);
data.push(2);
data.push(3);
data.push(4);
data.push(5);
}
function sum() external view returns(uint){
return Sum.sumUsingInlineAssembly(data);
}
}
Jalankan program di atas menggunakan langkah-langkah yang disediakan di bab Aplikasi Solidity First .
Note - Pilih Test dari dropdown sebelum mengklik tombol deploy.
Keluaran
0: uint256: 15
Acara adalah anggota kontrak yang diwariskan. Suatu peristiwa dipancarkan, ia menyimpan argumen yang diteruskan dalam log transaksi. Log ini disimpan di blockchain dan dapat diakses menggunakan alamat kontrak sampai kontrak ada di blockchain. Peristiwa yang dihasilkan tidak dapat diakses dari dalam kontrak, bahkan yang telah membuat dan memancarkannya pun tidak.
Sebuah event bisa dideklarasikan dengan menggunakan kata kunci event.
//Declare an Event
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
//Emit an event
emit Deposit(msg.sender, _id, msg.value);
Contoh
Coba kode berikut untuk memahami bagaimana sebuah event bekerja di Solidity.
Pertama Buat kontrak dan keluarkan acara.
pragma solidity ^0.5.0;
contract Test {
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
function deposit(bytes32 _id) public payable {
emit Deposit(msg.sender, _id, msg.value);
}
}
Kemudian akses acara kontrak dalam kode JavaScript.
var abi = /* abi as generated using compiler */;
var ClientReceipt = web3.eth.contract(abi);
var clientReceiptContract = ClientReceipt.at("0x1234...ab67" /* address */);
var event = clientReceiptContract.Deposit(function(error, result) {
if (!error)console.log(result);
});
Ini harus mencetak detail yang mirip dengan berikut -
Keluaran
{
"returnValues": {
"_from": "0x1111...FFFFCCCC",
"_id": "0x50...sd5adb20",
"_value": "0x420042"
},
"raw": {
"data": "0x7f...91385",
"topics": ["0xfd4...b4ead7", "0x7f...1a91385"]
}
}
Solidity menyediakan berbagai fungsi untuk penanganan error. Umumnya ketika terjadi kesalahan, keadaan dikembalikan ke keadaan semula. Pemeriksaan lainnya untuk mencegah akses kode yang tidak sah. Berikut adalah beberapa metode penting yang digunakan dalam penanganan kesalahan -
assert(bool condition)- Jika kondisi tidak terpenuhi, panggilan metode ini menyebabkan opcode tidak valid dan setiap perubahan yang dilakukan pada status dikembalikan. Metode ini akan digunakan untuk kesalahan internal.
require(bool condition)- Jika kondisi tidak terpenuhi, panggilan metode ini kembali ke keadaan semula. - Metode ini digunakan untuk kesalahan dalam input atau komponen eksternal.
require(bool condition, string memory message)- Jika kondisi tidak terpenuhi, panggilan metode ini kembali ke keadaan semula. - Metode ini digunakan untuk kesalahan dalam input atau komponen eksternal. Ini memberikan opsi untuk memberikan pesan khusus.
revert() - Metode ini membatalkan eksekusi dan mengembalikan setiap perubahan yang dilakukan pada status.
revert(string memory reason)- Metode ini membatalkan eksekusi dan mengembalikan setiap perubahan yang dilakukan pada status. Ini memberikan opsi untuk memberikan pesan khusus.
Contoh
Coba kode berikut untuk memahami bagaimana penanganan kesalahan bekerja di Solidity.
pragma solidity ^0.5.0;
contract Vendor {
address public seller;
modifier onlySeller() {
require(
msg.sender == seller,
"Only seller can call this."
);
_;
}
function sell(uint amount) public payable onlySeller {
if (amount > msg.value / 2 ether)
revert("Not enough Ether provided.");
// Perform the sell operation.
}
}
Ketika dipanggil kembali, itu akan mengembalikan data heksadesimal sebagai berikut.
Keluaran
0x08c379a0 // Function selector for Error(string)
0x0000000000000000000000000000000000000000000000000000000000000020 // Data offset
0x000000000000000000000000000000000000000000000000000000000000001a // String length
0x4e6f7420656e6f7567682045746865722070726f76696465642e000000000000 // String data