در بازار توکن های NFT که همواره در مسیر رشد و تکامل قرار دارد، قراردادهای NFT وجود دارد که از اهمیت بالایی برخوردارند. البته در بسیاری از قراردادهای NFT، علی رغم طراحی خوب، تعدادی اشتباه خاص و مشخص معمولا وجود دارد. پلتفرم Etherscan (اتر اسکن) یک ابزار جستجوی کاربردی دارد که کدهای بسیاری از قراردادهای ERC721 را به وسیله آن می توان با هم مقایسه کرد. به وسیله این ابزار می توان از ویژگی های تایید و Decompile استفاده کرد. در این مقاله قصد داریم به بررسی اشتباهات قراردادهای NFT یا به اصطلاح Anti-Pattern (ضدالگو) بپردازیم.
بررسی اشتباهات قراردادهای NFT
در قراردادهای NFT معمولا اشتباهات متعددی رخ می دهد که در ادامه قصد داریم به بررسی اشتباهات قراردادهای NFT و همچنین راهکارهایی برای پیشگیری از آنها بپردازیم.
1- آوردن اطلاعات مربوط به فروش، قیمت و منطق در قرارداد
این ضد الگو اشتباهات قراردادهای NFT می باشد که در یک قرارداد قبل از هر چیز دیگری به چشم میخورد. البته در پشت این اشتباه، انگیزه های قابل درک و منطقی وجود دارد. در اکثر شبکه ها، هزینه استقرار و مدیریت قرارداد بسیار زیاد می باشد، بنابراین افراد به دنبال صرفه جویی در این هزینهها می باشند. ممکن است این سوال برای برخی افراد پیش بیاید که چرا نباید در قرارداد، منطق صدور (ضرب) و فروش را آورد؟
جواب این سوال این است که ایده قرار دادن این نوع اطلاعات در قراردادهای NFT اصلا مناسب نمی باشد. اگر چه قرارداد NFT باید به عنوان یک مرکز غیر قابل تغییر شبکهای از منطقها عمل کند اما نباید مدیریت پول را به صورت مستقیم انجام دهد. به عبارت دیگر اطلاعات فروش، وایت لیست، زمان های فروش و... نباید در کد استقرار ERC721 به طور مستقیم قرار بگیرد. شباهت های بسیاری میان منطق هسته و منطق فروش وجود دارد. شاید منطقی ترین و بهترین دلیل جمع آوری تمام منطق ها در یک قرارداد NFT، صرفه جویی در هزینه گس باشد اما در نگاه کلی برای استفاده نکردن از این روش، دلایل مهم تری نیز وجود دارد.
منطق قرارداد ضمن این که باید بدون تغییر و ثابت باشد، باید بتواند به خوبی استانداردها را اجرا کند. اکثر Clones (کلونها) تقریبا شبیه هم می باشند. برای انعطاف پذیر بودن قرارداد و قابل اعتماد بودن برای کاربر، اطلاعاتی از جمله قیمت گذاری و استراتژی صدور باید کاملا جدا از منطق اصلی قرارداد باشند. همچنین باید طراحی مجزا و Single-responsibility (قاعده تک-وظیفهای) داشته باشد. علاوه بر این بهتر است که در خود قرارداد ERC721، عرضه (MaxSupply) محدود شود و قابلیت تغییر آن فقط در دست ادمین باشد.
2- عدم استفاده از امنیت مبتنی بر نقش
یکی دیگر از اشتباهات قراردادهای NFT، عدم استفاده از امنیت مبتنی بر نقش می باشد. از آن جایی که قابلیت دسترسی بعضی از عملیات ها (از جمله تغییر یا صدور پارامترهای عرضه) فقط باید برای آدرسهای مجاز باشند، بنابراین قراردادهای توکن نیازمند نوعی کنترل دسترسی می باشند. استفاده از یک مدل Ownable، می تواند برای اجرای این نوع کنترل دسترسی، ساده ترین راه باشد. (از آن جایی که این فقط یک نیاز ساده است، معمولا از قرارداد Ownable OpenZeppelin استفاده میشود.) البته توصیه میشود بنا به برخی دلایل از Role-Based Security (کنترل دسترسی مبتنی بر نقش) استفاده شود.
معمولا به دلیل سادگی از مدل Ownable استفاده میشود که ظاهرا انتخاب مناسبی می باشد. این امکان وجود دارد که فقط یک نفر قرارداد را برای همیشه مدیریت کند. همچنین افراد ترجیح می دهند زمانی که هزینه کم است، پیشبینی و مقابله با حوادث آینده (Future-proofing) را انتخاب کنند. OpenZeppelin (امنیت نقش محور) در مقایسه با مدل Ownable کمی پیچیده تر و گران تر می باشد. در صورت زیاد بودن هزینه گس، افراد می توانند فقط برای نیاز موجود، از کد امنیتی نقش محور (چه OpenZeppelin و چه مدل خاص مدنظر خود) استفاده کنند.
در صورتی که علاقه مند به آشنایی با سرویس های بلاک چین برای NFT، می توانید با مراجعه به مقاله بهترین سرویس های بلاک چین برای NFT، با این سرویس ها و مزایا و معایب آنها آشنا شوید.
برای استفاده از امنیت نقش محور، دلیل مهم تری نیز وجود دارد. در واقع امنیت نقش محور این امکان را به افراد می دهد تا از خود قرارداد ERC721، کاربرد (اطلاعات قیمتگذاری و فروش) را جدا کنند. همچنین به افراد این امکان را میدهد تا به عنوان صادر کننده (ضرب کننده)، یک قرارداد جداگانه ای را انتخاب کنند. همچنین این امکان را به افراد می دهد که بدون این که نیاز باشد به آن مجوز مدیریت کامل را بدهند، به آن نقش «صادرکننده» را اختصاص دهند.
در چنین شرایطی، ادمینها (که احتمالا انسان هستند) مجوزهای مهم از جمله ایجاد تغییر در مجوزها را در دست خواهند داشت؛ که افراد به صادر کننده دیگر نیازی نداشته باشند، به سادگی اقدام به لغو آن کنند و سپس به قرارداد دیگری که مناسب تر، ماژولار و امن تر است، نقش صادر کننده آن را به همراه استراتژی جدید واگذار کنند. از طریق این روش و بر اساس کاربردهای پروژه، عملیات دیگر را نیز میتوان مدیریت کرد.
3- استفاده نکردن از ERC-165 یا قابلیت Introspection
استفاده نکردن از ERC-165 یا قابلیت Introspection، یکی دیگر از اشتباهات قراردادهای NFT می باشد. اکثر قراردادها و یا توکن ها از ERC-165 استفاده نمی کنند و یا این که به طور مناسب آن را به اجرا در نمی آورند. اهمیت ERC-165 در ایجاد قابلیت Interoperability می باشد. ERC- 165 باعث افزایش سازگاری قرارداد می شود و این احتمال وجود دارد که صرافی ها بخواهند در جریان ساختار حق امتیاز NFT افراد باشند. برای اجرای درست این استاندارد در قراردادها باید به این قوانین توجه کرد:
1- هر کلاس والدی که اجرا کننده ERC-165 می باشد، باید در فهرست Override (لغو) قرار بگیرد. در چنین شرایطی، در زمان استفاده از دستور Super.supportsInterface به طور خودکار، آنها نیز فعال می شوند.
2- اگر یک رابط پیاده سازی در کلاس والد نباشد، امکان اضافه کردن آن از طریق کلمه an یا یک جمله به شکل زیر فراهم می باشد:
مثال:
در صورتی که کد فاقد کلاس والدی باشد که بتواند اجرای ERC-165 را انجام دهد، باید به نوع دوم اشاره کرد. همچنین در صورتی که کد کاربر هیچ رابط دیگری را به جز ERC-165 اجرا شده توسط کلاس والد، اجرا نکند، کاربر به نوع دوم نیازی ندارد. اگر چه اجرای صحیح ERC-165 اهمیت زیادی دارد اما کاملا اختیاری است. کاربر با استفاده از این اجرا می تواند توکنی سازگار با سیستمهای زیادی از جمله صرافی ها و یا حتی سیستم های پیاده سازی نشده، داشته باشد. استفاده از ERC-165 با بلوغ این حوزه و به مرور زمان افزایش خواهد یافت.
تاکنون ابزارهای متعددی برای توکن های NFT ایجاد شده است که برای شناخت آنها می توانید به مقاله بهترین ابزارهای کاربردی NFT، مراجعه کنید و با نحوه کار آنها آشنا شوید.
4- تست نکردن کامل قبل از استقرار
تست نکردن کامل قبل از استقرار یکی دیگر از اشتباهات قراردادهای NFT می باشد. حتی در صورت استاندارد بودن توکن ERC721 و استفاده از تمام کتابخانه ها و کلاس های والد شخص ثالث بدون تغییرات خاصی و همچنین اطمینان کاربر از امن بودن و تست کد شخص ثالث، باز هم باید به طور کامل کد خود را تست کند. کاربران قبل از این که کد را بر روی شبکه اصلی مستقر کنند، برای تست و رفع ایراد فقط یک بار فرصت دارند. اول از همه، کاربر باید Unit Testing (تست یونیت) را انجام دهد. نوع چهارچوبی که برای تست مورد استفاده قرار می گیرد مهم نیست. می توان از چارچوب های Ethers، Hardhat و Mocha استفاده کرد.
برای آشنایی با نقش توکن های NFT در فیلم سازی، بر روی لینک مربوطه کلیک کنید.
در انتخاب چهارچوب تست باید به نکات مهمی از جمله پوشش تست، پوشش موارد استثنایی، پوشش موارد Happy-path و عمق و گستردگی موارد Edge دقت کرد. حتی اگر کاربر از کدی که قبلا به خوبی تست شده (OpenZeppelin) استفاده میکند، باز هم امکان دارد که کد دچار مشکلاتی مربوط به موارد ذکر شده بالا شده باشد، بنابراین مجددا باید آزمایش شود. همچنین در گذشته OpenZeppelin باگ هایی داشته که احتمال دارد این باگها دوباره در آینده نیز ظاهر شوند.
کاربران می توانند برای صرفه جویی در وقت برای تمام توکنهای ERC721، توکنهای ERC1155، توکن های ERC20 و غیره مجموعه ای از تستها را آماده کنند و از آنها در هر پروژه ای استفاده کنند. همچنین میتوانند به پروژه ها موارد بیشتری را اضافه کنند و اقدام به سفارشی سازی استانداردها کنند. به این ترتیب در وقت آنها صرفه جویی میشود. تست های یونیت باید شامل پیاده سازی استاندارد ERC165، عملیات پایه (صدور و انتقال)، کنترل دسترسی، مکث پذیری (در صورتی که قرارداد دارای قابلیت مکث باشد) و غیره باشد. کاربران برای تست پوشش خود می توانند از یکی از پکیجهای پلتفرم Nodejs، به نام Solidity-Coverage استفاده کنند.
برای کسب اطلاعاتی در مورد پل های میان زنجیره ای NFT مقاله مربوطه را مطالعه فرمایید.
استفاده از ابزارهای خودکار در تستها می توانند به کاربران کمک زیادی کنند. معمولا شرکتهای بزرگ بازبینی امنیتی از جمله Certik و Consensys از استاندارد های صنعتی مانند Manticore، Slither و Mythril استفاده می کنند. Solidity-coverage نشان دهنده درصد تخمینی پوشش تستهای یونیت کاربران می باشد. Solgraph نیز ابزاری برای مشاهده روابط و ارتباطات موجود در کد قرارداد می باشد. همچنین در برنامه ریزی تست ها استفاده از آن می تواند مفید باشد. Echidna نیز یک ابزار پیچیده و مفید می باشد. بهتر است کاربران همیشه از یک روش Test-first (تست محور) استفاده کنند تا علاوه بر داشتن پوشش تست خوب، تست ها به مشخصات پروژه نزدیک شوند. به طور خلاصه می توان گفت به این موارد باید توجه شود:
- در تمام موارد باید یونیت تست کامل و عمیق انجام شود.
- تست و آزمایش دستی
- استفاده از ابزارهای خودکار از جمله Slither، Manticore، Mythril، Echidna و Solidity-coverage
توصیه: تایید قرارداد در اتر اسکن
پس از این که در سایت اتر اسکن قرارداد تایید شود و از این پلتفرم تیک سبز دریافت شود، افزایش مسئولیت پذیری و حس اعتماد را به دنبال خواهد داشت. به این ترتیب به فردی که قرارداد شما را برای اولین بار مشاهده می کند و به ارزیابی ریسک های سرمایه گذاری در آن می پردازد، کمک زیادی می کند. در اتر اسکن علاوه بر قراردادهای NFT، می توان همه قراردادهای دیگر را نیز تایید کرد. به طور کلی می توان گفت افراد با شناخت اشتباهات قراردادهای NFT، می توانند از بسیاری از مشکلات احتمالی جلوگیری کنند.
نظر بدهید