Ruka kwenda kwenye maudhui makuu

Kuingiliana na mikataba mingine kutoka Solidity

smart contracts
solidity
remix
deploying
composability
Advanced
jdourlens
5 Aprili 2020
4 minute read

Katika mafunzo yaliyopita tulijifunza mengi jinsi ya kupeleka mkataba-erevu wako wa kwanza na kuongeza baadhi ya vipengele kwake kama vile kudhibiti ufikiaji kwa virekebishaji (opens in a new tab) au kushughulikia makosa katika Solidity (opens in a new tab). Katika funzo hili tutajifunza jinsi ya kupeleka mkataba-erevu kutoka kwa mkataba uliopo na kuingiliana nao.

Tutaunda mkataba unaomwezesha mtu yeyote kuwa na mkataba-erevu wake wa Counter kwa kuunda kiwanda chake, jina lake litakuwa CounterFactory. Kwanza huu hapa msimbo wa mkataba-erevu wetu wa awali wa Counter:

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, "Wewe si mmiliki wa mkataba");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "Unahitaji kutumia kiwanda");
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}
Onyesha yote

Kumbuka kuwa tumerekebisha kidogo msimbo wa mkataba ili kufuatilia anwani ya kiwanda na anwani ya mmiliki wa mkataba. Unapoita msimbo wa mkataba kutoka kwa mkataba mwingine, msg.sender itarejelea anwani ya kiwanda chetu cha mkataba. Hili ni jambo muhimu sana kuelewa kwani kutumia mkataba kuingiliana na mikataba mingine ni jambo la kawaida. Kwa hivyo unapaswa kuwa mwangalifu kuhusu nani ni mtumaji katika visa tata.

Kwa ajili hii, pia tuliongeza kirekebishaji cha onlyFactory kinachohakikisha kuwa chaguo za kukokotoa zinazobadilisha hali zinaweza kuitwa tu na kiwanda ambacho kitapitisha mwitaji halisi kama kigezo.

Ndani ya CounterFactory yetu mpya ambayo itasimamia Kaunta zingine zote, tutaongeza ramani ambayo itahusisha mmiliki na anwani ya mkataba wake wa kaunta:

1mapping(address => Counter) _counters;

Katika Ethereum, ramani ni sawa na vitu katika javascript, zinawezesha kuweka ufunguo wa aina A kwa thamani ya aina B. Katika hali hii tunapanga anwani ya mmiliki na mfano wa Kaunta yake.

Kuanzisha Kaunta mpya kwa ajili ya mtu kutaonekana kama hivi:

1 function createCounter() public {
2 require (_counters[msg.sender] == Counter(0));
3 _counters[msg.sender] = new Counter(msg.sender);
4 }

Kwanza tunakagua kama mtu huyo tayari anamiliki kaunta. Ikiwa hamiliki kaunta, tunaanzisha kaunta mpya kwa kupitisha anwani yake kwa kijenzi cha Counter na kukabidhi mfano mpya ulioundwa kwenye ramani.

Ili kupata hesabu ya Kaunta maalum itaonekana kama hivi:

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}

Chaguo la kwanza la kukokotoa hukagua ikiwa mkataba wa Kaunta upo kwa anwani fulani na kisha huita mbinu ya getCount kutoka kwa mfano. Chaguo la pili la kukokotoa: getMyCount ni njia fupi tu ya kupitisha msg.sender moja kwa moja kwenye chaguo la kukokotoa la getCount.

Chaguo la kukokotoa la increment linafanana kabisa lakini hupitisha mtumaji asili wa muamala kwa mkataba wa Counter:

1function increment() public {
2 require (_counters[msg.sender] != Counter(0));
3 Counter(_counters[msg.sender]).increment(msg.sender);
4 }

Kumbuka kwamba ikiitwa mara nyingi sana, kaunta yetu inaweza kuwa mwathirika wa kufurika. Unapaswa kutumia maktaba ya SafeMath (opens in a new tab) kadri iwezekanavyo ili kujikinga na hali hii inayowezekana.

Ili kupeleka mkataba wetu, utahitaji kutoa msimbo wa CounterFactory na Counter. Wakati wa kupeleka kwa mfano katika Remix utahitaji kuchagua CounterFactory.

Huu hapa msimbo kamili:

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, "Wewe si mmiliki wa mkataba");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "Unahitaji kutumia kiwanda");
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}
Onyesha yote

Baada ya kuandaa, katika sehemu ya kupeleka ya Remix utachagua kiwanda kitakachopelekwa:

Ukichagua kiwanda cha kupelekwa katika Remix

Kisha unaweza kucheza na kiwanda chako cha mkataba na uangalie mabadiliko ya thamani. Ikiwa ungependa kuita mkataba-erevu kutoka kwa anwani tofauti utahitaji kubadilisha anwani katika uteuzi wa Akaunti ya Remix.

Ukurasa ulihaririwa mwisho: 15 Agosti 2023

Umesaidika na mafunzo haya?