Berinteraksi dengan kontrak lain dari Solidity
Dalam tutorial sebelumnya, kita belajar banyak cara menggunakan kontrak pintar pertama Anda dan menambahkan beberapa fitur ke dalamnya seperti mengontrol akses dengan pengubah(opens in a new tab) atau penanganan kesalahan di Solidity(opens in a new tab). Dalam tutorial ini kita akan mempelajari cara menggunakan kontrak pintar dari kontrak yang ada dan berinteraksi dengannya.
Kita akan membuat kontrak yang memungkinkan siapa pun untuk memiliki kontrak pintar Counter
sendiri dengan membuat pabrik untuknya, namanya adalah CounterFactory
. Pertama, ini adalah kode kontrak pintar Counter
awal kami:
1pragma solidity 0.5.17;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "You're not the owner of the contract");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "You need to use the factory");17 _;18 }1920 constructor(address owner) public {21 _owner = owner;22 _factory = msg.sender;23 }2425 function getCount() public view returns (uint256) {26 return _count;27 }2829 function increment(address caller) public onlyFactory onlyOwner(caller) {30 _count++;31 }3233}Tampilkan semuaSalin
Perhatikan bahwa kami sedikit memodifikasi kode kontrak untuk melacak alamat pabrik dan alamat pemilik kontrak. Saat Anda memanggil kode kontrak dari kontrak lain, msg.sender akan merujuk ke alamat pabrik kontrak kami. Ini poin yang sangat penting untuk dipahami karena menggunakan kontrak untuk berinteraksi dengan kontrak lain adalah praktik umum. Karena itu, Anda harus memperhatikan siapa pengirimnya dalam kasus yang rumit.
Untuk ini kami juga menambahkan pengubah onlyFactory
yang memastikan bahwa fungsi perubahan status hanya dapat dipanggil oleh pabrik yang akan meneruskan fungsi ke pemanggil asli sebagai parameter.
Di dalam CounterFactory
baru kami yang akan mengelola semua Penghitung lainnya, kami akan menambahkan pemetaan yang akan mengaitkan pemilik ke alamat kontrak penghitungnya:
1mapping(address => Counter) _counters;Salin
Di Ethereum, pemetaan sama dengan objek dalam javascript, yang memungkinkan untuk memetakan kunci jenis A ke nilai jenis B. Dalam hal ini, kami memetakan alamat pemilik dengan instance Penghitungnya.
Membuat instance Penghitung baru untuk seseorang akan terlihat seperti ini:
1 function createCounter() public {2 require (_counters[msg.sender] == Counter(0));3 _counters[msg.sender] = new Counter(msg.sender);4 }Salin
Pertama-tama kami memeriksa apakah orang tersebut sudah memiliki penghitung. Jika dia tidak memiliki penghitung, kami membuat instance penghitung baru dengan meneruskan alamatnya ke pembangun Counter
dan menetapkan instance yang baru dibuat ke pemetaan.
Untuk mendapatkan hitungan Penghitung tertentu akan terlihat seperti ini:
1function getCount(address account) public view returns (uint256) {2 require (_counters[account] != Counter(0));3 return (_counters[account].getCount());4}56function getMyCount() public view returns (uint256) {7 return (getCount(msg.sender));8}Salin
Fungsi pertama memeriksa apakah kontrak Penghitung ada untuk alamat tertentu lalu memanggil metode getCount
dari instance. Fungsi kedua: getMyCount
hanyalah akhir singkat untuk meneruskan msg.sender langsung ke fungsi getCount
.
Fungsi increment
cukup mirip tetapi meneruskan pengirim transaksi asli ke kontrak Counter
:
1function increment() public {2 require (_counters[msg.sender] != Counter(0));3 Counter(_counters[msg.sender]).increment(msg.sender);4 }Salin
Perhatikan bahwa jika dipanggil berulang kali, penghitung kami mungkin bisa menjadi korban dari overflow. Anda harus menggunakan pustaka SafeMath(opens in a new tab) sesering mungkin agar terhindar dari kasus yang mungkin terjadi ini.
Untuk menggunakan kontrak kami, Anda perlu menyediakan kode CounterFactory
dan Counter
. Saat menggunakan, misalnya di Remix, Anda perlu memilih CounterFactory.
Berikut kode lengkapnya:
1pragma solidity 0.5.17;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "You're not the owner of the contract");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "You need to use the factory");17 _;18 }1920 constructor(address owner) public {21 _owner = owner;22 _factory = msg.sender;23 }2425 function getCount() public view returns (uint256) {26 return _count;27 }2829 function increment(address caller) public onlyFactory onlyOwner(caller) {30 _count++;31 }3233}3435contract CounterFactory {3637 mapping(address => Counter) _counters;3839 function createCounter() public {40 require (_counters[msg.sender] == Counter(0));41 _counters[msg.sender] = new Counter(msg.sender);42 }4344 function increment() public {45 require (_counters[msg.sender] != Counter(0));46 Counter(_counters[msg.sender]).increment(msg.sender);47 }4849 function getCount(address account) public view returns (uint256) {50 require (_counters[account] != Counter(0));51 return (_counters[account].getCount());52 }5354 function getMyCount() public view returns (uint256) {55 return (getCount(msg.sender));56 }5758}Tampilkan semuaSalin
Setelah mengompilasi, di bagian penggunaan Remix, Anda akan memilih pabrik yang akan digunakan:
Kemudian, Anda bisa bermain dengan pabrik kontrak Anda dan memeriksa perubahan nilainya. Jika Anda ingin memangil kontrak pintar dari alamat lain, Anda perlu mengubah alamat di Akun Remix tertentu.
Terakhir diedit: @nhsz(opens in a new tab), 15 Agustus 2023