Solidity-யிலிருந்து பிற ஒப்பந்தங்களுடன் தொடர்புகொள்ளுதல்
முந்தைய பயிற்சிகளில் உங்கள் முதல் ஸ்மார்ட் ஒப்பந்தத்தை எவ்வாறு நிறுவுவது மற்றும் மாற்றிகளுடன் அணுகலைக் கட்டுப்படுத்துதல் (opens in a new tab) அல்லது Solidity-யில் பிழைகளைக் கையாளுதல் (opens in a new tab) போன்ற சில அம்சங்களை அதில் எவ்வாறு சேர்ப்பது என்பது பற்றி நிறைய கற்றுக்கொண்டோம். இந்தப் பயிற்சியில், ஏற்கனவே உள்ள ஒப்பந்தத்திலிருந்து ஒரு ஸ்மார்ட் ஒப்பந்தத்தை எவ்வாறு நிறுவுவது மற்றும் அதனுடன் தொடர்புகொள்வது எப்படி என்பதைக் கற்றுக்கொள்வோம்.
எவரும் தமக்கென சொந்தமாக ஒரு Counter ஸ்மார்ட் ஒப்பந்தத்தை வைத்திருக்க உதவும் வகையில், அதற்கான ஒரு தொழிற்சாலையை (factory) உருவாக்குவதன் மூலம் ஒரு ஒப்பந்தத்தை உருவாக்குவோம், அதன் பெயர் CounterFactory ஆக இருக்கும். முதலில் நமது ஆரம்ப 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, "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}அனைத்தையும் காட்டுதொழிற்சாலையின் முகவரி மற்றும் ஒப்பந்த உரிமையாளரின் முகவரியைக் கண்காணிப்பதற்காக ஒப்பந்தக் குறியீட்டை நாங்கள் சற்று மாற்றியுள்ளோம் என்பதை நினைவில் கொள்ளவும். நீங்கள் மற்றொரு ஒப்பந்தத்திலிருந்து ஒரு ஒப்பந்தக் குறியீட்டை அழைக்கும்போது, msg.sender நமது ஒப்பந்தத் தொழிற்சாலையின் முகவரியைக் குறிக்கும். பிற ஒப்பந்தங்களுடன் தொடர்புகொள்ள ஒரு ஒப்பந்தத்தைப் பயன்படுத்துவது ஒரு பொதுவான நடைமுறை என்பதால், இது புரிந்துகொள்ள வேண்டிய மிக முக்கியமான விஷயமாகும். எனவே சிக்கலான சந்தர்ப்பங்களில் அனுப்புநர் யார் என்பதில் நீங்கள் கவனம் செலுத்த வேண்டும்.
இதற்காக நாங்கள் onlyFactory என்ற மாற்றியையும் சேர்த்துள்ளோம், இது நிலையை மாற்றும் சார்பை (state changing function) அசல் அழைப்பாளரை ஒரு அளவுருவாக (parameter) அனுப்பும் தொழிற்சாலையால் மட்டுமே அழைக்க முடியும் என்பதை உறுதிசெய்கிறது.
மற்ற அனைத்து Counter-களையும் நிர்வகிக்கும் நமது புதிய CounterFactory-க்குள், ஒரு உரிமையாளரை அவரது counter ஒப்பந்தத்தின் முகவரியுடன் இணைக்கும் ஒரு மேப்பிங்கை (mapping) சேர்ப்போம்:
1mapping(address => Counter) _counters;Ethereum-ல், மேப்பிங் என்பது ஜாவாஸ்கிரிப்ட்டில் உள்ள ஆப்ஜெக்ட்களுக்கு (objects) சமமானதாகும், அவை A வகையின் திறவுகோலை (key) B வகையின் மதிப்புடன் இணைக்க உதவுகின்றன. இந்த நிலையில், ஒரு உரிமையாளரின் முகவரியை அதன் Counter-இன் நிகழ்வுடன் (instance) இணைக்கிறோம்.
ஒருவருக்காக புதிய Counter-ஐ உருவாக்குவது இதுபோன்று இருக்கும்:
1 function createCounter() public {2 require (_counters[msg.sender] == Counter(0));3 _counters[msg.sender] = new Counter(msg.sender);4 }அந்த நபரிடம் ஏற்கனவே ஒரு counter உள்ளதா என்பதை முதலில் சரிபார்க்கிறோம். அவரிடம் counter இல்லை என்றால், அவரது முகவரியை Counter கன்ஸ்ட்ரக்டருக்கு (constructor) அனுப்புவதன் மூலம் புதிய counter-ஐ உருவாக்கி, புதிதாக உருவாக்கப்பட்ட நிகழ்வை மேப்பிங்கிற்கு ஒதுக்குகிறோம்.
ஒரு குறிப்பிட்ட Counter-இன் எண்ணிக்கையைப் பெற இதுபோன்று இருக்கும்:
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}முதல் சார்பு (function) கொடுக்கப்பட்ட முகவரிக்கு Counter ஒப்பந்தம் உள்ளதா என்பதைச் சரிபார்த்து, பின்னர் நிகழ்விலிருந்து getCount முறையை அழைக்கிறது. இரண்டாவது சார்பு: getMyCount என்பது msg.sender-ஐ நேரடியாக getCount சார்புக்கு அனுப்புவதற்கான ஒரு சுருக்கமான வழியாகும்.
increment சார்பு மிகவும் ஒத்திருக்கிறது, ஆனால் அசல் பரிவர்த்தனை அனுப்புநரை Counter ஒப்பந்தத்திற்கு அனுப்புகிறது:
1function increment() public {2 require (_counters[msg.sender] != Counter(0));3 Counter(_counters[msg.sender]).increment(msg.sender);4 }பல முறை அழைக்கப்பட்டால், நமது counter ஓவர்ஃப்ளோவுக்கு (overflow) பலியாகக்கூடும் என்பதை நினைவில் கொள்ளவும். சாத்தியமான இந்த நிலையிலிருந்து பாதுகாக்க, நீங்கள் முடிந்தவரை SafeMath நூலகத்தைப் (opens in a new tab) பயன்படுத்த வேண்டும்.
நமது ஒப்பந்தத்தை நிறுவ, நீங்கள் CounterFactory மற்றும் Counter ஆகிய இரண்டின் குறியீட்டையும் வழங்க வேண்டும். எடுத்துக்காட்டாக Remix-ல் நிறுவும்போது, நீங்கள் CounterFactory-ஐத் தேர்ந்தெடுக்க வேண்டும்.
முழுமையான குறியீடு இங்கே:
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}அனைத்தையும் காட்டுதொகுத்த (compiling) பிறகு, Remix நிறுவல் பிரிவில் நீங்கள் நிறுவ வேண்டிய தொழிற்சாலையைத் தேர்ந்தெடுப்பீர்கள்:
பின்னர் நீங்கள் உங்கள் ஒப்பந்தத் தொழிற்சாலையுடன் விளையாடலாம் மற்றும் மதிப்பு மாறுவதைச் சரிபார்க்கலாம். நீங்கள் வேறு முகவரியிலிருந்து ஸ்மார்ட் ஒப்பந்தத்தை அழைக்க விரும்பினால், Remix-இன் கணக்குத் தேர்வில் (Account select) முகவரியை மாற்ற வேண்டும்.
பக்கம் கடைசியாகப் புதுப்பிக்கப்பட்டது: 15 ஆகஸ்ட், 2023
