Baru-baru ini saya mempelajari kembali soliditas, mengkonsolidasikan detailnya, dan menulis “Solidity Minimalist Primer” untuk digunakan pemula (orang pemrograman dapat menemukan tutorial lain), diperbarui 1-3 kali seminggu.
Semua kode dan tutorial adalah open source di GitHub: github.com/AmazingAng/WTFSolidity
Dalam Kuliah 17: Mengirim ETH, kami berbicara tentang menggunakan panggilan untuk mengirim ETH, dan dalam kuliah ini kami akan menunjukkan kepada Anda bagaimana menggunakannya untuk memanggil kontrak.
Call adalah fungsi anggota tingkat rendah dari jenis alamat, yang digunakan untuk berinteraksi dengan kontrak lain. Ini mengembalikan (bool, data), yang sesuai dengan keberhasilan panggilan dan nilai pengembalian fungsi objektif, masing-masing.
call adalah metode pengiriman ETH yang direkomendasikan secara resmi dengan memicu fungsi fallback atau receive dengan soliditas. Tidak disarankan untuk memanggil kontrak lain dengan panggilan, karena ketika Anda memanggil fungsi kontrak yang tidak aman, Anda memberikannya inisiatif. Metode yang disarankan adalah tetap memanggil fungsi setelah mendeklarasikan variabel kontrak, lihat Pelajaran 19: Memanggil Kontrak Lain. Jika kami tidak mengetahui kode sumber atau ABI kontrak pihak lain, kami tidak dapat menghasilkan variabel kontrak, tetapi kami masih dapat memanggil fungsi kontrak pihak lain melalui panggilan.
Aturan untuk menggunakan panggilan adalah sebagai berikut:

Pengkodean biner menggunakan fungsi pengkodean terstruktur abi.encodeWithSignature untuk memperoleh:

Tanda tangan fungsi adalah “Nama Fungsi (jenis parameter yang dipisahkan koma)”. Misalnya, abi.encodeWithSignature(“f(uint256,address)”, _x, _addr).
Selain itu, saat memanggil kontrak, Anda dapat menentukan jumlah ETH dan gas yang akan dikirim oleh transaksi:

Tampaknya agak rumit, jadi mari kita ambil contoh aplikasi panggilan.
Mari kita mulai dengan menulis kontrak target sederhana, OtherContract, dan menyebarkannya, kodenya pada dasarnya sama seperti pada Kuliah 19, kecuali dengan penambahan fungsi fallback.

Kontrak ini berisi variabel status x, log peristiwa yang dipicu saat ETH diterima, dan tiga fungsi:
getBalance(): Mengembalikan saldo ETH kontrak. setX(): fungsi hutang eksternal, yang dapat mengatur nilai x dan mengirim ETH ke kontrak. getX(): Membaca nilai x.
Mari kita tulis kontrak Call untuk memanggil fungsi kontrak target. Pertama-tama, tulis definisi peristiwa Respons, dan keluarkan keberhasilan dan data yang dikembalikan oleh panggilan, sehingga kita dapat mengamati nilai pengembalian.

Kami mendefinisikan fungsi callSetX untuk memanggil setX() dari kontrak target, mentransfer jumlah ETH ke msg.value, dan merilis peristiwa Response untuk menghasilkan kesuksesan dan data:

Selanjutnya, kita memanggil callSetX untuk mengubah variabel state _x menjadi 5, dan parameternya adalah alamat OtherContract dan 5, karena fungsi objektif setX() tidak mengembalikan nilai, sehingga output data dari peristiwa Response adalah 0x, yang kosong.
Mari kita panggil fungsi getX(), yang akan mengembalikan nilai kontrak target _x, dari tipe uint256. Kita dapat menggunakan abi.decode untuk memecahkan kode nilai pengembalian panggilan, data, dan membaca nilainya.

Dari output event Response, kita dapat melihat bahwa data tersebut 0x0000000000000000000000000000000000000000000000000000000000000005. Setelah abi.decode, nilai pengembalian akhir adalah 5.
Jika fungsi yang kita input ke call tidak ada dalam kontrak target, maka fungsi fallback dari kontrak target akan dipicu.

Dalam contoh di atas, kita memanggil fungsi foo yang tidak ada. Panggilan masih dapat dieksekusi dengan sukses dan mengembalikan kesuksesan, tetapi sebenarnya fungsi fallback dari kontrak target yang disebut.
Dalam pembicaraan ini, kami menunjukkan cara menggunakan panggilan fungsi tingkat rendah untuk memanggil kontrak lain. Panggilan bukanlah metode yang disarankan untuk memanggil kontrak karena tidak aman. Tetapi berguna untuk membiarkan kita memanggil kontrak target tanpa mengetahui kode sumber dan ABI.