ஸ்மார்ட் ஒப்பந்தங்களின் கட்டமைப்பு
பக்கம் கடைசியாகப் புதுப்பிக்கப்பட்டது: 23 பிப்ரவரி, 2026
ஸ்மார்ட் ஒப்பந்தம் என்பது Ethereum இல் உள்ள ஒரு முகவரியில் இயங்கும் ஒரு நிரலாகும். அவை ஒரு பரிவர்த்தனையைப் பெறும்போது செயல்படக்கூடிய தரவு மற்றும் செயல்பாடுகளால் (functions) ஆனவை. ஸ்மார்ட் ஒப்பந்தத்தை உருவாக்குவது பற்றிய ஒரு கண்ணோட்டம் இங்கே.
முன்நிபந்தனைகள்
முதலில் ஸ்மார்ட் ஒப்பந்தங்கள் பற்றிப் படித்திருப்பதை உறுதிசெய்யவும். JavaScript அல்லது Python போன்ற நிரலாக்க மொழிகளை நீங்கள் ஏற்கனவே அறிந்திருக்கிறீர்கள் என்று இந்த ஆவணம் கருதுகிறது.
தரவு
எந்தவொரு ஒப்பந்தத் தரவும் ஒரு இடத்திற்கு ஒதுக்கப்பட வேண்டும்: storage அல்லது memory. ஸ்மார்ட் ஒப்பந்தத்தில் சேமிப்பகத்தை (storage) மாற்றுவது செலவுமிக்கது, எனவே உங்கள் தரவு எங்கு இருக்க வேண்டும் என்பதை நீங்கள் கருத்தில் கொள்ள வேண்டும்.
சேமிப்பகம்
நிலையான தரவு சேமிப்பகம் (storage) என்று குறிப்பிடப்படுகிறது மற்றும் இது நிலை மாறிகளால் (state variables) குறிக்கப்படுகிறது. இந்த மதிப்புகள் பிளாக்செயினில் நிரந்தரமாக சேமிக்கப்படும். தொகுக்கப்படும்போது (compile) பிளாக்செயினில் எவ்வளவு சேமிப்பகம் தேவை என்பதை ஒப்பந்தம் கண்காணிக்க, நீங்கள் அதன் வகையை (type) அறிவிக்க வேண்டும்.
1// Solidity உதாரணம்2contract SimpleStorage {3 uint storedData; // நிலை மாறி4 // ...5}1# Vyper உதாரணம்2storedData: int128நீங்கள் ஏற்கனவே பொருள் சார்ந்த (object-oriented) மொழிகளில் நிரலாக்கம் செய்திருந்தால், பெரும்பாலான வகைகளை நீங்கள் அறிந்திருக்கலாம். இருப்பினும், நீங்கள் Ethereum மேம்பாட்டிற்குப் புதியவராக இருந்தால், address உங்களுக்குப் புதியதாக இருக்கும்.
ஒரு address வகையானது 20 பைட்டுகள் அல்லது 160 பிட்களுக்குச் சமமான Ethereum முகவரியைக் கொண்டிருக்கலாம். இது முன்னணியில் 0x உடன் ஹெக்ஸாடெசிமல் குறியீட்டில் திரும்பும்.
பிற வகைகள் பின்வருமாறு:
- பூலியன் (boolean)
- முழு எண் (integer)
- நிலையான புள்ளி எண்கள் (fixed point numbers)
- நிலையான அளவு பைட் வரிசைகள் (fixed-size byte arrays)
- மாறும் அளவு பைட் வரிசைகள் (dynamically sized byte arrays)
- விகிதமுறு மற்றும் முழு எண் லிட்டரல்கள் (rational and integer literals)
- சரம் லிட்டரல்கள் (string literals)
- ஹெக்ஸாடெசிமல் லிட்டரல்கள் (hexadecimal literals)
- எனம்கள் (enums)
கூடுதல் விளக்கத்திற்கு, ஆவணங்களைப் பார்க்கவும்:
நினைவகம்
ஒரு ஒப்பந்தச் செயல்பாட்டின் (function) செயலாக்க வாழ்நாளில் மட்டுமே சேமிக்கப்படும் மதிப்புகள் நினைவக மாறிகள் (memory variables) என்று அழைக்கப்படுகின்றன. இவை பிளாக்செயினில் நிரந்தரமாக சேமிக்கப்படாததால், இவற்றைப் பயன்படுத்துவது மிகவும் மலிவானது.
EVM எவ்வாறு தரவைச் சேமிக்கிறது (Storage, Memory, and the Stack) என்பதைப் பற்றி Solidity ஆவணங்களில் (opens in a new tab) மேலும் அறிக.
சுற்றுச்சூழல் மாறிகள்
உங்கள் ஒப்பந்தத்தில் நீங்கள் வரையறுக்கும் மாறிகளுக்கு கூடுதலாக, சில சிறப்பு உலகளாவிய மாறிகள் (global variables) உள்ளன. அவை முதன்மையாக பிளாக்செயின் அல்லது தற்போதைய பரிவர்த்தனை பற்றிய தகவல்களை வழங்கப் பயன்படுத்தப்படுகின்றன.
எடுத்துக்காட்டுகள்:
| பண்பு (Prop) | நிலை மாறி (State variable) | விளக்கம் |
|---|---|---|
block.timestamp | uint256 | தற்போதைய பிளாக் எபோக் நேரமுத்திரை (timestamp) |
msg.sender | address | செய்தியை அனுப்புபவர் (தற்போதைய அழைப்பு) |
செயல்பாடுகள்
மிகவும் எளிமையான சொற்களில், செயல்பாடுகள் (functions) உள்வரும் பரிவர்த்தனைகளுக்குப் பதிலளிக்கும் வகையில் தகவலைப் பெறலாம் அல்லது தகவலை அமைக்கலாம்.
இரண்டு வகையான செயல்பாட்டு அழைப்புகள் (function calls) உள்ளன:
internal– இவை EVM அழைப்பை உருவாக்காது- உள் செயல்பாடுகள் மற்றும் நிலை மாறிகளை உள்நாட்டில் மட்டுமே அணுக முடியும் (அதாவது, தற்போதைய ஒப்பந்தம் அல்லது அதிலிருந்து பெறப்பட்ட ஒப்பந்தங்களுக்குள் இருந்து)
external– இவை EVM அழைப்பை உருவாக்குகின்றன- வெளிப்புற செயல்பாடுகள் ஒப்பந்த இடைமுகத்தின் (interface) ஒரு பகுதியாகும், அதாவது அவற்றை பிற ஒப்பந்தங்களிலிருந்தும் பரிவர்த்தனைகள் மூலமாகவும் அழைக்கலாம். ஒரு வெளிப்புற செயல்பாடு
fஐ உள்நாட்டில் அழைக்க முடியாது (அதாவது,f()வேலை செய்யாது, ஆனால்this.f()வேலை செய்யும்).
- வெளிப்புற செயல்பாடுகள் ஒப்பந்த இடைமுகத்தின் (interface) ஒரு பகுதியாகும், அதாவது அவற்றை பிற ஒப்பந்தங்களிலிருந்தும் பரிவர்த்தனைகள் மூலமாகவும் அழைக்கலாம். ஒரு வெளிப்புற செயல்பாடு
அவை public அல்லது private ஆகவும் இருக்கலாம்
publicசெயல்பாடுகளை ஒப்பந்தத்திற்குள் இருந்து உள்நாட்டிலோ அல்லது செய்திகள் வழியாக வெளிப்புறமாகவோ அழைக்கலாம்privateசெயல்பாடுகள் அவை வரையறுக்கப்பட்ட ஒப்பந்தத்திற்கு மட்டுமே தெரியும், பெறப்பட்ட ஒப்பந்தங்களில் அல்ல
செயல்பாடுகள் மற்றும் நிலை மாறிகள் இரண்டையும் பொது (public) அல்லது தனிப்பட்டதாக (private) மாற்றலாம்
ஒப்பந்தத்தில் நிலை மாறியைப் புதுப்பிப்பதற்கான ஒரு செயல்பாடு இங்கே:
1// Solidity உதாரணம்2function update_name(string value) public {3 dapp_name = value;4}stringவகையின் அளவுரு (parameter)valueசெயல்பாட்டிற்குள் அனுப்பப்படுகிறது:update_name- இது
publicஎன அறிவிக்கப்பட்டுள்ளது, அதாவது யார் வேண்டுமானாலும் இதை அணுகலாம் - இது
viewஎன அறிவிக்கப்படவில்லை, எனவே இது ஒப்பந்த நிலையை மாற்றலாம்
View செயல்பாடுகள்
இந்த செயல்பாடுகள் ஒப்பந்தத்தின் தரவின் நிலையை மாற்றாது என்று உறுதியளிக்கின்றன. பொதுவான எடுத்துக்காட்டுகள் "getter" செயல்பாடுகள் – எடுத்துக்காட்டாக, பயனரின் இருப்பைப் (balance) பெற நீங்கள் இதைப் பயன்படுத்தலாம்.
1// Solidity உதாரணம்2function balanceOf(address _owner) public view returns (uint256 _balance) {3 return ownerPizzaCount[_owner];4}1dappName: public(string)23@view4@public5def readName() -> string:6 return dappNameநிலையை மாற்றுவதாகக் கருதப்படுவது எது:
- நிலை மாறிகளுக்கு எழுதுதல்.
- நிகழ்வுகளை வெளியிடுதல் (Emitting events) (opens in a new tab).
- பிற ஒப்பந்தங்களை உருவாக்குதல் (opens in a new tab).
selfdestructஐப் பயன்படுத்துதல்.- அழைப்புகள் (calls) மூலம் ஈதரை அனுப்புதல்.
viewஅல்லதுpureஎனக் குறிக்கப்படாத எந்தவொரு செயல்பாட்டையும் அழைத்தல்.- குறைந்த-நிலை அழைப்புகளைப் (low-level calls) பயன்படுத்துதல்.
- குறிப்பிட்ட ஆப்கோடுகளைக் (opcodes) கொண்ட இன்லைன் அசெம்பிளியைப் பயன்படுத்துதல்.
Constructor செயல்பாடுகள்
ஒப்பந்தம் முதன்முதலில் பயன்படுத்தப்படும்போது (deployed) constructor செயல்பாடுகள் ஒருமுறை மட்டுமே செயல்படுத்தப்படும். பல வகுப்பு அடிப்படையிலான (class-based) நிரலாக்க மொழிகளில் உள்ள constructor ஐப் போலவே, இந்த செயல்பாடுகள் பெரும்பாலும் நிலை மாறிகளை அவற்றின் குறிப்பிட்ட மதிப்புகளுக்குத் துவக்குகின்றன.
1// Solidity உதாரணம்2// ஒப்பந்தத்தின் தரவை துவக்குகிறது, `owner` ஐ3// ஒப்பந்தத்தை உருவாக்கியவரின் முகவரிக்கு அமைக்கிறது.4constructor() public {5 // அனைத்து ஸ்மார்ட் ஒப்பந்தங்களும் அதன் செயல்பாடுகளைத் தூண்டுவதற்கு வெளிப்புற பரிவர்த்தனைகளையே நம்பியுள்ளன.6 // `msg` என்பது கொடுக்கப்பட்ட பரிவர்த்தனை தொடர்பான தரவை உள்ளடக்கிய ஒரு உலகளாவிய மாறி,7 // அனுப்புநரின் முகவரி மற்றும் பரிவர்த்தனையில் சேர்க்கப்பட்டுள்ள ETH மதிப்பு போன்றவை இதில் அடங்கும்.8 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties9 owner = msg.sender;10}அனைத்தையும் காட்டு1# Vyper உதாரணம்23@external4def __init__(_beneficiary: address, _bidding_time: uint256):5 self.beneficiary = _beneficiary6 self.auctionStart = block.timestamp7 self.auctionEnd = self.auctionStart + _bidding_timeஉள்ளமைக்கப்பட்ட செயல்பாடுகள்
உங்கள் ஒப்பந்தத்தில் நீங்கள் வரையறுக்கும் மாறிகள் மற்றும் செயல்பாடுகளுக்கு கூடுதலாக, சில சிறப்பு உள்ளமைக்கப்பட்ட செயல்பாடுகள் (built-in functions) உள்ளன. மிகவும் வெளிப்படையான எடுத்துக்காட்டு:
address.send()– Soliditysend(address)– Vyper
இவை ஒப்பந்தங்கள் மற்ற கணக்குகளுக்கு ETH ஐ அனுப்ப அனுமதிக்கின்றன.
செயல்பாடுகளை எழுதுதல்
உங்கள் செயல்பாட்டிற்குத் தேவையானது:
- அளவுரு மாறி மற்றும் வகை (அது அளவுருக்களை ஏற்றுக் கொண்டால்)
- internal/external அறிவிப்பு
- pure/view/payable அறிவிப்பு
- திரும்பும் வகை (அது ஒரு மதிப்பை வழங்கினால்)
1pragma solidity >=0.4.0 <=0.6.0;23contract ExampleDapp {4 string dapp_name; // நிலை மாறி56 // ஒப்பந்தம் பயன்படுத்தப்படும்போது (deployed) அழைக்கப்பட்டு மதிப்பைத் துவக்குகிறது7 constructor() public {8 dapp_name = "My Example dapp";9 }1011 // Get செயல்பாடு12 function read_name() public view returns(string) {13 return dapp_name;14 }1516 // Set செயல்பாடு17 function update_name(string value) public {18 dapp_name = value;19 }20}அனைத்தையும் காட்டுஒரு முழுமையான ஒப்பந்தம் இதுபோன்று இருக்கலாம். இங்கே constructor செயல்பாடு dapp_name மாறிக்கு ஆரம்ப மதிப்பை வழங்குகிறது.
நிகழ்வுகள் மற்றும் பதிவுகள்
நிகழ்வுகள் (Events) உங்கள் ஸ்மார்ட் ஒப்பந்தத்தை உங்கள் முன்பக்கம் (frontend) அல்லது பிற சந்தாதாரர் பயன்பாடுகளுடன் தொடர்பு கொள்ள உதவுகின்றன. ஒரு பரிவர்த்தனை சரிபார்க்கப்பட்டு ஒரு பிளாக்கில் சேர்க்கப்பட்டவுடன், ஸ்மார்ட் ஒப்பந்தங்கள் நிகழ்வுகளை வெளியிடலாம் மற்றும் தகவல்களைப் பதிவு செய்யலாம், பின்னர் முன்பக்கம் அதைச் செயலாக்கிப் பயன்படுத்தலாம்.
சிறுகுறிப்பு எடுத்துக்காட்டுகள்
இவை Solidity இல் எழுதப்பட்ட சில எடுத்துக்காட்டுகள். நீங்கள் குறியீட்டுடன் விளையாட விரும்பினால், Remix (opens in a new tab) இல் அவற்றுடன் தொடர்பு கொள்ளலாம்.
Hello world
1// சொற்பொருள் பதிப்பைப் (semantic versioning) பயன்படுத்தி, Solidity-இன் பதிப்பைக் குறிப்பிடுகிறது.2// மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma3pragma solidity ^0.5.10;45// `HelloWorld` என்ற பெயரில் ஒரு ஒப்பந்தத்தை வரையறுக்கிறது.6// ஒப்பந்தம் என்பது செயல்பாடுகள் மற்றும் தரவுகளின் (அதன் நிலை) தொகுப்பாகும்.7// பயன்படுத்தப்பட்டவுடன் (deployed), ஒரு ஒப்பந்தம் Ethereum பிளாக்செயினில் ஒரு குறிப்பிட்ட முகவரியில் இருக்கும்.8// மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html9contract HelloWorld {1011 // `string` வகையிலான `message` என்ற நிலை மாறியை (state variable) அறிவிக்கிறது.12 // நிலை மாறிகள் என்பவை ஒப்பந்த சேமிப்பகத்தில் நிரந்தரமாக சேமிக்கப்படும் மதிப்புகளைக் கொண்ட மாறிகள் ஆகும்.13 // `public` என்ற முக்கிய சொல் ஒப்பந்தத்திற்கு வெளியேயும் மாறிகளை அணுகக்கூடியதாக ஆக்குகிறது14 // மேலும் மற்ற ஒப்பந்தங்கள் அல்லது வாடிக்கையாளர்கள் மதிப்பை அணுக அழைக்கும் ஒரு செயல்பாட்டை உருவாக்குகிறது.15 string public message;1617 // பல class-அடிப்படையிலான object-oriented மொழிகளைப் போலவே, constructor என்பது18 // ஒப்பந்தம் உருவாக்கப்படும் போது மட்டுமே செயல்படுத்தப்படும் ஒரு சிறப்புச் செயல்பாடாகும்.19 // ஒப்பந்தத்தின் தரவைத் துவக்க Constructors பயன்படுத்தப்படுகின்றன.20 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors21 constructor(string memory initMessage) public {22 // `initMessage` என்ற string அளபுருவை (argument) ஏற்றுக்கொண்டு மதிப்பை23 // ஒப்பந்தத்தின் `message` சேமிப்பக மாறியில் (storage variable) அமைக்கிறது.24 message = initMessage;25 }2627 // ஒரு string அளபுருவை ஏற்றுக்கொள்ளும் public செயல்பாடு28 // மற்றும் `message` சேமிப்பக மாறியைப் புதுப்பிக்கிறது.29 function update(string memory newMessage) public {30 message = newMessage;31 }32}அனைத்தையும் காட்டுToken
1pragma solidity ^0.5.10;23contract Token {4 // ஒரு `address` என்பது மின்னஞ்சல் முகவரியுடன் ஒப்பிடத்தக்கது - இது Ethereum இல் ஒரு கணக்கை அடையாளம் காணப் பயன்படுகிறது.5 // முகவரிகள் ஒரு ஸ்மார்ட் ஒப்பந்தம் அல்லது வெளிப்புற (பயனர்) கணக்குகளைக் குறிக்கலாம்.6 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/types.html#address7 address public owner;89 // ஒரு `mapping` என்பது அடிப்படையில் ஒரு hash table தரவு அமைப்பாகும்.10 // இந்த `mapping` ஒரு முகவரிக்கு (டோக்கன் வைத்திருப்பவர்) ஒரு unsigned integer-ஐ (டோக்கன் இருப்பு) ஒதுக்குகிறது.11 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types12 mapping (address => uint) public balances;1314 // பிளாக்செயினில் செயல்பாடுகளைப் பதிவு செய்ய Events அனுமதிக்கின்றன.15 // ஒப்பந்த நிலை மாற்றங்களுக்கு எதிர்வினையாற்ற Ethereum வாடிக்கையாளர்கள் events-ஐக் கவனிக்கலாம்.16 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events17 event Transfer(address from, address to, uint amount);1819 // ஒப்பந்தத்தின் தரவை துவக்குகிறது, `owner` ஐ20 // ஒப்பந்தத்தை உருவாக்கியவரின் முகவரிக்கு அமைக்கிறது.21 constructor() public {22 // அனைத்து ஸ்மார்ட் ஒப்பந்தங்களும் அதன் செயல்பாடுகளைத் தூண்டுவதற்கு வெளிப்புற பரிவர்த்தனைகளையே நம்பியுள்ளன.23 // `msg` என்பது கொடுக்கப்பட்ட பரிவர்த்தனை தொடர்பான தரவை உள்ளடக்கிய ஒரு உலகளாவிய மாறி,24 // அனுப்புநரின் முகவரி மற்றும் பரிவர்த்தனையில் சேர்க்கப்பட்டுள்ள ETH மதிப்பு போன்றவை இதில் அடங்கும்.25 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties26 owner = msg.sender;27 }2829 // புதிய டோக்கன்களின் அளவை உருவாக்கி அவற்றை ஒரு முகவரிக்கு அனுப்புகிறது.30 function mint(address receiver, uint amount) public {31 // `require` என்பது சில நிபந்தனைகளைச் செயல்படுத்தப் பயன்படும் ஒரு கட்டுப்பாட்டு அமைப்பாகும்.32 // ஒரு `require` அறிக்கை `false` என மதிப்பிடப்பட்டால், ஒரு exception தூண்டப்படும்,33 // இது தற்போதைய அழைப்பின் போது நிலையில் செய்யப்பட்ட அனைத்து மாற்றங்களையும் மாற்றியமைக்கிறது (reverts).34 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions3536 // ஒப்பந்த உரிமையாளர் மட்டுமே இந்த செயல்பாட்டை அழைக்க முடியும்37 require(msg.sender == owner, "You are not the owner.");3839 // அதிகபட்ச டோக்கன்களின் அளவைச் செயல்படுத்துகிறது40 require(amount < 1e60, "Maximum issuance exceeded");4142 // `receiver` இன் இருப்பை `amount` அளவு அதிகரிக்கிறது43 balances[receiver] += amount;44 }4546 // எந்தவொரு அழைப்பாளரிடமிருந்தும் ஒரு முகவரிக்கு இருக்கும் டோக்கன்களின் அளவை அனுப்புகிறது.47 function transfer(address receiver, uint amount) public {48 // அனுப்புநரிடம் அனுப்ப போதுமான டோக்கன்கள் இருக்க வேண்டும்49 require(amount <= balances[msg.sender], "Insufficient balance.");5051 // இரண்டு முகவரிகளின் டோக்கன் இருப்புகளை சரிசெய்கிறது52 balances[msg.sender] -= amount;53 balances[receiver] += amount;5455 // முன்னர் வரையறுக்கப்பட்ட event-ஐ வெளியிடுகிறது56 emit Transfer(msg.sender, receiver, amount);57 }58}அனைத்தையும் காட்டுUnique digital asset
1pragma solidity ^0.5.10;23// பிற கோப்புகளிலிருந்து குறியீடுகளை தற்போதைய ஒப்பந்தத்தில் இறக்குமதி செய்கிறது.4// இந்த நிலையில், OpenZeppelin இலிருந்து தொடர்ச்சியான உதவி ஒப்பந்தங்கள்.5// மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files67import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";8import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";9import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";10import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";1112// வெளிப்புற ஒப்பந்தங்களிலிருந்து செயல்பாடுகள் மற்றும் முக்கிய சொற்களைப் பெற (inherit) `is` என்ற முக்கிய சொல் பயன்படுத்தப்படுகிறது.13// இந்த நிலையில், `CryptoPizza` ஆனது `IERC721` மற்றும் `ERC165` ஒப்பந்தங்களிலிருந்து பெறுகிறது.14// மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance15contract CryptoPizza is IERC721, ERC165 {16 // எண்கணித செயல்பாடுகளைப் பாதுகாப்பாகச் செய்ய OpenZeppelin இன் SafeMath நூலகத்தைப் பயன்படுத்துகிறது.17 // மேலும் அறிய: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath18 using SafeMath for uint256;1920 // Solidity இல் உள்ள Constant நிலை மாறிகள் மற்ற மொழிகளைப் போலவே இருக்கும்21 // ஆனால் compile செய்யும் நேரத்தில் மாறிலியாக (constant) இருக்கும் ஒரு வெளிப்பாட்டிலிருந்து (expression) நீங்கள் மதிப்பை ஒதுக்க வேண்டும்.22 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables23 uint256 constant dnaDigits = 10;24 uint256 constant dnaModulus = 10 ** dnaDigits;25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;2627 // Struct வகைகள் உங்கள் சொந்த வகையை வரையறுக்க அனுமதிக்கின்றன28 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs29 struct Pizza {30 string name;31 uint256 dna;32 }3334 // Pizza structs இன் வெற்று வரிசையை (array) உருவாக்குகிறது35 Pizza[] public pizzas;3637 // பீட்சா ID இலிருந்து அதன் உரிமையாளரின் முகவரிக்கு Mapping செய்கிறது38 mapping(uint256 => address) public pizzaToOwner;3940 // உரிமையாளரின் முகவரியிலிருந்து சொந்தமான டோக்கன்களின் எண்ணிக்கைக்கு Mapping செய்கிறது41 mapping(address => uint256) public ownerPizzaCount;4243 // டோக்கன் ID இலிருந்து அங்கீகரிக்கப்பட்ட முகவரிக்கு Mapping செய்கிறது44 mapping(uint256 => address) pizzaApprovals;4546 // நீங்கள் mappings-ஐ ஒன்றோடொன்று இணைக்கலாம் (nest), இந்த உதாரணம் உரிமையாளரை ஆபரேட்டர் ஒப்புதல்களுக்கு வரைபடமாக்குகிறது47 mapping(address => mapping(address => bool)) private operatorApprovals;4849 // string (பெயர்) மற்றும் DNA இலிருந்து சீரற்ற (random) பீட்சாவை உருவாக்குவதற்கான Internal செயல்பாடு50 function _createPizza(string memory _name, uint256 _dna)51 // `internal` என்ற முக்கிய சொல், இந்த செயல்பாடு52 // இந்த ஒப்பந்தம் மற்றும் இதிலிருந்து பெறப்பட்ட ஒப்பந்தங்களுக்குள் மட்டுமே தெரியும் என்பதைக் குறிக்கிறது53 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters54 internal55 // `isUnique` என்பது பீட்சா ஏற்கனவே உள்ளதா எனச் சரிபார்க்கும் ஒரு function modifier ஆகும்56 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers57 isUnique(_name, _dna)58 {59 // பீட்சாக்களை வரிசையில் (array) சேர்த்து ID ஐப் பெறுகிறது60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);6162 // பீட்சா உரிமையாளரும் தற்போதைய பயனரும் ஒருவரா எனச் சரிபார்க்கிறது63 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions6465 // address(0) என்பது பூஜ்ஜிய முகவரி என்பதை நினைவில் கொள்க,66 // இது pizza[id] இன்னும் ஒரு குறிப்பிட்ட பயனருக்கு ஒதுக்கப்படவில்லை என்பதைக் குறிக்கிறது.6768 assert(pizzaToOwner[id] == address(0));6970 // பீட்சாவை உரிமையாளருக்கு Map செய்கிறது71 pizzaToOwner[id] = msg.sender;72 ownerPizzaCount[msg.sender] = SafeMath.add(73 ownerPizzaCount[msg.sender],74 175 );76 }7778 // string (பெயர்) இலிருந்து சீரற்ற பீட்சாவை உருவாக்குகிறது79 function createRandomPizza(string memory _name) public {80 uint256 randDna = generateRandomDna(_name, msg.sender);81 _createPizza(_name, randDna);82 }8384 // string (பெயர்) மற்றும் உரிமையாளரின் (உருவாக்கியவர்) முகவரியிலிருந்து சீரற்ற DNA ஐ உருவாக்குகிறது85 function generateRandomDna(string memory _str, address _owner)86 public87 // `pure` எனக் குறிக்கப்பட்ட செயல்பாடுகள் நிலையைப் படிக்கவோ மாற்றவோ மாட்டாது என உறுதியளிக்கின்றன88 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions89 pure90 returns (uint256)91 {92 // string (பெயர்) + முகவரி (உரிமையாளர்) இலிருந்து சீரற்ற uint ஐ உருவாக்குகிறது93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +94 uint256(_owner);95 rand = rand % dnaModulus;96 return rand;97 }9899 // உரிமையாளர் கண்டறிந்த பீட்சாக்களின் வரிசையை (array) வழங்குகிறது100 function getPizzasByOwner(address _owner)101 public102 // `view` எனக் குறிக்கப்பட்ட செயல்பாடுகள் நிலையை மாற்ற மாட்டாது என உறுதியளிக்கின்றன103 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions104 view105 returns (uint256[] memory)106 {107 // மதிப்புகளைச் சேமிக்க `memory` சேமிப்பக இருப்பிடத்தைப் பயன்படுத்துகிறது108 // இந்தச் செயல்பாட்டு அழைப்பின் வாழ்க்கைச் சுழற்சிக்கு மட்டுமே.109 // மேலும் அறிய: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack110 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);111 uint256 counter = 0;112 for (uint256 i = 0; i < pizzas.length; i++) {113 if (pizzaToOwner[i] == _owner) {114 result[counter] = i;115 counter++;116 }117 }118 return result;119 }120121 // பீட்சா மற்றும் உரிமையை வேறு முகவரிக்கு மாற்றுகிறது122 function transferFrom(address _from, address _to, uint256 _pizzaId) public {123 require(_from != address(0) && _to != address(0), "Invalid address.");124 require(_exists(_pizzaId), "Pizza does not exist.");125 require(_from != _to, "Cannot transfer to the same address.");126 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");127128 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);129 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);130 pizzaToOwner[_pizzaId] = _to;131132 // இறக்குமதி செய்யப்பட்ட IERC721 ஒப்பந்தத்தில் வரையறுக்கப்பட்ட event-ஐ வெளியிடுகிறது133 emit Transfer(_from, _to, _pizzaId);134 _clearApproval(_to, _pizzaId);135 }136137 /* *138 * கொடுக்கப்பட்ட டோக்கன் ID இன் உரிமையை மற்றொரு முகவரிக்குப் பாதுகாப்பாக மாற்றுகிறது139 * இலக்கு முகவரி ஒரு ஒப்பந்தமாக இருந்தால், அது `onERC721Received` ஐச் செயல்படுத்த வேண்டும்,140 * இது பாதுகாப்பான பரிமாற்றத்தின் போது அழைக்கப்பட்டு, `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` என்ற மேஜிக் மதிப்பை வழங்கும்;141 * இல்லையெனில், பரிமாற்றம் மாற்றியமைக்கப்படும் (reverted). */142 function safeTransferFrom(address from, address to, uint256 pizzaId)143 public144 {145 // solium-disable-next-line arg-overflow146 this.safeTransferFrom(from, to, pizzaId, "");147 }148149 /* *150 * கொடுக்கப்பட்ட டோக்கன் ID இன் உரிமையை மற்றொரு முகவரிக்குப் பாதுகாப்பாக மாற்றுகிறது151 * இலக்கு முகவரி ஒரு ஒப்பந்தமாக இருந்தால், அது `onERC721Received` ஐச் செயல்படுத்த வேண்டும்,152 * இது பாதுகாப்பான பரிமாற்றத்தின் போது அழைக்கப்பட்டு, `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` என்ற மேஜிக் மதிப்பை வழங்கும்;153 * இல்லையெனில், பரிமாற்றம் மாற்றியமைக்கப்படும் (reverted). */154 function safeTransferFrom(155 address from,156 address to,157 uint256 pizzaId,158 bytes memory _data159 ) public {160 this.transferFrom(from, to, pizzaId);161 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");162 }163164 /* *165 * இலக்கு முகவரியில் `onERC721Received` ஐ அழைப்பதற்கான Internal செயல்பாடு166 * இலக்கு முகவரி ஒரு ஒப்பந்தமாக இல்லாவிட்டால் அழைப்பு செயல்படுத்தப்படாது */167 function _checkOnERC721Received(168 address from,169 address to,170 uint256 pizzaId,171 bytes memory _data172 ) internal returns (bool) {173 if (!isContract(to)) {174 return true;175 }176177 bytes4 retval = IERC721Receiver(to).onERC721Received(178 msg.sender,179 from,180 pizzaId,181 _data182 );183 return (retval == _ERC721_RECEIVED);184 }185186 // பீட்சாவை எரிக்கிறது (Burns) - டோக்கனை முழுமையாக அழிக்கிறது187 // `external` function modifier என்பது இந்தச் செயல்பாடு188 // ஒப்பந்த இடைமுகத்தின் ஒரு பகுதி மற்றும் பிற ஒப்பந்தங்கள் இதை அழைக்கலாம் என்பதாகும்189 function burn(uint256 _pizzaId) external {190 require(msg.sender != address(0), "Invalid address.");191 require(_exists(_pizzaId), "Pizza does not exist.");192 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");193194 ownerPizzaCount[msg.sender] = SafeMath.sub(195 ownerPizzaCount[msg.sender],196 1197 );198 pizzaToOwner[_pizzaId] = address(0);199 }200201 // முகவரி வாரியாக பீட்சாக்களின் எண்ணிக்கையை வழங்குகிறது202 function balanceOf(address _owner) public view returns (uint256 _balance) {203 return ownerPizzaCount[_owner];204 }205206 // id மூலம் கண்டறியப்பட்ட பீட்சாவின் உரிமையாளரை வழங்குகிறது207 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {208 address owner = pizzaToOwner[_pizzaId];209 require(owner != address(0), "Invalid Pizza ID.");210 return owner;211 }212213 // பீட்சாவின் உரிமையை மாற்ற பிற முகவரியை அங்கீகரிக்கிறது214 function approve(address _to, uint256 _pizzaId) public {215 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");216 pizzaApprovals[_pizzaId] = _to;217 emit Approval(msg.sender, _to, _pizzaId);218 }219220 // குறிப்பிட்ட பீட்சாவிற்கான அங்கீகரிக்கப்பட்ட முகவரியை வழங்குகிறது221 function getApproved(uint256 _pizzaId)222 public223 view224 returns (address operator)225 {226 require(_exists(_pizzaId), "Pizza does not exist.");227 return pizzaApprovals[_pizzaId];228 }229230 /* *231 * கொடுக்கப்பட்ட டோக்கன் ID இன் தற்போதைய ஒப்புதலை அழிக்க Private செயல்பாடு232 * கொடுக்கப்பட்ட முகவரி டோக்கனின் உண்மையான உரிமையாளராக இல்லாவிட்டால் மாற்றியமைக்கப்படும் (Reverts) */233 function _clearApproval(address owner, uint256 _pizzaId) private {234 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");235 require(_exists(_pizzaId), "Pizza does not exist.");236 if (pizzaApprovals[_pizzaId] != address(0)) {237 pizzaApprovals[_pizzaId] = address(0);238 }239 }240241 /* * கொடுக்கப்பட்ட ஆபரேட்டரின் ஒப்புதலை அமைக்கிறது அல்லது நீக்குகிறது242 * அனுப்புநரின் சார்பாக அனைத்து டோக்கன்களையும் மாற்ற ஒரு ஆபரேட்டர் அனுமதிக்கப்படுகிறார் */243 function setApprovalForAll(address to, bool approved) public {244 require(to != msg.sender, "Cannot approve own address");245 operatorApprovals[msg.sender][to] = approved;246 emit ApprovalForAll(msg.sender, to, approved);247 }248249 // ஒரு ஆபரேட்டர் கொடுக்கப்பட்ட உரிமையாளரால் அங்கீகரிக்கப்பட்டுள்ளாரா என்பதைக் கூறுகிறது250 function isApprovedForAll(address owner, address operator)251 public252 view253 returns (bool)254 {255 return operatorApprovals[owner][operator];256 }257258 // பீட்சாவின் உரிமையை எடுத்துக்கொள்கிறது - அங்கீகரிக்கப்பட்ட பயனர்களுக்கு மட்டுமே259 function takeOwnership(uint256 _pizzaId) public {260 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");261 address owner = this.ownerOf(_pizzaId);262 this.transferFrom(owner, msg.sender, _pizzaId);263 }264265 // பீட்சா உள்ளதா எனச் சரிபார்க்கிறது266 function _exists(uint256 pizzaId) internal view returns (bool) {267 address owner = pizzaToOwner[pizzaId];268 return owner != address(0);269 }270271 // முகவரி உரிமையாளரா அல்லது பீட்சாவை மாற்ற அங்கீகரிக்கப்பட்டுள்ளதா எனச் சரிபார்க்கிறது272 function _isApprovedOrOwner(address spender, uint256 pizzaId)273 internal274 view275 returns (bool)276 {277 address owner = pizzaToOwner[pizzaId];278 // இதன் காரணமாக solium சரிபார்ப்பை முடக்கு279 // https://github.com/duaraghav8/Solium/issues/175280 // solium-disable-next-line operator-whitespace281 return (spender == owner ||282 this.getApproved(pizzaId) == spender ||283 this.isApprovedForAll(owner, spender));284 }285286 // பீட்சா தனித்துவமானதா மற்றும் இதுவரை இல்லையா எனச் சரிபார்க்கவும்287 modifier isUnique(string memory _name, uint256 _dna) {288 bool result = true;289 for (uint256 i = 0; i < pizzas.length; i++) {290 if (291 keccak256(abi.encodePacked(pizzas[i].name)) ==292 keccak256(abi.encodePacked(_name)) &&293 pizzas[i].dna == _dna294 ) {295 result = false;296 }297 }298 require(result, "Pizza with such name already exists.");299 _;300 }301302 // இலக்கு முகவரி ஒரு ஒப்பந்தமா என்பதை வழங்குகிறது303 function isContract(address account) internal view returns (bool) {304 uint256 size;305 // தற்போது ஒரு முகவரியில் ஒப்பந்தம் உள்ளதா எனச் சரிபார்க்க சிறந்த வழி எதுவும் இல்லை306 // அந்த முகவரியில் உள்ள குறியீட்டின் அளவைச் சரிபார்ப்பதைத் தவிர.307 // https://ethereum.stackexchange.com/a/14016/36603 ஐப் பார்க்கவும்308 // இது எவ்வாறு செயல்படுகிறது என்பது பற்றிய கூடுதல் விவரங்களுக்கு.309 // TODO செரினிட்டி (Serenity) வெளியீட்டிற்கு முன் இதை மீண்டும் சரிபார்க்கவும், ஏனெனில் அனைத்து முகவரிகளும்310 // அப்போது ஒப்பந்தங்களாக இருக்கும்.311 // solium-disable-next-line security/no-inline-assembly312 assembly {313 size := extcodesize(account)314 }315 return size > 0;316 }317}அனைத்தையும் காட்டுமேலும் படிக்க
ஸ்மார்ட் ஒப்பந்தங்கள் பற்றிய முழுமையான கண்ணோட்டத்திற்கு Solidity மற்றும் Vyper இன் ஆவணங்களைப் பார்க்கவும்:
தொடர்புடைய தலைப்புகள்
தொடர்புடைய பயிற்சிகள்
- ஒப்பந்த அளவு வரம்பை எதிர்த்துப் போராட ஒப்பந்தங்களைக் குறைத்தல் – உங்கள் ஸ்மார்ட் ஒப்பந்தத்தின் அளவைக் குறைப்பதற்கான சில நடைமுறை குறிப்புகள்.
- நிகழ்வுகளுடன் ஸ்மார்ட் ஒப்பந்தங்களிலிருந்து தரவைப் பதிவுசெய்தல் – ஸ்மார்ட் ஒப்பந்த நிகழ்வுகள் மற்றும் தரவைப் பதிவுசெய்ய அவற்றை எவ்வாறு பயன்படுத்தலாம் என்பதற்கான அறிமுகம்.
- Solidity இலிருந்து பிற ஒப்பந்தங்களுடன் தொடர்பு கொள்ளுங்கள் – ஏற்கனவே உள்ள ஒப்பந்தத்திலிருந்து ஸ்மார்ட் ஒப்பந்தத்தை எவ்வாறு பயன்படுத்துவது மற்றும் அதனுடன் எவ்வாறு தொடர்புகொள்வது.