مرکزی مواد پر جائیں

⁦Vyper ERC-721⁩ کنٹریکٹ کا جائزہ

Vyper
erc-721
Python
ابتدائی
اوری پومرانٹز
۱ اپریل، ۲۰۲۱
25 منٹ کا مطالعہ

تعارف

ERC-721 معیار کا استعمال نان فنجیبل ٹوکنز (NFT) کی ملکیت رکھنے کے لیے کیا جاتا ہے۔ ERC-20 ٹوکنز ایک شے (commodity) کے طور پر برتاؤ کرتے ہیں، کیونکہ انفرادی ٹوکنز کے درمیان کوئی فرق نہیں ہوتا۔ اس کے برعکس، ERC-721 ٹوکنز ایسے اثاثوں کے لیے بنائے گئے ہیں جو ملتے جلتے تو ہیں لیکن بالکل ایک جیسے نہیں، جیسے کہ مختلف بلیوں کے کارٹونز (opens in a new tab) یا رئیل اسٹیٹ کے مختلف حصوں کے ملکیتی حقوق۔

اس مضمون میں ہم ریویا ناکامورا کے ERC-721 کنٹریکٹ (opens in a new tab) کا تجزیہ کریں گے۔ یہ کنٹریکٹ Vyper (opens in a new tab) میں لکھا گیا ہے، جو کہ Python جیسی ایک کنٹریکٹ زبان ہے جسے اس طرح ڈیزائن کیا گیا ہے کہ اس میں غیر محفوظ کوڈ لکھنا Solidity کی نسبت زیادہ مشکل ہو۔

کنٹریکٹ

# @dev ERC-721 نان فنجیبل ٹوکن اسٹینڈرڈ کا نفاذ۔
# @author Ryuya Nakamura (@nrryuya)
# یہاں سے ترمیم شدہ: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy

Vyper میں تبصرے (comments)، بالکل Python کی طرح، ایک ہیش (#) سے شروع ہوتے ہیں اور لائن کے آخر تک جاری رہتے ہیں۔ وہ تبصرے جن میں @<keyword> شامل ہوتا ہے، انہیں NatSpec (opens in a new tab) انسانوں کے پڑھنے کے قابل دستاویزات (documentation) تیار کرنے کے لیے استعمال کرتا ہے۔

from vyper.interfaces import ERC721

implements: ERC721

ERC-721 انٹرفیس Vyper زبان میں پہلے سے موجود (built-in) ہے۔ آپ یہاں کوڈ کی تعریف دیکھ سکتے ہیں (opens in a new tab)۔ انٹرفیس کی تعریف Vyper کے بجائے Python میں لکھی گئی ہے، کیونکہ انٹرفیسز نہ صرف بلاک چین کے اندر استعمال ہوتے ہیں، بلکہ کسی بیرونی کلائنٹ سے بلاک چین کو ٹرانزیکشن بھیجتے وقت بھی استعمال ہوتے ہیں، جو کہ Python میں لکھا ہو سکتا ہے۔

پہلی لائن انٹرفیس کو امپورٹ کرتی ہے، اور دوسری یہ بتاتی ہے کہ ہم اسے یہاں نافذ (implement) کر رہے ہیں۔

ERC721Receiver انٹرفیس

# safeTransferFrom() کے ذریعے کال کیے گئے کنٹریکٹ کا انٹرفیس
interface ERC721Receiver:
    def onERC721Received(

ERC-721 دو قسم کی منتقلی کو سپورٹ کرتا ہے:

  • transferFrom، جو بھیجنے والے کو کسی بھی منزل کا پتہ بتانے کی اجازت دیتا ہے اور منتقلی کی ذمہ داری بھیجنے والے پر ڈالتا ہے۔ اس کا مطلب ہے کہ آپ کسی غلط پتے پر بھی منتقلی کر سکتے ہیں، جس صورت میں NFT ہمیشہ کے لیے ضائع ہو جاتا ہے۔
  • safeTransferFrom، جو یہ چیک کرتا ہے کہ آیا منزل کا پتہ کوئی کنٹریکٹ ہے۔ اگر ایسا ہے، تو ERC-721 کنٹریکٹ وصول کرنے والے کنٹریکٹ سے پوچھتا ہے کہ کیا وہ NFT وصول کرنا چاہتا ہے۔

safeTransferFrom درخواستوں کا جواب دینے کے لیے وصول کرنے والے کنٹریکٹ کو ERC721Receiver نافذ کرنا پڑتا ہے۔

            _operator: address,
            _from: address,

_from پتہ ٹوکن کا موجودہ مالک ہے۔ _operator پتہ وہ ہے جس نے منتقلی کی درخواست کی تھی (یہ دونوں ایک جیسے نہیں بھی ہو سکتے، الاؤنسز کی وجہ سے)۔

            _tokenId: uint256,

ERC-721 ٹوکن آئی ڈیز 256 bits کی ہوتی ہیں۔ عام طور پر یہ اس چیز کی تفصیل کی ہیشنگ کر کے بنائی جاتی ہیں جس کی ٹوکن نمائندگی کرتا ہے۔

            _data: Bytes[1024]

درخواست میں صارف کا 1024 bytes تک کا ڈیٹا ہو سکتا ہے۔

        ) -> bytes32: view

ایسے معاملات کو روکنے کے لیے جن میں کوئی کنٹریکٹ غلطی سے منتقلی قبول کر لے، واپسی کی قدر (return value) بولین (boolean) نہیں ہوتی، بلکہ ایک مخصوص قدر کے ساتھ 256 bits ہوتی ہے۔

یہ فنکشن ایک view ہے، جس کا مطلب ہے کہ یہ بلاک چین کی حالت کو پڑھ سکتا ہے، لیکن اسے تبدیل نہیں کر سکتا۔

ایونٹس

ایونٹس کو بلاک چین سے باہر صارفین اور سرورز کو واقعات سے آگاہ کرنے کے لیے خارج (emit) کیا جاتا ہے۔ یاد رکھیں کہ ایونٹس کا مواد بلاک چین پر موجود کنٹریکٹس کے لیے دستیاب نہیں ہوتا۔

یہ ERC-20 ٹرانسفر ایونٹ کی طرح ہے، سوائے اس کے کہ ہم رقم کے بجائے tokenId رپورٹ کرتے ہیں۔ صفر ایڈریس کا کوئی مالک نہیں ہوتا، اس لیے روایت کے مطابق ہم اسے ٹوکنز کی تخلیق اور تباہی کی اطلاع دینے کے لیے استعمال کرتے ہیں۔

ایک ERC-721 منظوری (approval) ERC-20 الاؤنس کی طرح ہوتی ہے۔ ایک مخصوص پتے کو ایک مخصوص ٹوکن منتقل کرنے کی اجازت دی جاتی ہے۔ یہ کنٹریکٹس کو ٹوکن قبول کرنے پر ردعمل ظاہر کرنے کا طریقہ کار فراہم کرتا ہے۔ کنٹریکٹس ایونٹس کو نہیں سن سکتے، اس لیے اگر آپ صرف ٹوکن انہیں منتقل کر دیں تو انہیں اس کے بارے میں "پتہ" نہیں چلتا۔ اس طرح مالک پہلے منظوری جمع کراتا ہے اور پھر کنٹریکٹ کو درخواست بھیجتا ہے: "میں نے آپ کو ٹوکن X منتقل کرنے کی منظوری دے دی ہے، براہ کرم یہ کریں..."۔

یہ ایک ڈیزائن کا انتخاب ہے تاکہ ERC-721 معیار کو ERC-20 معیار کے مشابہ بنایا جا سکے۔ چونکہ ERC-721 ٹوکنز فنجیبل نہیں ہوتے، اس لیے ایک کنٹریکٹ ٹوکن کی ملکیت دیکھ کر بھی یہ پہچان سکتا ہے کہ اسے ایک مخصوص ٹوکن ملا ہے۔

بعض اوقات ایک آپریٹر کا ہونا مفید ہوتا ہے جو کسی اکاؤنٹ کے ایک مخصوص قسم کے تمام ٹوکنز (وہ جو کسی مخصوص کنٹریکٹ کے زیر انتظام ہوں) کا انتظام کر سکے، بالکل پاور آف اٹارنی کی طرح۔ مثال کے طور پر، میں ایک ایسے کنٹریکٹ کو یہ اختیار دینا چاہوں گا جو یہ چیک کرے کہ آیا میں نے چھ ماہ سے اس سے رابطہ نہیں کیا، اور اگر ایسا ہے تو میرے اثاثے میرے ورثاء میں تقسیم کر دے (اگر ان میں سے کوئی اس کی درخواست کرے، کنٹریکٹس ٹرانزیکشن کے ذریعے کال کیے بغیر کچھ نہیں کر سکتے)۔ ERC-20 میں ہم صرف ایک وراثتی کنٹریکٹ کو زیادہ الاؤنس دے سکتے ہیں، لیکن یہ ERC-721 کے لیے کام نہیں کرتا کیونکہ ٹوکنز فنجیبل نہیں ہوتے۔ یہ اسی کا متبادل ہے۔

approved قدر ہمیں بتاتی ہے کہ آیا ایونٹ منظوری کے لیے ہے، یا منظوری واپس لینے کے لیے۔

حالت کے متغیرات (State Variables)

یہ متغیرات (variables) ٹوکنز کی موجودہ حالت پر مشتمل ہوتے ہیں: کون سے دستیاب ہیں اور ان کا مالک کون ہے۔ ان میں سے زیادہ تر HashMap آبجیکٹس ہیں، یک طرفہ میپنگز جو دو اقسام کے درمیان موجود ہوتی ہیں (opens in a new tab)۔

# @dev NFT ID سے اس کے مالک کے پتہ تک میپنگ۔
idToOwner: HashMap[uint256, address]

# @dev NFT ID سے منظور شدہ پتہ تک میپنگ۔
idToApprovals: HashMap[uint256, address]

ایتھیریم میں صارف اور کنٹریکٹ کی شناخت کو 160-bit پتوں سے ظاہر کیا جاتا ہے۔ یہ دو متغیرات میپ کرتے ہیں ٹوکن آئی ڈیز سے ان کے مالکان اور انہیں منتقل کرنے کی منظوری پانے والوں تک (ہر ایک کے لیے زیادہ سے زیادہ ایک)۔ ایتھیریم میں، غیر شروع شدہ (uninitialized) ڈیٹا ہمیشہ صفر ہوتا ہے، لہذا اگر کوئی مالک یا منظور شدہ ٹرانسفرر نہیں ہے تو اس ٹوکن کی قدر صفر ہوتی ہے۔

# @dev مالک کے پتہ سے اس کے ٹوکنز کی گنتی تک میپنگ۔
ownerToNFTokenCount: HashMap[address, uint256]

یہ متغیر ہر مالک کے لیے ٹوکنز کی گنتی رکھتا ہے۔ مالکان سے ٹوکنز تک کوئی میپنگ نہیں ہے، اس لیے کسی مخصوص مالک کے ٹوکنز کی شناخت کرنے کا واحد طریقہ بلاک چین کی ایونٹ ہسٹری میں پیچھے مڑ کر دیکھنا اور مناسب Transfer ایونٹس کو تلاش کرنا ہے۔ ہم اس متغیر کا استعمال یہ جاننے کے لیے کر سکتے ہیں کہ ہمارے پاس تمام NFTs کب آ گئے ہیں اور ہمیں مزید پیچھے دیکھنے کی ضرورت نہیں ہے۔

یاد رکھیں کہ یہ الگورتھم صرف یوزر انٹرفیسز اور بیرونی سرورز کے لیے کام کرتا ہے۔ خود بلاک چین پر چلنے والا کوڈ ماضی کے ایونٹس کو نہیں پڑھ سکتا۔

# @dev مالک کے پتہ سے آپریٹر کے پتوں کی میپنگ تک میپنگ۔
ownerToOperators: HashMap[address, HashMap[address, bool]]

ایک اکاؤنٹ کے ایک سے زیادہ آپریٹرز ہو سکتے ہیں۔ ان کا ٹریک رکھنے کے لیے ایک سادہ HashMap ناکافی ہے، کیونکہ ہر کلید ایک ہی قدر کی طرف لے جاتی ہے۔ اس کے بجائے، آپ HashMap[address, bool] کو قدر کے طور پر استعمال کر سکتے ہیں۔ پہلے سے طے شدہ (by default) ہر پتے کی قدر False ہوتی ہے، جس کا مطلب ہے کہ یہ آپریٹر نہیں ہے۔ آپ ضرورت کے مطابق اقدار کو True پر سیٹ کر سکتے ہیں۔

# @dev منٹر کا پتہ، جو ٹوکن کو ڈھال سکتا ہے
minter: address

نئے ٹوکنز کو کسی نہ کسی طرح بنانا پڑتا ہے۔ اس کنٹریکٹ میں صرف ایک ہی ہستی کو ایسا کرنے کی اجازت ہے، جو کہ minter ہے۔ مثال کے طور پر، یہ کسی گیم کے لیے کافی ہو سکتا ہے۔ دیگر مقاصد کے لیے، زیادہ پیچیدہ کاروباری منطق (business logic) بنانا ضروری ہو سکتا ہے۔

# @dev انٹرفیس آئی ڈی سے بولین (bool) تک میپنگ کہ آیا یہ سپورٹڈ ہے یا نہیں۔
supportedInterfaces: HashMap[bytes32, bool]

# @dev ERC165 کی ERC165 انٹرفیس آئی ڈی
ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7

# @dev ERC721 کی ERC165 انٹرفیس آئی ڈی
ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd

ERC-165 (opens in a new tab) ایک کنٹریکٹ کے لیے یہ ظاہر کرنے کا طریقہ کار بتاتا ہے کہ ایپلی کیشنز اس کے ساتھ کیسے بات چیت کر سکتی ہیں، اور یہ کن ERCs کی تعمیل کرتا ہے۔ اس صورت میں، کنٹریکٹ ERC-165 اور ERC-721 کی تعمیل کرتا ہے۔

فنکشنز

یہ وہ فنکشنز ہیں جو دراصل ERC-721 کو نافذ کرتے ہیں۔

کنسٹرکٹر

@external
def __init__():

Vyper میں، بالکل Python کی طرح، کنسٹرکٹر فنکشن کو __init__ کہا جاتا ہے۔

    """
    @dev کنٹریکٹ کنسٹرکٹر۔
    """

Python اور Vyper میں، آپ ایک ملٹی لائن سٹرنگ (جو """ سے شروع اور ختم ہوتی ہے) بتا کر بھی تبصرہ بنا سکتے ہیں، اور اسے کسی بھی طرح استعمال نہیں کر سکتے۔ ان تبصروں میں NatSpec (opens in a new tab) بھی شامل ہو سکتا ہے۔

    self.supportedInterfaces[ERC165_INTERFACE_ID] = True
    self.supportedInterfaces[ERC721_INTERFACE_ID] = True
    self.minter = msg.sender

حالت کے متغیرات تک رسائی حاصل کرنے کے لیے آپ self.<variable name> استعمال کرتے ہیں (دوبارہ، بالکل Python کی طرح)۔

ویو فنکشنز (View Functions)

یہ وہ فنکشنز ہیں جو بلاک چین کی حالت کو تبدیل نہیں کرتے، اور اس لیے اگر انہیں بیرونی طور پر کال کیا جائے تو انہیں مفت میں چلایا جا سکتا ہے۔ اگر ویو فنکشنز کو کسی کنٹریکٹ کے ذریعے کال کیا جائے تو انہیں پھر بھی ہر نوڈ پر چلانا پڑتا ہے اور اس لیے ان پر گیس خرچ ہوتی ہے۔

@view
@external

فنکشن کی تعریف سے پہلے یہ کلیدی الفاظ جو ایٹ سائن (@) سے شروع ہوتے ہیں، انہیں ڈیکوریشنز (decorations) کہا جاتا ہے۔ یہ ان حالات کی وضاحت کرتے ہیں جن میں کسی فنکشن کو کال کیا جا سکتا ہے۔

  • @view یہ بتاتا ہے کہ یہ فنکشن ایک ویو (view) ہے۔
  • @external یہ بتاتا ہے کہ اس مخصوص فنکشن کو ٹرانزیکشنز اور دیگر کنٹریکٹس کے ذریعے کال کیا جا سکتا ہے۔
def supportsInterface(_interfaceID: bytes32) -> bool:

Python کے برعکس، Vyper ایک سٹیٹک ٹائپڈ زبان (opens in a new tab) ہے۔ آپ ڈیٹا ٹائپ (opens in a new tab) کی شناخت کیے بغیر کسی متغیر، یا فنکشن پیرامیٹر کا اعلان نہیں کر سکتے۔ اس صورت میں ان پٹ پیرامیٹر bytes32 ہے، جو کہ ایک 256-bit قدر ہے (256 bits ایتھیریم ورچوئل مشین کا مقامی ورڈ سائز ہے)۔ آؤٹ پٹ ایک بولین قدر ہے۔ روایت کے مطابق، فنکشن پیرامیٹرز کے نام انڈرسکور (_) سے شروع ہوتے ہیں۔

    """
    @dev انٹرفیس کی شناخت ERC-165 میں بیان کی گئی ہے۔
    @param _interfaceID انٹرفیس کی آئی ڈی
    """
    return self.supportedInterfaces[_interfaceID]

self.supportedInterfaces ہیش میپ (HashMap) سے قدر واپس کریں، جو کنسٹرکٹر (__init__) میں سیٹ کی گئی ہے۔

### ویو فنکشنز ###

یہ وہ ویو فنکشنز ہیں جو ٹوکنز کے بارے میں معلومات صارفین اور دیگر کنٹریکٹس کو دستیاب کراتے ہیں۔

یہ لائن یقینی بناتی ہے (opens in a new tab) کہ _owner صفر نہیں ہے۔ اگر ایسا ہے، تو ایک خرابی ہے اور آپریشن کو ریورٹ کر دیا جاتا ہے۔

ایتھیریم ورچوئل مشین (EVM) میں کوئی بھی سٹوریج جس میں کوئی قدر محفوظ نہ ہو، وہ صفر ہوتی ہے۔ اگر _tokenId پر کوئی ٹوکن نہیں ہے تو self.idToOwner[_tokenId] کی قدر صفر ہوتی ہے۔ اس صورت میں فنکشن ریورٹ ہو جاتا ہے۔

یاد رکھیں کہ getApproved صفر واپس کر سکتا ہے۔ اگر ٹوکن درست ہے تو یہ self.idToApprovals[_tokenId] واپس کرتا ہے۔ اگر کوئی منظوری دینے والا نہیں ہے تو وہ قدر صفر ہوتی ہے۔

یہ فنکشن چیک کرتا ہے کہ آیا _operator کو اس کنٹریکٹ میں _owner کے تمام ٹوکنز کا انتظام کرنے کی اجازت ہے۔ چونکہ ایک سے زیادہ آپریٹرز ہو سکتے ہیں، اس لیے یہ دو درجے کا ہیش میپ (HashMap) ہے۔

ٹرانسفر ہیلپر فنکشنز

یہ فنکشنز ان آپریشنز کو نافذ کرتے ہیں جو ٹوکنز کی منتقلی یا انتظام کا حصہ ہیں۔


### ٹرانسفر فنکشن ہیلپرز ###

@view
@internal

اس ڈیکوریشن، @internal، کا مطلب ہے کہ فنکشن صرف اسی کنٹریکٹ کے اندر موجود دیگر فنکشنز سے قابل رسائی ہے۔ روایت کے مطابق، ان فنکشنز کے نام بھی انڈرسکور (_) سے شروع ہوتے ہیں۔

تین طریقے ہیں جن سے کسی پتے کو ٹوکن منتقل کرنے کی اجازت دی جا سکتی ہے:

  1. پتہ ٹوکن کا مالک ہو
  2. پتے کو وہ ٹوکن خرچ کرنے کی منظوری دی گئی ہو
  3. پتہ ٹوکن کے مالک کا آپریٹر ہو

مندرجہ بالا فنکشن ایک ویو ہو سکتا ہے کیونکہ یہ حالت کو تبدیل نہیں کرتا۔ آپریٹنگ اخراجات کو کم کرنے کے لیے، کوئی بھی فنکشن جو ویو ہو سکتا ہے اسے ویو ہونا چاہیے۔

جب منتقلی میں کوئی مسئلہ ہوتا ہے تو ہم کال کو ریورٹ کر دیتے ہیں۔

صرف ضرورت پڑنے پر ہی قدر تبدیل کریں۔ حالت کے متغیرات سٹوریج میں رہتے ہیں۔ سٹوریج میں لکھنا ان سب سے مہنگے آپریشنز میں سے ایک ہے جو EVM (ایتھیریم ورچوئل مشین) کرتا ہے (گیس کے لحاظ سے)۔ اس لیے، اسے کم سے کم کرنا ایک اچھا خیال ہے، یہاں تک کہ موجودہ قدر کو لکھنے کی بھی زیادہ قیمت ہوتی ہے۔

ہمارے پاس یہ اندرونی فنکشن اس لیے ہے کیونکہ ٹوکنز منتقل کرنے کے دو طریقے ہیں (باقاعدہ اور محفوظ)، لیکن ہم کوڈ میں صرف ایک ہی جگہ چاہتے ہیں جہاں ہم یہ کریں تاکہ آڈیٹنگ کو آسان بنایا جا سکے۔

Vyper میں ایونٹ خارج کرنے کے لیے آپ log سٹیٹمنٹ استعمال کرتے ہیں (مزید تفصیلات کے لیے یہاں دیکھیں (opens in a new tab)

ٹرانسفر فنکشنز

یہ فنکشن آپ کو کسی بھی صوابدیدی (arbitrary) پتے پر منتقل کرنے کی اجازت دیتا ہے۔ جب تک کہ پتہ کوئی صارف نہ ہو، یا کوئی ایسا کنٹریکٹ نہ ہو جو ٹوکنز منتقل کرنا جانتا ہو، آپ کا منتقل کردہ کوئی بھی ٹوکن اس پتے میں پھنس جائے گا اور بیکار ہو جائے گا۔

پہلے منتقلی کرنا ٹھیک ہے کیونکہ اگر کوئی مسئلہ ہوا تو ہم ویسے بھی ریورٹ کرنے والے ہیں، اس لیے کال میں کیا گیا ہر کام منسوخ ہو جائے گا۔

    if _to.is_contract: # چیک کریں کہ آیا `_to` ایک کنٹریکٹ کا پتہ ہے

پہلے یہ چیک کریں کہ آیا پتہ کوئی کنٹریکٹ ہے (اگر اس میں کوڈ ہے)۔ اگر نہیں، تو فرض کریں کہ یہ صارف کا پتہ ہے اور صارف ٹوکن استعمال کرنے یا اسے منتقل کرنے کے قابل ہو گا۔ لیکن اسے آپ کو تحفظ کے جھوٹے احساس میں مبتلا نہ ہونے دیں۔ آپ ٹوکنز کھو سکتے ہیں، یہاں تک کہ safeTransferFrom کے ساتھ بھی، اگر آپ انہیں کسی ایسے پتے پر منتقل کرتے ہیں جس کی نجی کلید کوئی نہیں جانتا۔

        returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data)

ہدف کنٹریکٹ کو کال کریں تاکہ یہ دیکھا جا سکے کہ آیا وہ ERC-721 ٹوکنز وصول کر سکتا ہے۔

        # اگر منتقلی کی منزل ایک ایسا کنٹریکٹ ہے جو 'onERC721Received' کو نافذ نہیں کرتا ہے تو ایرر (Throws) دیتا ہے
        assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32)

اگر منزل ایک کنٹریکٹ ہے، لیکن ایسا جو ERC-721 ٹوکنز قبول نہیں کرتا (یا جس نے اس مخصوص منتقلی کو قبول نہ کرنے کا فیصلہ کیا ہے)، تو ریورٹ کریں۔

روایت کے مطابق اگر آپ نہیں چاہتے کہ کوئی منظوری دینے والا ہو تو آپ صفر ایڈریس مقرر کرتے ہیں، خود کو نہیں۔

    # ضروریات چیک کریں
    senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender
    senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender]
    assert (senderIsOwner or senderIsApprovedForAll)

منظوری سیٹ کرنے کے لیے آپ یا تو مالک ہو سکتے ہیں، یا مالک کی طرف سے مجاز آپریٹر۔

نئے ٹوکنز ڈھالنا اور موجودہ کو تباہ کرنا

جس اکاؤنٹ نے کنٹریکٹ بنایا ہے وہ minter ہے، وہ سپر یوزر جو نئے NFTs ڈھالنے کا مجاز ہے۔ تاہم، اسے بھی موجودہ ٹوکنز جلانے کی اجازت نہیں ہے۔ صرف مالک، یا مالک کی طرف سے مجاز کوئی ہستی ہی ایسا کر سکتی ہے۔

### ڈھالنے اور جلانے کے فنکشنز ###

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

یہ فنکشن ہمیشہ True واپس کرتا ہے، کیونکہ اگر آپریشن ناکام ہو جاتا ہے تو اسے ریورٹ کر دیا جاتا ہے۔

صرف منٹر (وہ اکاؤنٹ جس نے ERC-721 کنٹریکٹ بنایا ہے) ہی نئے ٹوکنز ڈھال سکتا ہے۔ یہ مستقبل میں ایک مسئلہ ہو سکتا ہے اگر ہم منٹر کی شناخت تبدیل کرنا چاہیں۔ پروڈکشن کنٹریکٹ میں آپ شاید ایک ایسا فنکشن چاہیں گے جو منٹر کو منٹر کے مراعات کسی اور کو منتقل کرنے کی اجازت دے۔

    # اگر `_to` صفر ایڈریس ہے تو ایرر (Throws) دیتا ہے
    assert _to != ZERO_ADDRESS
    # NFT شامل کریں۔ اگر `_tokenId` کسی کی ملکیت ہے تو ایرر (Throws) دیتا ہے
    self._addTokenTo(_to, _tokenId)
    log Transfer(ZERO_ADDRESS, _to, _tokenId)
    return True

روایت کے مطابق، نئے ٹوکنز کی ڈھلائی کو صفر ایڈریس سے منتقلی کے طور پر شمار کیا جاتا ہے۔

جس کسی کو بھی ٹوکن منتقل کرنے کی اجازت ہے اسے جلانے کی بھی اجازت ہے۔ اگرچہ جلانا صفر ایڈریس پر منتقل کرنے کے مترادف لگتا ہے، لیکن صفر ایڈریس دراصل ٹوکن وصول نہیں کرتا۔ یہ ہمیں وہ تمام سٹوریج خالی کرنے کی اجازت دیتا ہے جو ٹوکن کے لیے استعمال کی گئی تھی، جس سے ٹرانزیکشن کی گیس کی قیمت کم ہو سکتی ہے۔

اس کنٹریکٹ کا استعمال

Solidity کے برعکس، Vyper میں وراثت (inheritance) نہیں ہوتی۔ یہ ایک دانستہ ڈیزائن کا انتخاب ہے تاکہ کوڈ کو واضح اور اس لیے محفوظ بنانے میں آسانی ہو۔ لہذا اپنا Vyper ERC-721 کنٹریکٹ بنانے کے لیے آپ یہ کنٹریکٹ (opens in a new tab) لیتے ہیں اور اپنی مطلوبہ کاروباری منطق کو نافذ کرنے کے لیے اس میں ترمیم کرتے ہیں۔

نتیجہ

جائزے کے لیے، اس کنٹریکٹ کے کچھ اہم ترین خیالات یہ ہیں:

  • محفوظ منتقلی کے ساتھ ERC-721 ٹوکنز وصول کرنے کے لیے، کنٹریکٹس کو ERC721Receiver انٹرفیس نافذ کرنا پڑتا ہے۔
  • یہاں تک کہ اگر آپ محفوظ منتقلی کا استعمال کرتے ہیں، تب بھی ٹوکنز پھنس سکتے ہیں اگر آپ انہیں کسی ایسے پتے پر بھیجتے ہیں جس کی نجی کلید نامعلوم ہے۔
  • جب کسی آپریشن میں کوئی مسئلہ ہو تو کال کو revert کرنا ایک اچھا خیال ہے، بجائے اس کے کہ صرف ناکامی کی قدر واپس کی جائے۔
  • ERC-721 ٹوکنز تب موجود ہوتے ہیں جب ان کا کوئی مالک ہو۔
  • NFT منتقل کرنے کا مجاز ہونے کے تین طریقے ہیں۔ آپ مالک ہو سکتے ہیں، کسی مخصوص ٹوکن کے لیے منظور شدہ ہو سکتے ہیں، یا مالک کے تمام ٹوکنز کے لیے آپریٹر ہو سکتے ہیں۔
  • ماضی کے ایونٹس صرف بلاک چین کے باہر نظر آتے ہیں۔ بلاک چین کے اندر چلنے والا کوڈ انہیں نہیں دیکھ سکتا۔

اب جائیں اور محفوظ Vyper کنٹریکٹس نافذ کریں۔

میرے مزید کام کے لیے یہاں دیکھیں (opens in a new tab)۔