---
title: "Vyper ERC-721 ஒப்பந்தத்தின் வழிகாட்டி"
description: "Ryuya Nakamura-வின் ERC-721 ஒப்பந்தம் மற்றும் அது எவ்வாறு செயல்படுகிறது"
author: "ஓரி பொமரன்ட்ஸ்"
lang: ta
tags: ["Vyper", "erc-721", "Python"]
skill: beginner
breadcrumb: Vyper ERC-721
published: 2021-04-01
---

## அறிமுகம் {#introduction}

[ERC-721](/developers/docs/standards/tokens/erc-721/) தரநிலையானது பூஞ்சையற்ற வில்லைகளின் (Non-Fungible Tokens - NFT) உரிமையைக் கொண்டிருக்கப் பயன்படுகிறது.
தனிப்பட்ட வில்லைகளுக்கு இடையே எந்த வித்தியாசமும் இல்லாததால், [ERC-20](/developers/docs/standards/tokens/erc-20/) வில்லைகள் ஒரு பண்டமாகச் செயல்படுகின்றன.
இதற்கு நேர்மாறாக, ERC-721 வில்லைகள் வெவ்வேறு [பூனை கார்ட்டூன்கள்](https://www.cryptokitties.co/) அல்லது வெவ்வேறு ரியல் எஸ்டேட் சொத்துகளின் பத்திரங்கள் போன்ற ஒரே மாதிரியான ஆனால் முற்றிலும் ஒன்றல்லாத சொத்துகளுக்காக வடிவமைக்கப்பட்டுள்ளன.

இந்தக் கட்டுரையில் நாம் [Ryuya Nakamura-வின் ERC-721 ஒப்பந்தத்தை](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) பகுப்பாய்வு செய்வோம்.
இந்த ஒப்பந்தம் [Vyper](https://vyper.readthedocs.io/en/latest/index.html)-இல் எழுதப்பட்டுள்ளது, இது Solidity-ஐ விட பாதுகாப்பற்ற குறியீட்டை எழுதுவதைக் கடினமாக்கும் வகையில் வடிவமைக்கப்பட்ட Python போன்ற ஒப்பந்த மொழியாகும்.

## ஒப்பந்தம் {#contract}

```python
# @dev ERC-721 மாற்ற முடியாத வில்லை தரநிலையின் செயலாக்கம்.
# @author Ryuya Nakamura (@nrryuya)
# இதிலிருந்து மாற்றியமைக்கப்பட்டது: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy
```

Python-ஐப் போலவே Vyper-இலும் குறிப்புகள் ஒரு ஹாஷ் (`ethereum.ercs`) குறியீட்டுடன் தொடங்கி வரியின் இறுதி வரை தொடரும். மனிதர்கள் படிக்கக்கூடிய ஆவணங்களை உருவாக்க [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html)-ஆல் `@<keyword>` உள்ளடங்கிய குறிப்புகள் பயன்படுத்தப்படுகின்றன.

```python
from vyper.interfaces import ERC721

implements: ERC721
```

ERC-721 இடைமுகம் Vyper மொழியிலேயே கட்டமைக்கப்பட்டுள்ளது.
[குறியீட்டு வரையறையை நீங்கள் இங்கே காணலாம்](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py).
இடைமுக வரையறை Vyper-க்கு பதிலாக Python-இல் எழுதப்பட்டுள்ளது, ஏனெனில் இடைமுகங்கள் தொகுதிச்சங்கிலிக்குள் மட்டுமல்லாமல், Python-இல் எழுதப்பட்டிருக்கக்கூடிய வெளிப்புற கிளையண்டிலிருந்து தொகுதிச்சங்கிலிக்கு ஒரு பரிவர்த்தனையை அனுப்பும்போதும் பயன்படுத்தப்படுகின்றன.

முதல் வரி இடைமுகத்தை இறக்குமதி செய்கிறது, இரண்டாவது வரி அதை நாம் இங்கு செயல்படுத்துகிறோம் என்பதைக் குறிப்பிடுகிறது.

```python
#pragma version >0.3.10
```

```python
#pragma version >0.3.10
```
### ERC721Receiver இடைமுகம்

```python
# safeTransferFrom() மூலம் அழைக்கப்படும் ஒப்பந்தத்திற்கான இடைமுகம்
interface ERC721Receiver:
    def onERC721Received(
```

ERC-721 இரண்டு வகையான பரிமாற்றங்களை ஆதரிக்கிறது:

- `transferFrom`, இது அனுப்புநரை எந்தவொரு இலக்கு முகவரியையும் குறிப்பிட அனுமதிக்கிறது மற்றும் பரிமாற்றத்திற்கான பொறுப்பை அனுப்புநரின் மீது வைக்கிறது. இதன் பொருள் நீங்கள் செல்லுபடியாகாத முகவரிக்கு பரிமாற்றம் செய்யலாம், அவ்வாறு செய்தால் NFT நிரந்தரமாக இழக்கப்படும்.
- `safeTransferFrom`, இது இலக்கு முகவரி ஒரு ஒப்பந்தமா என்பதைச் சரிபார்க்கிறது. அப்படியானால், ERC-721 ஒப்பந்தம் பெறும் ஒப்பந்தத்திடம் NFT-ஐப் பெற விரும்புகிறதா என்று கேட்கும்.

`safeTransferFrom` கோரிக்கைகளுக்குப் பதிலளிக்க, பெறும் ஒப்பந்தம் `ERC721Receiver`-ஐச் செயல்படுத்த வேண்டும்.

```python
            _operator: address,
            _from: address,
```

`_from` முகவரி என்பது வில்லை இன் தற்போதைய உரிமையாளர் ஆகும். `_operator` முகவரி என்பது பரிமாற்றத்தைக் கோரியவர் (அனுமதித்தொகைகள் காரணமாக, இவை இரண்டும் ஒன்றாக இருக்க வேண்டியதில்லை). மரபுப்படி, இந்த ஒப்பந்தத்தில் உள்ள பெரும்பாலான செயல்பாட்டு அளவுருக்கள் அடிக்கோடிட்டு (`_`) தொடங்குகின்றன.

```python
            _tokenId: uint256,
```

ERC-721 வில்லை ஐடிகள் 256 பிட்களாகும். பொதுவாக அவை வில்லை எதைக் குறிக்கிறதோ அதன் விளக்கத்தை ஹாஷ் செய்வதன் மூலம் உருவாக்கப்படுகின்றன.

```python
            _data: Bytes[1024]
```

கோரிக்கையானது 1024 பைட்டுகள் வரையிலான பயனர் தரவைக் கொண்டிருக்கலாம்.

```python
        ) -> bytes4: nonpayable
```

ஒரு ஒப்பந்தம் தற்செயலாக ஒரு பரிமாற்றத்தை ஏற்கும் நிகழ்வுகளைத் தடுக்க, திரும்பப் பெறும் மதிப்பு ஒரு பூலியன் அல்ல, மாறாக ஒரு குறிப்பிட்ட நான்கு-பைட் மதிப்பு, அதாவது `onERC721Received`-இன் செயல்பாட்டுத் தேர்வி (function selector) ஆகும். ஒரு வில்லை ஐ ஏற்கும் போது பெறும் ஒப்பந்தம் அதன் சொந்த நிலையை மாற்றக்கூடும் என்பதால், இந்தச் செயல்பாடு `nonpayable` ஆகும்.
### நிகழ்வுகள்

தொகுதிச்சங்கிலிக்கு வெளியே உள்ள பயனர்கள் மற்றும் சேவையகங்களுக்கு நிகழ்வுகளைத் தெரிவிக்க [நிகழ்வுகள்](/developers/docs/smart-contracts/anatomy/#events-and-logs) வெளியிடப்படுகின்றன. நிகழ்வுகளின் உள்ளடக்கம் தொகுதிச்சங்கிலியில் உள்ள ஒப்பந்தங்களுக்குக் கிடைக்காது என்பதை நினைவில் கொள்ளவும். மூன்று ERC-721 நிகழ்வுகள் நாம் இறக்குமதி செய்த `IERC721` இடைமுகத்தால் வரையறுக்கப்பட்டுள்ளன, எனவே இந்த ஒப்பந்தம் அவற்றை தானாகவே அறிவிக்காது; கீழே உள்ள பரிமாற்றச் செயல்பாடுகளில் நாம் காணப்போவது போல, இது அவற்றை `log IERC721.<Event>(...)` மூலம் வெளியிடுகிறது.

`Transfer` (`sender`, `receiver`, `token_id`) என்பது ஒரு NFT-இன் உரிமையில் ஏற்படும் மாற்றத்தைப் புகாரளிக்கிறது. இது ERC-20 Transfer நிகழ்வைப் போன்றது, ஆனால் நாம் ஒரு தொகைக்குப் பதிலாக `token_id`-ஐப் புகாரளிக்கிறோம். சுழி முகவரி யாருக்கும் சொந்தமானது அல்ல, எனவே மரபுப்படி வில்லைகளின் உருவாக்கம் மற்றும் அழிவைப் புகாரளிக்க அதைப் பயன்படுத்துகிறோம். இதற்கு ஒரு விதிவிலக்கு ஒப்பந்த உருவாக்கம் ஆகும், இதன் போது `Transfer`-ஐ வெளியிடாமல் எத்தனை NFT-களையும் உருவாக்கி ஒதுக்கலாம்.

ஒரு ERC-721 ஒப்புதல் என்பது ERC-20 அனுமதித்தொகையைப் போன்றது: ஒரு குறிப்பிட்ட முகவரி ஒரு குறிப்பிட்ட வில்லை ஐப் பரிமாற்றம் செய்ய அனுமதிக்கப்படுகிறது, மேலும் அந்த அங்கீகரிக்கப்பட்ட முகவரி அமைக்கப்படும்போதோ அல்லது மீண்டும் உறுதிப்படுத்தப்படும்போதோ `Approval` (`owner`, `approved`, `token_id`) வெளியிடப்படுகிறது. இது ஒப்பந்தங்கள் ஒரு வில்லை ஐ ஏற்கும் போது பதிலளிப்பதற்கான ஒரு வழிமுறையை வழங்குகிறது. ஒப்பந்தங்களால் நிகழ்வுகளைக் கேட்க முடியாது, எனவே நீங்கள் வில்லை ஐ அவற்றுக்குப் பரிமாற்றம் செய்தால், அவற்றிற்கு அது "தெரியாது". இந்த வழியில் உரிமையாளர் முதலில் ஒரு ஒப்புதலைச் சமர்ப்பித்து, பின்னர் ஒப்பந்தத்திற்கு ஒரு கோரிக்கையை அனுப்புகிறார்: "வில்லை X-ஐப் பரிமாற்றம் செய்ய நான் உங்களுக்கு ஒப்புதல் அளித்துள்ளேன், தயவுசெய்து ... செய்யுங்கள்". இது ERC-721 தரநிலையை ERC-20 தரநிலைக்கு ஒத்ததாக மாற்றுவதற்கான ஒரு வடிவமைப்புத் தேர்வாகும். ERC-721 வில்லைகள் பூஞ்சையற்றவை என்பதால், ஒரு ஒப்பந்தம் வில்லை இன் உரிமையைப் பார்ப்பதன் மூலம் ஒரு குறிப்பிட்ட வில்லை ஐப் பெற்றுள்ளது என்பதையும் அடையாளம் காண முடியும்.

இறுதியாக, ஒரு உரிமையாளருக்கு ஒரு _ஆபரேட்டர்_ (operator) இயக்கப்படும்போது அல்லது முடக்கப்படும்போது `ApprovalForAll` (`owner`, `operator`, `approved`) வெளியிடப்படுகிறது. ஒரு கணக்கின் குறிப்பிட்ட வகையிலான அனைத்து வில்லைகளையும் (ஒரு குறிப்பிட்ட ஒப்பந்தத்தால் நிர்வகிக்கப்படுபவை) நிர்வகிக்கக்கூடிய ஒரு ஆபரேட்டரைக் கொண்டிருப்பது சில நேரங்களில் பயனுள்ளதாக இருக்கும், இது ஒரு அதிகாரப் பத்திரம் (power of attorney) போன்றது. எடுத்துக்காட்டாக, நான் ஆறு மாதங்களாகத் தொடர்புகொள்ளவில்லையா என்பதைச் சரிபார்த்து, அவ்வாறு இருந்தால் எனது சொத்துகளை எனது வாரிசுகளுக்குப் பகிர்ந்தளிக்கும் ஒரு ஒப்பந்தத்திற்கு அத்தகைய அதிகாரத்தை நான் வழங்க விரும்பலாம் (அவர்களில் ஒருவர் அதைக் கேட்டால் மட்டுமே, ஒரு பரிவர்த்தனையால் அழைக்கப்படாமல் ஒப்பந்தங்களால் எதையும் செய்ய முடியாது). ERC-20-இல் நாம் ஒரு பரம்பரை ஒப்பந்தத்திற்கு அதிக அனுமதித்தொகையை வழங்க முடியும், ஆனால் வில்லைகள் பூஞ்சையற்றவை என்பதால் ERC-721-க்கு அது வேலை செய்யாது. இது அதற்குச் சமமானதாகும். `approved` மதிப்பானது நிகழ்வு ஒரு ஒப்புதலுக்கானதா அல்லது ஒப்புதலைத் திரும்பப் பெறுவதற்கானதா என்பதை நமக்குத் தெரிவிக்கிறது.
### நிலை மாறிகள்

இந்த மாறிகள் வில்லைகளின் தற்போதைய நிலையைக் கொண்டுள்ளன: எவை கிடைக்கின்றன மற்றும் அவற்றை யார் வைத்திருக்கிறார்கள். இவற்றில் பெரும்பாலானவை `HashMap` பொருள்களாகும், இவை [இரண்டு வகைகளுக்கு இடையே இருக்கும் ஒரு திசை மேப்பிங்குகள்](https://vyper.readthedocs.io/en/latest/types.html#mappings) ஆகும்.

```python
# @dev NFT ஐடியிலிருந்து அதை வைத்திருக்கும் முகவரிக்கு மேப்பிங்.
idToOwner: HashMap[uint256, address]

# @dev NFT ஐடியிலிருந்து அங்கீகரிக்கப்பட்ட முகவரிக்கு மேப்பிங்.
idToApprovals: HashMap[uint256, address]
```

எத்திரியம்-இல் பயனர் மற்றும் ஒப்பந்த அடையாளங்கள் 160-பிட் முகவரிகளால் குறிக்கப்படுகின்றன. இந்த இரண்டு மாறிகளும் வில்லை ஐடிகளிலிருந்து அவற்றின் உரிமையாளர்களுக்கும் அவற்றைப் பரிமாற்றம் செய்ய அங்கீகரிக்கப்பட்டவர்களுக்கும் (ஒவ்வொன்றுக்கும் அதிகபட்சம் ஒன்று) மேப் செய்கின்றன. எத்திரியம்-இல், துவக்கப்படாத தரவு எப்போதும் சுழியாகும், எனவே உரிமையாளர் அல்லது அங்கீகரிக்கப்பட்ட பரிமாற்றுபவர் இல்லை என்றால் அந்த வில்லைக்கான மதிப்பு சுழியாகும்.

```python
# @dev உரிமையாளர் முகவரியிலிருந்து அவரது வில்லைகளின் எண்ணிக்கைக்கு மேப்பிங்.
ownerToNFTokenCount: HashMap[address, uint256]
```

இந்த மாறி ஒவ்வொரு உரிமையாளருக்குமான வில்லைகளின் எண்ணிக்கையைக் கொண்டுள்ளது. உரிமையாளர்களிடமிருந்து வில்லைகளுக்கு எந்த மேப்பிங்கும் இல்லை, எனவே ஒரு குறிப்பிட்ட உரிமையாளர் வைத்திருக்கும் வில்லைகளை அடையாளம் காண ஒரே வழி, தொகுதிச்சங்கிலியின் நிகழ்வு வரலாற்றைத் திரும்பிப் பார்த்து பொருத்தமான `Transfer` நிகழ்வுகளைக் காண்பதுதான். நம்மிடம் அனைத்து NFT-களும் எப்போது உள்ளன என்பதையும், மேலும் பின்னோக்கிப் பார்க்கத் தேவையில்லை என்பதையும் அறிய இந்த மாறியைப் பயன்படுத்தலாம்.

இந்த அல்காரிதம் பயனர் இடைமுகங்கள் மற்றும் வெளிப்புற சேவையகங்களுக்கு மட்டுமே வேலை செய்யும் என்பதை நினைவில் கொள்ளவும். தொகுதிச்சங்கிலியிலேயே இயங்கும் குறியீட்டால் கடந்த கால நிகழ்வுகளைப் படிக்க முடியாது.

```python
# @dev உரிமையாளர் முகவரியிலிருந்து ஆபரேட்டர் முகவரிகளின் மேப்பிங்கிற்கு மேப்பிங்.
ownerToOperators: HashMap[address, HashMap[address, bool]]
```

ஒரு கணக்கு ஒன்றுக்கு மேற்பட்ட ஆபரேட்டர்களைக் கொண்டிருக்கலாம். அவற்றைக் கண்காணிக்க ஒரு எளிய `HashMap` போதுமானதல்ல, ஏனெனில் ஒவ்வொரு திறவுகோல்-உம் ஒரு ஒற்றை மதிப்புக்கு வழிவகுக்கிறது. அதற்குப் பதிலாக, நீங்கள் `HashMap[address, bool]`-ஐ மதிப்பாகப் பயன்படுத்தலாம். முன்னிருப்பாக ஒவ்வொரு முகவரிக்கான மதிப்பும் `False` ஆகும், அதாவது அது ஒரு ஆபரேட்டர் அல்ல. தேவைக்கேற்ப நீங்கள் மதிப்புகளை `True` என அமைக்கலாம்.

```python
# @dev வில்லை ஐ அச்சிடக்கூடிய அச்சிடுபவரின் முகவரி
minter: address
```

புதிய வில்லைகள் எப்படியாவது உருவாக்கப்பட வேண்டும். இந்த ஒப்பந்தத்தில் அவ்வாறு செய்ய அனுமதிக்கப்பட்ட ஒரே ஒரு நிறுவனம் உள்ளது, அது `minter` ஆகும். எடுத்துக்காட்டாக, ஒரு விளையாட்டுக்கு இது போதுமானதாக இருக்கலாம். பிற நோக்கங்களுக்காக, மிகவும் சிக்கலான வணிக தர்க்கத்தை உருவாக்குவது அவசியமாக இருக்கலாம்.

```python
# @dev ஆதரிக்கப்படும் ERC165 இடைமுக ஐடிகளின் நிலையான பட்டியல்
SUPPORTED_INTERFACES: constant(bytes4[2]) = [
    # ERC165-இன் ERC165 இடைமுக ஐடி
    0x01ffc9a7,
    # ERC721-இன் ERC165 இடைமுக ஐடி
    0x80ac58cd,
]
```

[ERC-165](https://eips.ethereum.org/EIPS/eip-165) ஆனது, பயன்பாடுகள் அதனுடன் எவ்வாறு தொடர்பு கொள்ளலாம், எந்த ERC-களுக்கு அது இணங்குகிறது என்பதை ஒரு ஒப்பந்தம் வெளிப்படுத்துவதற்கான ஒரு வழிமுறையைக் குறிப்பிடுகிறது. `SUPPORTED_INTERFACES` என்பது இந்த ஒப்பந்தம் இணங்கும் இரண்டு நான்கு-பைட் இடைமுக ஐடிகளின் நிலையான பட்டியலாகும்: ERC-165 மற்றும் ERC-721.
### செயல்பாடுகள் {#functions}

இவைதான் உண்மையில் ERC-721-ஐச் செயல்படுத்தும் செயல்பாடுகள் ஆகும்.

#### ஆக்கி

```python
@deploy
def __init__():
```

Python-ஐப் போலவே Vyper-இலும், ஆக்கிச் செயல்பாடு `__init__` என்று அழைக்கப்படுகிறது. இது `@deploy` அலங்காரத்துடன் (decoration) குறிக்கப்பட்டுள்ளது, அதாவது ஒப்பந்தம் பயன்படுத்தப்படும்போது இது ஒரு முறை இயங்கும்.

```python
    """
    @dev ஒப்பந்த ஆக்கி.
    """
```

Python மற்றும் Vyper-இல், பல வரி சரத்தைக் குறிப்பிடுவதன் மூலமும் (இது `"""` உடன் தொடங்கி முடிவடையும்), அதை எந்த வகையிலும் பயன்படுத்தாமலும் நீங்கள் ஒரு குறிப்பை உருவாக்கலாம். இந்தக் குறிப்புகளில் [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html)-உம் அடங்கும்.

```python
    self.minter = msg.sender
```

நிலை மாறிகளை அணுக நீங்கள் `self.<variable name>`-ஐப் பயன்படுத்துகிறீர்கள் (மீண்டும், Python-இல் உள்ளதைப் போலவே). ஆக்கியானது ஒப்பந்தத்தைப் பயன்படுத்திய கணக்கை `minter` ஆகப் பதிவு செய்கிறது.
#### காட்சிச் செயல்பாடுகள்

இவை தொகுதிச்சங்கிலியின் நிலையை மாற்றாத செயல்பாடுகளாகும், எனவே அவை வெளிப்புறமாக அழைக்கப்பட்டால் இலவசமாக இயக்கப்படலாம். காட்சிச் செயல்பாடுகள் ஒரு ஒப்பந்தத்தால் அழைக்கப்பட்டால், அவை இன்னும் ஒவ்வொரு கணு-விலும் இயக்கப்பட வேண்டும், எனவே எரிவாயு செலவாகும்.

```python
@view
@external
```

ஒரு செயல்பாட்டு வரையறைக்கு முன்னதாக அட் குறியீட்டுடன் (`@`) தொடங்கும் இந்த முக்கியச் சொற்கள் _அலங்காரங்கள்_ (decorations) என்று அழைக்கப்படுகின்றன. ஒரு செயல்பாட்டை அழைக்கக்கூடிய சூழ்நிலைகளை அவை குறிப்பிடுகின்றன.

- `@view` இந்தச் செயல்பாடு ஒரு காட்சி என்பதைக் குறிப்பிடுகிறது.
- `@external` இந்தக் குறிப்பிட்ட செயல்பாட்டைப் பரிவர்த்தனைகள் மற்றும் பிற ஒப்பந்தங்களால் அழைக்க முடியும் என்பதைக் குறிப்பிடுகிறது.

```python
def supportsInterface(interface_id: bytes4) -> bool:
```

Python-க்கு நேர்மாறாக, Vyper ஒரு [நிலையான தட்டச்சு செய்யப்பட்ட மொழி](https://wikipedia.org/wiki/Type_system#Static_type_checking) (static typed language) ஆகும். [தரவு வகையை](https://vyper.readthedocs.io/en/latest/types.html) அடையாளம் காணாமல் நீங்கள் ஒரு மாறியையோ அல்லது செயல்பாட்டு அளவுருவையோ அறிவிக்க முடியாது. இந்த நிலையில் உள்ளீட்டு அளவுரு `bytes4` ஆகும், இது ஒரு நான்கு-பைட் மதிப்பு, மற்றும் வெளியீடு ஒரு பூலியன் மதிப்பாகும்.

```python
    """
    @dev இடைமுக அடையாளம் ERC-165-இல் குறிப்பிடப்பட்டுள்ளது.
    @param interface_id இடைமுகத்தின் ஐடி
    """
    return interface_id in SUPPORTED_INTERFACES
```

`interface_id` ஆனது `SUPPORTED_INTERFACES` பட்டியலில் உள்ள இடைமுக ஐடிகளில் ஒன்றாக இருந்தால் `True`-ஐத் திருப்பி அனுப்பும்.

```python
### காட்சிச் செயல்பாடுகள் ###
```

பயனர்களுக்கும் பிற ஒப்பந்தங்களுக்கும் வில்லைகள் பற்றிய தகவல்களைக் கிடைக்கச் செய்யும் காட்சிச் செயல்பாடுகள் இவை.

```python
@view
@external
def balanceOf(_owner: address) -> uint256:
    """
    @dev `_owner` வைத்திருக்கும் NFT-களின் எண்ணிக்கையைத் திருப்பி அனுப்புகிறது.
         `_owner` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும். சுழி முகவரிக்கு ஒதுக்கப்பட்ட NFT-கள் செல்லுபடியாகாதவையாகக் கருதப்படும்.
    @param _owner யாருக்கான இருப்பை வினவ வேண்டுமோ அந்த முகவரி.
    """
    assert _owner != empty(address)
```

இந்த வரி `_owner` சுழி முகவரி அல்ல என்பதை [உறுதிப்படுத்துகிறது](https://vyper.readthedocs.io/en/latest/statements.html#assert), இது `empty(address)` என எழுதப்பட்டுள்ளது. அது சுழி முகவரியாக இருந்தால், ஒரு பிழை ஏற்பட்டு செயல்பாடு மீளமைக்கப்படும்.

```python
    return self.ownerToNFTokenCount[_owner]

@view
@external
def ownerOf(_tokenId: uint256) -> address:
    """
    @dev NFT-இன் உரிமையாளரின் முகவரியைத் திருப்பி அனுப்புகிறது.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
    @param _tokenId ஒரு NFT-க்கான அடையாளங்காட்டி.
    """
    owner: address = self.idToOwner[_tokenId]
    # `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்
    assert owner != empty(address)
    return owner
```

எத்திரியம் மெய்நிகர் இயந்திரத்தில் (EVM) மதிப்பு சேமிக்கப்படாத எந்தவொரு சேமிப்பகமும் சுழியாகும். `_tokenId`-இல் வில்லை இல்லை என்றால், `self.idToOwner[_tokenId]`-இன் மதிப்பு சுழியாகும். அந்த நிலையில் செயல்பாடு மீளமைக்கப்படும்.

```python
@view
@external
def getApproved(_tokenId: uint256) -> address:
    """
    @dev ஒரு ஒற்றை NFT-க்கான அங்கீகரிக்கப்பட்ட முகவரியைப் பெறுகிறது.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
    @param _tokenId எந்த NFT-இன் ஒப்புதலை வினவ வேண்டுமோ அதன் ஐடி.
    """
    # `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்
    assert self.idToOwner[_tokenId] != empty(address)
    return self.idToApprovals[_tokenId]
```

`getApproved` சுழியைத் திருப்பி அனுப்ப _முடியும்_ என்பதை நினைவில் கொள்ளவும். வில்லை செல்லுபடியாகும் என்றால் அது `self.idToApprovals[_tokenId]`-ஐத் திருப்பி அனுப்பும். ஒப்புதல் அளிப்பவர் இல்லை என்றால் அந்த மதிப்பு சுழியாகும்.

```python
@view
@external
def isApprovedForAll(_owner: address, _operator: address) -> bool:
    """
    @dev `_operator` என்பவர் `_owner`-க்கான அங்கீகரிக்கப்பட்ட ஆபரேட்டரா என்பதைச் சரிபார்க்கிறது.
    @param _owner NFT-களை வைத்திருக்கும் முகவரி.
    @param _operator உரிமையாளரின் சார்பாகச் செயல்படும் முகவரி.
    """
    return (self.ownerToOperators[_owner])[_operator]
```

இந்த ஒப்பந்தத்தில் `_owner`-இன் அனைத்து வில்லைகளையும் நிர்வகிக்க `_operator` அனுமதிக்கப்படுகிறாரா என்பதை இந்தச் செயல்பாடு சரிபார்க்கிறது. பல ஆபரேட்டர்கள் இருக்க முடியும் என்பதால், இது இரண்டு நிலை HashMap ஆகும்.
#### பரிமாற்ற உதவிச் செயல்பாடுகள்

இந்தச் செயல்பாடுகள் வில்லைகளைப் பரிமாற்றம் செய்யும் அல்லது நிர்வகிக்கும் செயல்பாடுகளைச் செயல்படுத்துகின்றன.

```python

### பரிமாற்ற உதவிச் செயல்பாடுகள் ###

@view
@internal
```

இந்த `@internal` அலங்காரம், அதே ஒப்பந்தத்திற்குள் உள்ள பிற செயல்பாடுகளிலிருந்து மட்டுமே இந்தச் செயல்பாட்டை அணுக முடியும் என்பதைக் குறிக்கிறது. மரபுப்படி, இந்தச் செயல்பாட்டுப் பெயர்களும் அடிக்கோடிட்டு (`_`) தொடங்குகின்றன.

```python
def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool:
    """
    @dev கொடுக்கப்பட்ட செலவிடுபவர் கொடுக்கப்பட்ட வில்லை ஐடியைப் பரிமாற்றம் செய்ய முடியுமா என்பதைத் திருப்பி அனுப்புகிறது
    @param spender வினவ வேண்டிய செலவிடுபவரின் முகவரி
    @param tokenId பரிமாற்றம் செய்யப்பட வேண்டிய வில்லை இன் uint256 ஐடி
    @return bool msg.sender கொடுக்கப்பட்ட வில்லை ஐடிக்கு அங்கீகரிக்கப்பட்டுள்ளாரா,
        உரிமையாளரின் ஆபரேட்டரா அல்லது வில்லை இன் உரிமையாளரா என்பது
    """
    owner: address = self.idToOwner[_tokenId]
    spenderIsOwner: bool = owner == _spender
    spenderIsApproved: bool = _spender == self.idToApprovals[_tokenId]
    spenderIsApprovedForAll: bool = (self.ownerToOperators[owner])[_spender]
    return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll
```

ஒரு முகவரி ஒரு வில்லை ஐப் பரிமாற்றம் செய்ய அனுமதிக்கப்பட மூன்று வழிகள் உள்ளன:

1. முகவரி வில்லை இன் உரிமையாளராக இருப்பது
2. அந்த வில்லை ஐச் செலவிட முகவரி அங்கீகரிக்கப்பட்டிருப்பது
3. முகவரி வில்லை இன் உரிமையாளருக்கான ஆபரேட்டராக இருப்பது

மேலே உள்ள செயல்பாடு நிலையை மாற்றாததால் அது ஒரு காட்சியாக இருக்கலாம். இயக்கச் செலவுகளைக் குறைக்க, ஒரு காட்சியாக இருக்க _முடியும்_ எந்தவொரு செயல்பாடும் ஒரு காட்சியாக இருக்க _வேண்டும்_.

```python
@internal
def _addTokenTo(_to: address, _tokenId: uint256):
    """
    @dev கொடுக்கப்பட்ட முகவரிக்கு ஒரு NFT-ஐச் சேர்க்கிறது
         `_tokenId` யாருக்காவது சொந்தமாக இருந்தால் பிழையை எறியும்.
    """
    # `_tokenId` யாருக்காவது சொந்தமாக இருந்தால் பிழையை எறியும்
    assert self.idToOwner[_tokenId] == empty(address)
    # உரிமையாளரை மாற்றவும்
    self.idToOwner[_tokenId] = _to
    # எண்ணிக்கை கண்காணிப்பை மாற்றவும்
    self.ownerToNFTokenCount[_to] += 1


@internal
def _removeTokenFrom(_from: address, _tokenId: uint256):
    """
    @dev கொடுக்கப்பட்ட முகவரியிலிருந்து ஒரு NFT-ஐ நீக்குகிறது
         `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்.
    """
    # `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்
    assert self.idToOwner[_tokenId] == _from
    # உரிமையாளரை மாற்றவும்
    self.idToOwner[_tokenId] = empty(address)
    # எண்ணிக்கை கண்காணிப்பை மாற்றவும்
    self.ownerToNFTokenCount[_from] -= 1
```

ஒரு பரிமாற்றத்தில் சிக்கல் ஏற்படும் போது நாம் அழைப்பை மீளமைக்கிறோம்.

```python
@internal
def _clearApproval(_owner: address, _tokenId: uint256):
    """
    @dev கொடுக்கப்பட்ட முகவரியின் ஒப்புதலை அழிக்கிறது
         `_owner` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்.
    """
    # `_owner` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்
    assert self.idToOwner[_tokenId] == _owner
    if self.idToApprovals[_tokenId] != empty(address):
        # ஒப்புதல்களை மீட்டமைக்கவும்
        self.idToApprovals[_tokenId] = empty(address)
```

தேவைப்பட்டால் மட்டுமே மதிப்பை மாற்றவும். நிலை மாறிகள் சேமிப்பகத்தில் வாழ்கின்றன. சேமிப்பகத்தில் எழுதுவது EVM (எத்திரியம் மெய்நிகர் இயந்திரம்) செய்யும் மிகவும் விலையுயர்ந்த செயல்பாடுகளில் ஒன்றாகும் ([எரிவாயு](/developers/docs/gas/) அடிப்படையில்). எனவே, அதைக் குறைப்பது ஒரு நல்ல யோசனையாகும், ஏற்கனவே உள்ள மதிப்பை எழுதுவது கூட அதிக செலவைக் கொண்டுள்ளது.

```python
@internal
def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address):
    """
    @dev ஒரு NFT-இன் பரிமாற்றத்தைச் செயல்படுத்துகிறது.
         `msg.sender` தற்போதைய உரிமையாளராக, அங்கீகரிக்கப்பட்ட ஆபரேட்டராக அல்லது இந்த NFT-க்கான அங்கீகரிக்கப்பட்ட
         முகவரி ஆக இல்லாவிட்டால் பிழையை எறியும். (குறிப்பு: தனிப்பட்ட செயல்பாட்டில் `msg.sender` அனுமதிக்கப்படாது, எனவே `_sender`-ஐ அனுப்பவும்.)
         `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்.
         `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
    """
```

வில்லைகளைப் பரிமாற்றம் செய்ய இரண்டு வழிகள் (வழக்கமான மற்றும் பாதுகாப்பான) இருப்பதால் இந்த உள்ளகச் செயல்பாட்டை நாம் கொண்டுள்ளோம், ஆனால் தணிக்கை செய்வதை எளிதாக்க குறியீட்டில் ஒரே ஒரு இடத்தில் மட்டுமே அதைச் செய்ய விரும்புகிறோம்.

```python
    # தேவைகளைச் சரிபார்க்கவும்
    assert self._isApprovedOrOwner(_sender, _tokenId)
    # `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்
    assert _to != empty(address)
    # ஒப்புதலை அழிக்கவும். `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்
    self._clearApproval(_from, _tokenId)
    # NFT-ஐ நீக்கவும். `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்
    self._removeTokenFrom(_from, _tokenId)
    # NFT-ஐச் சேர்க்கவும்
    self._addTokenTo(_to, _tokenId)
    # பரிமாற்றத்தைப் பதிவு செய்யவும்
    log IERC721.Transfer(sender=_from, receiver=_to, token_id=_tokenId)
```

Vyper-இல் ஒரு நிகழ்வை வெளியிட நீங்கள் `log` அறிக்கையைப் பயன்படுத்துகிறீர்கள் ([மேலும் விவரங்களுக்கு இங்கே பார்க்கவும்](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging)). நிகழ்வுகள் இறக்குமதி செய்யப்பட்ட இடைமுகத்தைச் சேர்ந்தவை என்பதால், நாம் அவற்றை `IERC721.Transfer` எனக் குறிப்பிட்டு அவற்றின் புலங்களை முக்கியச் சொல் மூலம் அனுப்புகிறோம்.
```python

### பரிமாற்றச் செயல்பாடுகள் ###

@external
@payable
def transferFrom(_from: address, _to: address, _tokenId: uint256):
    """
    @dev `msg.sender` தற்போதைய உரிமையாளராக, அங்கீகரிக்கப்பட்ட ஆபரேட்டராக அல்லது இந்த NFT-க்கான அங்கீகரிக்கப்பட்ட
         முகவரி ஆக இல்லாவிட்டால் பிழையை எறியும்.
         `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்.
         `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
    @notice `_to` முகவரியால் NFT-களைப் பெற முடியுமா என்பதை உறுதிப்படுத்துவது அழைப்பாளரின் பொறுப்பாகும், இல்லையெனில்
            அவை நிரந்தரமாக இழக்கப்படலாம்.
    @param _from NFT-இன் தற்போதைய உரிமையாளர்.
    @param _to புதிய உரிமையாளர்.
    @param _tokenId பரிமாற்றம் செய்ய வேண்டிய NFT.
    """
    self._transferFrom(_from, _to, _tokenId, msg.sender)
```

இந்தச் செயல்பாடு உங்களை ஒரு தன்னிச்சையான முகவரிக்குப் பரிமாற்றம் செய்ய அனுமதிக்கிறது. அந்த முகவரி ஒரு பயனராகவோ அல்லது வில்லைகளைப் பரிமாற்றம் செய்யத் தெரிந்த ஒரு ஒப்பந்தமாகவோ இல்லாவிட்டால், நீங்கள் பரிமாற்றம் செய்யும் எந்த வில்லையும் அந்த முகவரியிலேயே சிக்கிக்கொண்டு பயனற்றதாகிவிடும்.

`IERC721` இடைமுகம் `transferFrom`, `safeTransferFrom` மற்றும் `approve` ஆகியவற்றை payable என அறிவிப்பதால், `@payable` அலங்காரம் இங்கு உள்ளது, எனவே இடைமுகத்தைச் செயல்படுத்தும் ஒரு ஒப்பந்தம் அந்த கையொப்பங்களுடன் பொருந்த வேண்டும்.

```python
@external
@payable
def safeTransferFrom(
        _from: address,
        _to: address,
        _tokenId: uint256,
        _data: Bytes[1024]=b""
    ):
    """
    @dev ஒரு NFT-இன் உரிமையை ஒரு முகவரியிலிருந்து மற்றொரு முகவரிக்குப் பரிமாற்றம் செய்கிறது.
         `msg.sender` தற்போதைய உரிமையாளராக, அங்கீகரிக்கப்பட்ட ஆபரேட்டராக அல்லது இந்த NFT-க்கான
         அங்கீகரிக்கப்பட்ட முகவரி ஆக இல்லாவிட்டால் பிழையை எறியும்.
         `_from` தற்போதைய உரிமையாளராக இல்லாவிட்டால் பிழையை எறியும்.
         `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
         `_to` ஒரு ஒப்பந்தமாக இருந்தால், அது `_to`-இல் `onERC721Received`-ஐ அழைக்கும் மற்றும்
         திருப்பி அனுப்பும் மதிப்பு `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` ஆக இல்லாவிட்டால் பிழையை எறியும்.
    @param _from NFT-இன் தற்போதைய உரிமையாளர்.
    @param _to புதிய உரிமையாளர்.
    @param _tokenId பரிமாற்றம் செய்ய வேண்டிய NFT.
    @param _data `_to`-க்கான அழைப்பில் அனுப்பப்படும், குறிப்பிட்ட வடிவம் இல்லாத கூடுதல் தரவு.
    """
    self._transferFrom(_from, _to, _tokenId, msg.sender)
```

முதலில் பரிமாற்றத்தைச் செய்வது சரியானது, ஏனெனில் ஏதேனும் சிக்கல் இருந்தால் எப்படியும் நாம் மீளமைக்கப் போகிறோம், எனவே அழைப்பில் செய்யப்பட்ட அனைத்தும் ரத்து செய்யப்படும்.

```python
    if _to.is_contract: # `_to` ஒரு ஒப்பந்த முகவரியா என்பதைச் சரிபார்க்கவும்
```

முதலில் முகவரி ஒரு ஒப்பந்தமா (அதில் குறியீடு உள்ளதா) என்பதைச் சரிபார்க்கவும். இல்லையெனில், அது ஒரு பயனர் முகவரி என்றும், பயனரால் வில்லையைப் பயன்படுத்தவோ அல்லது பரிமாற்றம் செய்யவோ முடியும் என்றும் கருதிக்கொள்ளவும். ஆனால் இது உங்களுக்கு ஒரு தவறான பாதுகாப்பு உணர்வைத் தர அனுமதிக்க வேண்டாம். யாருக்கும் தனிப்பட்ட திறவுகோல் தெரியாத ஒரு முகவரிக்கு நீங்கள் வில்லைகளைப் பரிமாற்றம் செய்தால், `safeTransferFrom`-ஐப் பயன்படுத்தினாலும் நீங்கள் வில்லைகளை இழக்க நேரிடலாம்.

```python
        returnValue: bytes4 = extcall ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data)
```

இலக்கு ஒப்பந்தத்தால் ERC-721 வில்லைகளைப் பெற முடியுமா என்பதைப் பார்க்க அதை அழைக்கவும். Vyper 0.4-இல் பிற ஒப்பந்தங்களுக்கான அழைப்புகள் குறிக்கப்பட வேண்டும், எனவே அழைப்புக்கு முன்னொட்டாக `extcall` சேர்க்கப்பட்டுள்ளது.

```python
        # பரிமாற்ற இலக்கு 'onERC721Received'-ஐச் செயல்படுத்தாத ஒரு ஒப்பந்தமாக இருந்தால் பிழையை எறியும்
        assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes4)
```

இலக்கு ஒரு ஒப்பந்தமாக இருந்து, ஆனால் அது ERC-721 வில்லைகளை ஏற்கவில்லை என்றால் (அல்லது இந்த குறிப்பிட்ட பரிமாற்றத்தை ஏற்க வேண்டாம் என்று முடிவு செய்தால்), மீளமைக்கவும்.

```python
@external
@payable
def approve(_approved: address, _tokenId: uint256):
    """
    @dev ஒரு NFT-க்கான அங்கீகரிக்கப்பட்ட முகவரியை அமைக்கவும் அல்லது மீண்டும் உறுதிப்படுத்தவும். சுழி முகவரி என்பது அங்கீகரிக்கப்பட்ட முகவரி இல்லை என்பதைக் குறிக்கிறது.
         `msg.sender` தற்போதைய NFT உரிமையாளராக அல்லது தற்போதைய உரிமையாளரின் அங்கீகரிக்கப்பட்ட ஆபரேட்டராக இல்லாவிட்டால் பிழையை எறியும்.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும். (குறிப்பு: இது EIP-இல் எழுதப்படவில்லை)
         `_approved` தற்போதைய உரிமையாளராக இருந்தால் பிழையை எறியும். (குறிப்பு: இது EIP-இல் எழுதப்படவில்லை)
    @param _approved கொடுக்கப்பட்ட NFT ஐடி-க்கு அங்கீகரிக்கப்பட வேண்டிய முகவரி.
    @param _tokenId அங்கீகரிக்கப்பட வேண்டிய வில்லை இன் ஐடி.
    """
    owner: address = self.idToOwner[_tokenId]
    # `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்
    assert owner != empty(address)
    # `_approved` தற்போதைய உரிமையாளராக இருந்தால் பிழையை எறியும்
    assert _approved != owner
```

மரபுப்படி, உங்களுக்கு ஒரு அங்கீகரிப்பாளர் இருக்க வேண்டாம் என நீங்கள் விரும்பினால், உங்களை அல்லாமல் சுழி முகவரியை நியமிக்க வேண்டும்.

```python
    # தேவைகளைச் சரிபார்க்கவும்
    senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender
    senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender]
    assert (senderIsOwner or senderIsApprovedForAll)
```

ஒரு அங்கீகாரத்தை அமைக்க நீங்கள் உரிமையாளராகவோ அல்லது உரிமையாளரால் அங்கீகரிக்கப்பட்ட ஒரு ஆபரேட்டராகவோ இருக்க வேண்டும்.

```python
    # அங்கீகாரத்தை அமைக்கவும்
    self.idToApprovals[_tokenId] = _approved
    log IERC721.Approval(owner=owner, approved=_approved, token_id=_tokenId)


@external
def setApprovalForAll(_operator: address, _approved: bool):
    """
    @dev `msg.sender`-இன் அனைத்துச் சொத்துகளையும் நிர்வகிக்க ஒரு மூன்றாம் தரப்பினருக்கான ("ஆபரேட்டர்") அங்கீகாரத்தை
         இயக்குகிறது அல்லது முடக்குகிறது. இது ApprovalForAll நிகழ்வையும் வெளியிடுகிறது.
         `_operator` என்பது `msg.sender` ஆக இருந்தால் பிழையை எறியும். (குறிப்பு: இது EIP-இல் எழுதப்படவில்லை)
    @notice அந்த நேரத்தில் அனுப்புநரிடம் எந்த வில்லைகளும் இல்லாவிட்டாலும் இது செயல்படும்.
    @param _operator அங்கீகரிக்கப்பட்ட ஆபரேட்டர்களின் தொகுப்பில் சேர்க்க வேண்டிய முகவரி.
    @param _approved ஆபரேட்டர்கள் அங்கீகரிக்கப்பட்டால் True, அங்கீகாரத்தை ரத்து செய்ய false.
    """
    # `_operator` என்பது `msg.sender` ஆக இருந்தால் பிழையை எறியும்
    assert _operator != msg.sender
    self.ownerToOperators[msg.sender][_operator] = _approved
    log IERC721.ApprovalForAll(owner=msg.sender, operator=_operator, approved=_approved)
```
#### புதிய வில்லைகளை அச்சிடுதல் மற்றும் ஏற்கனவே உள்ளவற்றை அழித்தல் {#mint-burn}

ஒப்பந்தத்தை உருவாக்கிய கணக்கு `minter` ஆகும், இது புதிய NFT-களை அச்சிட அங்கீகரிக்கப்பட்ட சூப்பர் பயனராகும். இருப்பினும், ஏற்கனவே உள்ள வில்லைகளை எரிக்க அது கூட அனுமதிக்கப்படவில்லை. உரிமையாளர் அல்லது உரிமையாளரால் அங்கீகரிக்கப்பட்ட ஒரு நிறுவனத்தால் மட்டுமே அதைச் செய்ய முடியும்.

```python
### அச்சிடு & எரி செயல்பாடுகள் ###

@external
def mint(_to: address, _tokenId: uint256) -> bool:
```

இந்தச் செயல்பாடு எப்போதும் `True`-ஐத் திருப்பி அனுப்புகிறது, ஏனெனில் செயல்பாடு தோல்வியுற்றால் அது மீளமைக்கப்படும்.

```python
    """
    @dev வில்லை களை அச்சிடு செய்வதற்கான செயல்பாடு
         `msg.sender` அச்சிடுபவராக இல்லாவிட்டால் பிழையை எறியும்.
         `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்.
         `_tokenId` யாருக்காவது சொந்தமாக இருந்தால் பிழையை எறியும்.
    @param _to அச்சிடு செய்யப்பட்ட வில்லை களைப் பெறும் முகவரி.
    @param _tokenId அச்சிடு செய்ய வேண்டிய வில்லை ஐடி.
    @return செயல்பாடு வெற்றிகரமாக இருந்ததா என்பதைக் குறிக்கும் பூலியன்.
    """
    # `msg.sender` அச்சிடுபவராக இல்லாவிட்டால் பிழையை எறியும்
    assert msg.sender == self.minter
```

அச்சிடுபவர் (ERC-721 ஒப்பந்தத்தை உருவாக்கிய கணக்கு) மட்டுமே புதிய வில்லைகளை அச்சிட முடியும். எதிர்காலத்தில் அச்சிடுபவரின் அடையாளத்தை மாற்ற விரும்பினால் இது ஒரு சிக்கலாக இருக்கலாம். ஒரு தயாரிப்பு ஒப்பந்தத்தில், அச்சிடுபவர் தனது அச்சிடும் சலுகைகளை வேறொருவருக்குப் பரிமாற்றம் செய்ய அனுமதிக்கும் ஒரு செயல்பாட்டை நீங்கள் விரும்பலாம்.

```python
    # `_to` சுழி முகவரி ஆக இருந்தால் பிழையை எறியும்
    assert _to != ZERO_ADDRESS
    # NFT-ஐச் சேர்க்கவும். `_tokenId` யாருக்காவது சொந்தமாக இருந்தால் பிழையை எறியும்
    self._addTokenTo(_to, _tokenId)
    log Transfer(ZERO_ADDRESS, _to, _tokenId)
    return True
```

மரபுப்படி, புதிய வில்லைகளை அச்சிடுவது சுழி முகவரியிலிருந்து ஒரு பரிமாற்றமாகக் கணக்கிடப்படுகிறது.

```python

@external
def burn(_tokenId: uint256):
    """
    @dev ஒரு குறிப்பிட்ட ERC-721 வில்லை ஐ எரி செய்கிறது.
         `msg.sender` தற்போதைய உரிமையாளராக, அங்கீகரிக்கப்பட்ட ஆபரேட்டராக அல்லது இந்த NFT-க்கான அங்கீகரிக்கப்பட்ட
         முகவரி ஆக இல்லாவிட்டால் பிழையை எறியும்.
         `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்.
    @param _tokenId எரி செய்யப்பட வேண்டிய ERC-721 வில்லை இன் uint256 ஐடி.
    """
    # தேவைகளைச் சரிபார்க்கவும்
    assert self._isApprovedOrOwner(msg.sender, _tokenId)
    owner: address = self.idToOwner[_tokenId]
    # `_tokenId` செல்லுபடியாகும் NFT ஆக இல்லாவிட்டால் பிழையை எறியும்
    assert owner != ZERO_ADDRESS
    self._clearApproval(owner, _tokenId)
    self._removeTokenFrom(owner, _tokenId)
    log Transfer(owner, ZERO_ADDRESS, _tokenId)
```

ஒரு வில்லையைப் பரிமாற்றம் செய்ய அனுமதிக்கப்பட்ட எவரும் அதை எரிக்கவும் அனுமதிக்கப்படுவார்கள். எரிப்பது சுழி முகவரிக்குப் பரிமாற்றம் செய்வதற்குச் சமமானதாகத் தோன்றினாலும், சுழி முகவரி உண்மையில் வில்லையைப் பெறுவதில்லை. இது வில்லைக்காகப் பயன்படுத்தப்பட்ட அனைத்துச் சேமிப்பகத்தையும் விடுவிக்க அனுமதிக்கிறது, இது பரிவர்த்தனையின் எரிவாயு செலவைக் குறைக்கலாம்.

## இந்த ஒப்பந்தத்தைப் பயன்படுத்துதல் {#using-contract}

Solidity-க்கு நேர்மாறாக, Vyper-இல் மரபுரிமை (inheritance) இல்லை. இது குறியீட்டைத் தெளிவாக்குவதற்கும், எனவே பாதுகாப்பதை எளிதாக்குவதற்கும் செய்யப்பட்ட ஒரு வேண்டுமென்றே வடிவமைப்புத் தேர்வாகும். எனவே உங்கள் சொந்த Vyper ERC-721 ஒப்பந்தத்தை உருவாக்க, நீங்கள் [இந்த ஒப்பந்தத்தை](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) எடுத்து, நீங்கள் விரும்பும் வணிக தர்க்கத்தைச் செயல்படுத்த அதை மாற்றியமைக்கிறீர்கள்.

## முடிவுரை {#conclusion}

மதிப்பாய்வுக்காக, இந்த ஒப்பந்தத்தில் உள்ள சில மிக முக்கியமான கருத்துகள் இங்கே:

- பாதுகாப்பான பரிமாற்றத்துடன் ERC-721 வில்லைகளைப் பெற, ஒப்பந்தங்கள் `ERC721Receiver` இடைமுகத்தைச் செயல்படுத்த வேண்டும்.
- நீங்கள் பாதுகாப்பான பரிமாற்றத்தைப் பயன்படுத்தினாலும், தனிப்பட்ட திறவுகோல் தெரியாத முகவரிக்கு வில்லைகளை அனுப்பினால் அவை இன்னும் சிக்கிக்கொள்ளலாம்.
- ஒரு செயல்பாட்டில் சிக்கல் ஏற்படும் போது, தோல்வி மதிப்பைத் திருப்பி அனுப்புவதை விட, அழைப்பை `revert` செய்வது (மீளமைப்பது) ஒரு நல்ல யோசனையாகும்.
- ERC-721 வில்லைகளுக்கு ஒரு உரிமையாளர் இருக்கும்போது அவை உள்ளன.
- ஒரு NFT-ஐப் பரிமாற்றம் செய்ய அங்கீகரிக்கப்பட மூன்று வழிகள் உள்ளன. நீங்கள் உரிமையாளராக இருக்கலாம், ஒரு குறிப்பிட்ட வில்லைக்கு ஒப்புதல் பெற்றிருக்கலாம் அல்லது உரிமையாளரின் அனைத்து வில்லைகளுக்கும் ஒரு ஆபரேட்டராக இருக்கலாம்.
- கடந்த கால நிகழ்வுகள் தொகுதிச்சங்கிலிக்கு வெளியே மட்டுமே தெரியும். தொகுதிச்சங்கிலிக்குள் இயங்கும் குறியீட்டால் அவற்றைப் பார்க்க முடியாது.

இப்போது சென்று பாதுகாப்பான Vyper ஒப்பந்தங்களைச் செயல்படுத்துங்கள்.

[எனது மேலும் பல பணிகளுக்கு இங்கே பார்க்கவும்](https://cryptodocguy.pro/).
