Kuingiliana na mikataba mingine kutoka Solidity
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;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "Wewe si mmiliki wa mkataba");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "Unahitaji kutumia kiwanda");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}Onyesha yoteKumbuka 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}56function 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;23contract Counter {45 uint256 private _count;6 address private _owner;7 address private _factory;8910 modifier onlyOwner(address caller) {11 require(caller == _owner, "Wewe si mmiliki wa mkataba");12 _;13 }1415 modifier onlyFactory() {16 require(msg.sender == _factory, "Unahitaji kutumia kiwanda");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}Onyesha yoteBaada ya kuandaa, katika sehemu ya kupeleka ya Remix utachagua kiwanda kitakachopelekwa:
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
