মূল কন্টেন্টে যান

Vyper ERC-721 কন্ট্রাক্ট ওয়াকথ্রু

Vyper
erc-721
Python
শিক্ষানবিস
ওরি পোমেরান্টজ
1 এপ্রিল, 2021
19 মিনিট পড়ার সময়

ভূমিকা

ERC-721 স্ট্যান্ডার্ডটি নন-ফাঞ্জিবল টোকেন (NFT)-এর মালিকানা ধরে রাখতে ব্যবহৃত হয়। ERC-20 টোকেনগুলো একটি পণ্যের মতো আচরণ করে, কারণ প্রতিটি আলাদা টোকেনের মধ্যে কোনো পার্থক্য নেই। এর বিপরীতে, 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

Python-এর মতো Vyper-এও মন্তব্যগুলো একটি হ্যাশ (#) দিয়ে শুরু হয় এবং লাইনের শেষ পর্যন্ত চলতে থাকে। যেসব মন্তব্যে @<keyword> থাকে, সেগুলো NatSpec (opens in a new tab) ব্যবহার করে মানুষের পড়ার উপযোগী ডকুমেন্টেশন তৈরি করতে ব্যবহৃত হয়।

from vyper.interfaces import ERC721

implements: ERC721

ERC-721 ইন্টারফেসটি Vyper ভাষার ভেতরেই তৈরি করা আছে। আপনি এখানে কোডের সংজ্ঞা দেখতে পারেন (opens in a new tab)। ইন্টারফেসের সংজ্ঞাটি Vyper-এর পরিবর্তে Python-এ লেখা হয়েছে, কারণ ইন্টারফেসগুলো শুধু ব্লকচেইনের ভেতরেই ব্যবহৃত হয় না, বরং কোনো এক্সটার্নাল ক্লায়েন্ট থেকে ব্লকচেইনে ট্রানজ্যাকশন পাঠানোর সময়ও ব্যবহৃত হয়, যা Python-এ লেখা হতে পারে।

প্রথম লাইনটি ইন্টারফেস ইমপোর্ট করে এবং দ্বিতীয় লাইনটি নির্দিষ্ট করে যে আমরা এটি এখানে ইমপ্লিমেন্ট করছি।

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 বিটের হয়। সাধারণত টোকেনটি যা উপস্থাপন করে তার একটি বিবরণ হ্যাশিং করার মাধ্যমে এগুলো তৈরি করা হয়।

            _data: Bytes[1024]

রিকোয়েস্টে 1024 বাইট পর্যন্ত ইউজার ডেটা থাকতে পারে।

        ) -> bytes32: view

কোনো কন্ট্রাক্ট যাতে ভুলবশত কোনো হস্তান্তর গ্রহণ না করে, তা প্রতিরোধ করতে রিটার্ন ভ্যালু কোনো বুলিয়ান নয়, বরং একটি নির্দিষ্ট মানসহ 256 বিট হয়।

এই ফাংশনটি একটি view, যার মানে হলো এটি ব্লকচেইনের স্টেট পড়তে পারে, কিন্তু তা পরিবর্তন করতে পারে না।

ইভেন্ট

ব্লকচেইনের বাইরের ব্যবহারকারী এবং সার্ভারগুলোকে ইভেন্ট সম্পর্কে জানাতে ইভেন্ট এমিট করা হয়। মনে রাখবেন যে ইভেন্টের বিষয়বস্তু ব্লকচেইনের কন্ট্রাক্টগুলোর জন্য উপলব্ধ নয়।

এটি ERC-20 হস্তান্তর ইভেন্টের মতোই, তবে পার্থক্য হলো আমরা পরিমাণের পরিবর্তে একটি tokenId রিপোর্ট করি। জিরো অ্যাড্রেস কারও মালিকানাধীন নয়, তাই প্রথা অনুযায়ী আমরা টোকেন তৈরি এবং ধ্বংস করার রিপোর্ট করতে এটি ব্যবহার করি।

একটি ERC-721 অনুমোদন একটি ERC-20 অ্যালাউন্সের মতোই। একটি নির্দিষ্ট ঠিকানাকে একটি নির্দিষ্ট টোকেন হস্তান্তর করার অনুমতি দেওয়া হয়। এটি কন্ট্রাক্টগুলোর জন্য একটি মেকানিজম প্রদান করে যাতে তারা কোনো টোকেন গ্রহণ করার সময় সাড়া দিতে পারে। কন্ট্রাক্টগুলো ইভেন্ট শুনতে পারে না, তাই আপনি যদি শুধু তাদের কাছে টোকেন হস্তান্তর করেন তবে তারা এটি সম্পর্কে "জানতে" পারে না। এই পদ্ধতিতে মালিক প্রথমে একটি অনুমোদন জমা দেন এবং তারপর কন্ট্রাক্টে একটি রিকোয়েস্ট পাঠান: "আমি আপনাকে টোকেন X হস্তান্তর করার অনুমোদন দিয়েছি, অনুগ্রহ করে করুন..."।

ERC-721 স্ট্যান্ডার্ডকে ERC-20 স্ট্যান্ডার্ডের মতো করার জন্য এটি একটি ডিজাইনগত সিদ্ধান্ত। যেহেতু ERC-721 টোকেনগুলো ফাঞ্জিবল নয়, তাই একটি কন্ট্রাক্ট টোকেনের মালিকানা দেখেও শনাক্ত করতে পারে যে এটি একটি নির্দিষ্ট টোকেন পেয়েছে।

পাওয়ার অফ অ্যাটর্নির মতো এমন একজন অপারেটর থাকা মাঝে মাঝে দরকারী, যে একটি অ্যাকাউন্টের নির্দিষ্ট ধরনের সমস্ত টোকেন (যেগুলো একটি নির্দিষ্ট কন্ট্রাক্ট দ্বারা পরিচালিত হয়) পরিচালনা করতে পারে। উদাহরণস্বরূপ, আমি এমন একটি কন্ট্রাক্টকে এই ক্ষমতা দিতে চাইতে পারি যা পরীক্ষা করে যে আমি ছয় মাস ধরে এর সাথে যোগাযোগ করিনি কি না, এবং যদি তা হয় তবে আমার সম্পদগুলো আমার উত্তরাধিকারীদের মধ্যে বিতরণ করে (যদি তাদের মধ্যে কেউ এটি চায়, কারণ ট্রানজ্যাকশন দ্বারা কল করা ছাড়া কন্ট্রাক্টগুলো কিছুই করতে পারে না)। ERC-20-তে আমরা একটি উত্তরাধিকার কন্ট্রাক্টকে শুধু একটি উচ্চ অ্যালাউন্স দিতে পারি, কিন্তু ERC-721-এর ক্ষেত্রে এটি কাজ করে না কারণ টোকেনগুলো ফাঞ্জিবল নয়। এটি তারই সমতুল্য।

approved মানটি আমাদের বলে যে ইভেন্টটি কোনো অনুমোদনের জন্য, নাকি কোনো অনুমোদন প্রত্যাহারের জন্য।

স্টেট ভেরিয়েবল

এই ভেরিয়েবলগুলোতে টোকেনগুলোর বর্তমান স্টেট থাকে: কোনগুলো উপলব্ধ আছে এবং সেগুলোর মালিক কে। এগুলোর বেশিরভাগই হলো HashMap অবজেক্ট, দুটি টাইপের মধ্যে থাকা একমুখী ম্যাপিং (opens in a new tab)

# @dev NFT ID থেকে এর মালিকানার ঠিকানায় ম্যাপিং।
idToOwner: HashMap[uint256, address]

# @dev NFT ID থেকে অনুমোদিত ঠিকানায় ম্যাপিং।
idToApprovals: HashMap[uint256, address]

ইথেরিয়াম-এ ব্যবহারকারী এবং কন্ট্রাক্টের পরিচয় 160-বিট ঠিকানা দ্বারা উপস্থাপন করা হয়। এই দুটি ভেরিয়েবল টোকেন আইডি থেকে তাদের মালিকদের এবং সেগুলো হস্তান্তর করার জন্য অনুমোদিত ব্যক্তিদের (প্রতিটির জন্য সর্বোচ্চ একজন) ম্যাপ করে। ইথেরিয়াম-এ, আনইনিশিয়ালাইজড ডেটা সর্বদা শূন্য হয়, তাই যদি কোনো মালিক বা অনুমোদিত হস্তান্তরকারী না থাকে তবে সেই টোকেনের মান শূন্য হয়।

# @dev মালিকের ঠিকানা থেকে তার টোকেন সংখ্যায় ম্যাপিং।
ownerToNFTokenCount: HashMap[address, uint256]

এই ভেরিয়েবলটি প্রতিটি মালিকের জন্য টোকেনের সংখ্যা ধারণ করে। মালিকদের থেকে টোকেনগুলোতে কোনো ম্যাপিং নেই, তাই কোনো নির্দিষ্ট মালিকের মালিকানাধীন টোকেনগুলো শনাক্ত করার একমাত্র উপায় হলো ব্লকচেইনের ইভেন্ট ইতিহাসে ফিরে তাকানো এবং উপযুক্ত Transfer ইভেন্টগুলো দেখা। আমরা এই ভেরিয়েবলটি ব্যবহার করে জানতে পারি কখন আমাদের কাছে সমস্ত NFT আছে এবং সময়ের আরও পেছনে ফিরে দেখার প্রয়োজন নেই।

মনে রাখবেন যে এই অ্যালগরিদমটি শুধুমাত্র ইউজার ইন্টারফেস এবং এক্সটার্নাল সার্ভারের জন্য কাজ করে। ব্লকচেইনে চলা কোড নিজে অতীতের ইভেন্টগুলো পড়তে পারে না।

# @dev মালিকের ঠিকানা থেকে অপারেটর ঠিকানাগুলোর ম্যাপিংয়ে ম্যাপিং।
ownerToOperators: HashMap[address, HashMap[address, bool]]

একটি অ্যাকাউন্টের একাধিক অপারেটর থাকতে পারে। তাদের ট্র্যাক রাখার জন্য একটি সাধারণ HashMap অপর্যাপ্ত, কারণ প্রতিটি কী একটি একক মানের দিকে নিয়ে যায়। এর পরিবর্তে, আপনি মান হিসেবে HashMap[address, bool] ব্যবহার করতে পারেন। ডিফল্টরূপে প্রতিটি ঠিকানার মান হলো False, যার মানে এটি কোনো অপারেটর নয়। আপনি প্রয়োজন অনুযায়ী মানগুলোকে True-এ সেট করতে পারেন।

# @dev মিন্টারের ঠিকানা, যিনি একটি টোকেন মিন্ট করতে পারেন
minter: address

নতুন টোকেনগুলো কোনো না কোনোভাবে তৈরি করতে হবে। এই কন্ট্রাক্টে শুধুমাত্র একটি এনটিটি এটি করার অনুমতিপ্রাপ্ত, যা হলো minter। উদাহরণস্বরূপ, একটি গেমের জন্য এটি সম্ভবত যথেষ্ট। অন্যান্য উদ্দেশ্যে, আরও জটিল ব্যবসায়িক লজিক তৈরি করার প্রয়োজন হতে পারে।

# @dev ইন্টারফেস আইডি থেকে এটি সমর্থিত কিনা সেই সম্পর্কিত bool-এ ম্যাপিং
supportedInterfaces: HashMap[bytes32, bool]

# @dev ERC-165-এর ERC-165 ইন্টারফেস আইডি
ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7

# @dev ERC-721-এর ERC-165 ইন্টারফেস আইডি
ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd

ERC-165 (opens in a new tab) একটি কন্ট্রাক্টের জন্য এমন একটি মেকানিজম নির্দিষ্ট করে যার মাধ্যমে এটি প্রকাশ করতে পারে যে অ্যাপ্লিকেশনগুলো কীভাবে এর সাথে যোগাযোগ করতে পারে এবং এটি কোন ERC-গুলো মেনে চলে। এই ক্ষেত্রে, কন্ট্রাক্টটি ERC-165 এবং ERC-721 মেনে চলে।

ফাংশন

এগুলো হলো সেই ফাংশন যা আসলে ERC-721 ইমপ্লিমেন্ট করে।

কনস্ট্রাক্টর

@external
def __init__():

Python-এর মতো Vyper-এও কনস্ট্রাক্টর ফাংশনটিকে __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
@external

ফাংশন সংজ্ঞার আগে থাকা এই কিওয়ার্ডগুলো, যা একটি অ্যাট সাইন (@) দিয়ে শুরু হয়, সেগুলোকে ডেকোরেশন বলা হয়। এগুলো নির্দিষ্ট করে যে কোন পরিস্থিতিতে একটি ফাংশন কল করা যেতে পারে।

  • @view নির্দিষ্ট করে যে এই ফাংশনটি একটি ভিউ।
  • @external নির্দিষ্ট করে যে এই নির্দিষ্ট ফাংশনটি ট্রানজ্যাকশন এবং অন্যান্য কন্ট্রাক্ট দ্বারা কল করা যেতে পারে।
def supportsInterface(_interfaceID: bytes32) -> bool:

Python-এর বিপরীতে, Vyper হলো একটি স্ট্যাটিক টাইপড ভাষা (opens in a new tab)। আপনি ডেটা টাইপ (opens in a new tab) শনাক্ত না করে কোনো ভেরিয়েবল বা ফাংশন প্যারামিটার ডিক্লেয়ার করতে পারবেন না। এই ক্ষেত্রে ইনপুট প্যারামিটারটি হলো bytes32, যা একটি 256-বিট মান (256 বিট হলো ইথেরিয়াম ভার্চুয়াল মেশিন-এর নেটিভ ওয়ার্ড সাইজ)। আউটপুটটি হলো একটি বুলিয়ান মান। প্রথা অনুযায়ী, ফাংশন প্যারামিটারের নামগুলো একটি আন্ডারস্কোর (_) দিয়ে শুরু হয়।

    """
    @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))।

হস্তান্তর ফাংশন

এই ফাংশনটি আপনাকে একটি ইচ্ছামতো ঠিকানায় হস্তান্তর করতে দেয়। যদি না ঠিকানাটি কোনো ব্যবহারকারী হয়, বা এমন কোনো কন্ট্রাক্ট হয় যা জানে কীভাবে টোকেন হস্তান্তর করতে হয়, তবে আপনার হস্তান্তর করা যেকোনো টোকেন সেই ঠিকানায় আটকে যাবে এবং অকেজো হয়ে যাবে।

প্রথমে হস্তান্তর করা ঠিক আছে কারণ যদি কোনো সমস্যা হয় তবে আমরা এমনিতেই রিভার্ট করতে যাচ্ছি, তাই কলে করা সবকিছু বাতিল হয়ে যাবে।

    if _to.is_contract: # `_to` একটি কন্ট্রাক্ট ঠিকানা কিনা তা চেক করুন

প্রথমে পরীক্ষা করে দেখুন ঠিকানাটি কোনো কন্ট্রাক্ট কি না (যদি এর কোড থাকে)। যদি না হয়, তবে ধরে নিন এটি একটি ব্যবহারকারীর ঠিকানা এবং ব্যবহারকারী টোকেনটি ব্যবহার করতে বা হস্তান্তর করতে সক্ষম হবেন। তবে এটি যেন আপনাকে নিরাপত্তার মিথ্যা অনুভূতি না দেয়। আপনি টোকেন হারাতে পারেন, এমনকি safeTransferFrom ব্যবহার করেও, যদি আপনি সেগুলোকে এমন কোনো ঠিকানায় হস্তান্তর করেন যার প্রাইভেট কী কেউ জানে না।

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

টার্গেট কন্ট্রাক্টটি ERC-721 টোকেন গ্রহণ করতে পারে কি না তা দেখতে সেটিকে কল করুন।

        # হস্তান্তরের গন্তব্য যদি এমন একটি কন্ট্রাক্ট হয় যা 'onERC721Received' ইমপ্লিমেন্ট করে না তবে থ্রো করে
        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, সুপার ইউজার যা নতুন NFT মিন্ট করার জন্য অনুমোদিত। তবে, এমনকি এটিকেও বিদ্যমান টোকেন পোড়ানোর অনুমতি দেওয়া হয় না। শুধুমাত্র মালিক, বা মালিক দ্বারা অনুমোদিত কোনো এনটিটি এটি করতে পারে।

### মিন্ট এবং পোড়ানো ফাংশনগুলো ###

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

এই ফাংশনটি সর্বদা True রিটার্ন করে, কারণ যদি অপারেশনটি ব্যর্থ হয় তবে এটি রিভার্ট করা হয়।

শুধুমাত্র মিন্টার (যে অ্যাকাউন্টটি ERC-721 কন্ট্রাক্ট তৈরি করেছে) নতুন টোকেন মিন্ট করতে পারে। ভবিষ্যতে যদি আমরা মিন্টারের পরিচয় পরিবর্তন করতে চাই তবে এটি একটি সমস্যা হতে পারে। একটি প্রোডাকশন কন্ট্রাক্টে আপনি সম্ভবত এমন একটি ফাংশন চাইবেন যা মিন্টারকে অন্য কারও কাছে মিন্টারের সুবিধাগুলো হস্তান্তর করার অনুমতি দেয়।

    # `_to` জিরো অ্যাড্রেস হলে থ্রো করে
    assert _to != ZERO_ADDRESS
    # NFT যোগ করুন। `_tokenId` কারও মালিকানাধীন হলে থ্রো করে
    self._addTokenTo(_to, _tokenId)
    log Transfer(ZERO_ADDRESS, _to, _tokenId)
    return True

প্রথা অনুযায়ী, নতুন টোকেন মিন্টিং জিরো অ্যাড্রেস থেকে একটি হস্তান্তর হিসেবে গণ্য হয়।

যে কাউকে টোকেন হস্তান্তর করার অনুমতি দেওয়া হয়, তাকে এটি পোড়ানোরও অনুমতি দেওয়া হয়। যদিও পোড়ানো জিরো অ্যাড্রেসে হস্তান্তর করার সমতুল্য বলে মনে হয়, জিরো অ্যাড্রেস আসলে টোকেনটি গ্রহণ করে না। এটি আমাদের টোকেনের জন্য ব্যবহৃত সমস্ত স্টোরেজ খালি করার অনুমতি দেয়, যা ট্রানজ্যাকশনের গ্যাস খরচ কমাতে পারে।

এই কন্ট্রাক্ট ব্যবহার করা

Solidity-এর বিপরীতে, Vyper-এ ইনহেরিটেন্স নেই। কোডটিকে আরও পরিষ্কার এবং তাই সুরক্ষিত করা সহজ করার জন্য এটি একটি ইচ্ছাকৃত ডিজাইনগত সিদ্ধান্ত। তাই আপনার নিজস্ব Vyper ERC-721 কন্ট্রাক্ট তৈরি করতে আপনি এই কন্ট্রাক্টটি (opens in a new tab) নিতে পারেন এবং আপনি যে ব্যবসায়িক লজিক চান তা ইমপ্লিমেন্ট করতে এটি পরিবর্তন করতে পারেন।

উপসংহার

পর্যালোচনার জন্য, এখানে এই কন্ট্রাক্টের সবচেয়ে গুরুত্বপূর্ণ কিছু ধারণা দেওয়া হলো:

  • নিরাপদ হস্তান্তরের মাধ্যমে ERC-721 টোকেন গ্রহণ করতে, কন্ট্রাক্টগুলোকে ERC721Receiver ইন্টারফেস ইমপ্লিমেন্ট করতে হবে।
  • এমনকি আপনি নিরাপদ হস্তান্তর ব্যবহার করলেও, টোকেনগুলো আটকে যেতে পারে যদি আপনি সেগুলোকে এমন কোনো ঠিকানায় পাঠান যার প্রাইভেট কী অজানা।
  • যখন কোনো অপারেশনে সমস্যা হয় তখন শুধু একটি ব্যর্থতার মান রিটার্ন করার পরিবর্তে কলটি revert করা একটি ভালো ধারণা।
  • ERC-721 টোকেনগুলোর অস্তিত্ব থাকে যখন সেগুলোর একজন মালিক থাকে।
  • একটি NFT হস্তান্তর করার জন্য অনুমোদিত হওয়ার তিনটি উপায় রয়েছে। আপনি মালিক হতে পারেন, একটি নির্দিষ্ট টোকেনের জন্য অনুমোদিত হতে পারেন, অথবা মালিকের সমস্ত টোকেনের জন্য একজন অপারেটর হতে পারেন।
  • অতীতের ইভেন্টগুলো শুধুমাত্র ব্লকচেইনের বাইরে দৃশ্যমান। ব্লকচেইনের ভেতরে চলা কোড সেগুলো দেখতে পারে না।

এখন যান এবং সুরক্ষিত Vyper কন্ট্রাক্ট ইমপ্লিমেন্ট করুন।

আমার আরও কাজের জন্য এখানে দেখুন (opens in a new tab)