Lanjut ke konten utama

Berinteraksi dengan kontrak lain dari Solidity

kontrak pintarsolidityremixpabrikmenyebarkankomposabilitas
Tingkat lanjut
jdourlens
EthereumDev(opens in a new tab)
5 April 2020
3 bacaan singkat minute read
comp-tutorial-metadata-tip-author 0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE

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;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
Tampilkan semua
Salin

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}
5
6function 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;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
34
35contract CounterFactory {
36
37 mapping(address => Counter) _counters;
38
39 function createCounter() public {
40 require (_counters[msg.sender] == Counter(0));
41 _counters[msg.sender] = new Counter(msg.sender);
42 }
43
44 function increment() public {
45 require (_counters[msg.sender] != Counter(0));
46 Counter(_counters[msg.sender]).increment(msg.sender);
47 }
48
49 function getCount(address account) public view returns (uint256) {
50 require (_counters[account] != Counter(0));
51 return (_counters[account].getCount());
52 }
53
54 function getMyCount() public view returns (uint256) {
55 return (getCount(msg.sender));
56 }
57
58}
Tampilkan semua
Salin

Setelah mengompilasi, di bagian penggunaan Remix, Anda akan memilih pabrik yang akan digunakan:

Memilih pabrik yang akan digunakan di Remix

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

Apakah tutorial ini membantu?