فایلهای منبع میتوانند حاوی تعداد دلخواهی از تعاریف قرارداد، دستورهای ایمپورت ، دستورهای پراگما، struct، enum، تابع، خطا، تعاریف متغیر ثابت باشند.
Table of contents [Show]
فایلهای منبع میتوانند حاوی تعداد دلخواهی از تعاریف قرارداد، دستورهای ایمپورت ، دستورهای پراگما، struct، enum، تابع، خطا، تعاریف متغیر ثابت باشند.
در صورت در دسترس بودن کد منبع ، اعتماد به قرارداد هوشمند میتواند بهتر ایجاد شود. از آنجا که در دسترس قرار دادن کد منبع همیشه مشکلات حقوقی مربوط به حق چاپ را تحت تأثیر قرار می دهد، کامپایلر سالیدیتی استفاده از مشخص کنندهِ لایسنس SPDX قابلِ خوانده شدن توسطِ ماشین را ترغیب میکند. هر فایل منبع باید با یک کامنت که نشان دهد لایسنس آن است شروع شود:
SPDX-License-Identifier: MIT//
کامپایلر تأیید نمیکند که مجوز بخشی از لیست مجاز SPDX است، اما رشته ارائه شده در فراداده بایت کد را شامل میشود.
اگر نمیخواهید مجوزی را تعیین کنید یا اگر کد منبع، منبع باز نیست؛ لطفاً از مقدار ویژه UNLICENSED استفاده کنید. توجه داشته باشید که UNLICENSED (استفاده مجاز نیست، در لیست مجوز SPDX وجود ندارد) با UNLICENSE متفاوت است (کلیه حقوق را به همه اعطا میکند). Solidity از npm recommendation پیروی می کند.
البته ارائه این کامنت شما را از سایر تعهدات مربوط به صدور لایسنس مانند نیاز به ذکر مجوز خاص در هِدر هر فایل منبع یا دارنده اصلی حق چاپ خلاص نمی کند.
کامنت توسط کامپایلر در هر کجای فایل در سطح فایل شناسایی میشود، اما توصیه میشود آن را در بالای فایل قرار دهید.
اطلاعات بیشتر در مورد نحوه استفاده از مشخص کننده لایسنس SPDX را میتوانید در وب سایت SPDX بیابید.
کلمه کلیدی pragma یا پراگما برای فعال کردن برخی از ویژگیهای کامپایلر یا بررسیها استفاده میشود. یک دستورالعمل پراگما همیشه محلی برای یک فایل منبع است، بنابراین اگر میخواهید آن را در کل پروژه خود فعال کنید، باید پراگما را به تمام فایلهای خود اضافه کنید. اگر فایل دیگری را ایمپورت کنید، پراگمای آن فایل به طور خودکار در فایل وارد شده اعمال نمیشود.
فایلهای منبع را میتوان (و باید) با یک نسخه ، نسخه بندی کرد تا کامپایل با نسخههای کامپایلر آتی را رد کند که ممکن است تغییرات ناسازگار را معرفی کند. ما سعی میکنیم این موارد را به حداقل برسانیم و آنها را به گونه ای معرفی کنیم که تغییر در سِمَنتیکها نیاز به تغییرسینتکس داشته باشد، اما این امر همیشه امکان پذیر نیست. به همین دلیل، همیشه ایده خوبی است که حداقل برای نسخههایی که شامل تغییرات خراب کننده هستند، از تغییرات جدید استفاده کنید. این نسخهها همیشه نسخههایی از فرم 0.x.0 یا x.0.0 دارند.
نسخه پراگما به شرح زیر استفاده می شود :
pragma solidity ^0.5.2;
یک فایل منبع با خط بالا با یک کامپایلر جدیدتر از نسخه 0.5.2 کامپایل نمیشود و همچنین در یک کامپایلر که از نسخه 0.6.0 شروع میشود کار نمیکند (این شرط دوم با استفاده از ^ اضافه میشود). از آنجا که تا قبل از نسخه 0.6.0 هیچ تغییر جدید ایجاد نخواهد شد، میتوانید مطمئن باشید که کد شما به همان روشی که شما در نظر داشتید، کامپایل میشود. نسخه دقیق کامپایلر ثبت نشده است، بنابراین انتشار رفع خطا همچنان امکان پذیر است.
میتوان قوانین پیچیدهتری را برای نسخه کامپایلر تعیین کرد، اینها از همان سینتکسی استفاده میکنند که توسط npm استفاده میشود.
توجه داشته باشید
با استفاده از نسخه pragma نسخه کامپایلر تغییر نمیکند. همچنین ویژگیهای کامپایلر را فعال یا غیرفعال نمیکند. این فقط به کامپایلر دستور میدهد که بررسی کند آیا نسخه آن با نسخه مورد نیاز پراگما مطابقت دارد یا خیر. اگر مطابقت نداشته باشد، کامپایلر خطایی را صادر میکند.
با استفاده از pragma abicoder v1 یا pragma abicoder v2 میتوانید از بین دو پیاده سازی رمزگذار و رمزگشای ABI یکی را انتخاب کنید.
کدگذار جدید(v2) ABI قادر به رمزگذاری و رمزگشایی آرایه ها و ساختارهای تو در تو دلخواه است. جدای از پشتیبانی از انواع بیشتر، شامل اعتبار سنجی و بررسی های ایمنی گسترده تر است که ممکن است منجر به هزینههای گس بیشتر شود، اما امنیت را نیز افزایش می دهد. از Solidity 0.6.0 غیر آزمایشی در نظر گرفته می شود و به طور پیش فرض با شروع Solidity 0.8.0 فعال میشود. رمزگذار ABI قدیمی هنوز هم می تواند با استفاده از ;pragma abicoder v1 انتخاب شود.
مجموعه نوعهای پشتیبانی شده توسط رمزگذار جدید یک مجموعه فوق العاده دقیق از نوعهای پشتیبانی شده توسط رمزگذار قدیمی است. قراردادهایی که از آن استفاده میکنند میتوانند با قراردادهایی که بدون محدودیت نیستند ارتباط برقرار کنند. بازگشت فقط تا زمانی امکان پذیر است که قرارداد غیر abicoder v2 سعی در فراخوانیهایی نداشته باشد که نیاز به انواع رمزگشایی داشته باشند که فقط توسط رمزگذار جدید پشتیبانی میشوند. کامپایلر میتواند این مورد را تشخیص دهد و خطایی ایجاد کند. فعال کردن abicoder v2 قرارداد برای اینکه خطا برطرف شود، کافی است.
توجه داشته باشید
این پراگما برای همه کدهای تعریف شده در فایل در جایی که فعال شدهاست اعمال میشود، صرف نظر از اینکه سرانجام این کد به کجا ختم میشود. این بدان معناست که قراردادی که فایل منبع آن برای کامپایل با کدگذار ABI v1 انتخاب شدهاست، همچنان میتواند حاوی کدی باشد که با به ارث بردن رمزگذار جدید از قرارداد دیگر، از رمزگذار جدید استفاده کند. این درصورتی مجاز است که نوعهای جدید فقط در داخل استفاده شوند و در امضاهای تابع خارجی نباشند.
توجه داشته باشید
تا سالیدیتی نسخه 0.7.4، میتوان با استفاده از pragma experimental ABIEncoderV2 رمزگذار ABI v2 را انتخاب کرد، اما صریحاً رمزگذار v1 را نمیتوان انتخاب کرد زیرا پیش فرض بود.
پراگما دوم ، پراگما آزمایشی است. میتوانند برای فعال کردن ویژگیهای کامپایلر یا زبان استفاده شوند که هنوز به طور پیش فرض فعال نشدهاند. پراگماهای آزمایشی زیر در حال حاضر پشتیبانی میشوند:
از آنجا که رمزگذار ABI v2 دیگر آزمایشی محسوب نمیشود، میتوان از طریق سالیدیتی نسخه 0.7.4 از طریق pragma abicoder v2 آن را انتخاب کرد (لطفاً به قسمت بالا مراجعه کنید).
این مؤلفه باید در هنگام ساخت کامپایلر سالیدیتی فعال شود و بنابراین در تمام باینریهای سالیدیتی در دسترس نیست. دستورالعملهای نسخه، نحوه فعال سازی این گزینه را توضیح میدهند. برای نسخههای اوبنتو PPA در اکثر نسخهها فعال شده، اما برای تصویرهای داکر ، باینریهای ویندوز یا باینریهای لینوکس نسخه ایستا ، فعال نیست. اگر یک حل کننده SMT را به صورت محلی نصب کرده باشید و solc-js را از طریق گره (نه از طریق مرورگر) اجرا کنید، میتواند از طریق smtCallbackبرای solc-js فعال شود.
اگر ;pragma experimental SMTChecker استفاده میکنید، هشدارهای ایمنی بیشتری دریافت میکنید که با پرس و جو از یک حل کننده SMT بدست میآیند. این مولفه هنوز از تمام ویژگیهای زبان سالیدیتی پشتیبانی نمیکند و احتمالاً هشدارهای زیادی را در بر داشته باشد. در صورت گزارش ویژگیهای پشتیبانی نشده، ممکن است تجزیه و تحلیل کاملاً مناسب نباشد.
سالیدیتی برای کمک به ماژولی بودن کد شما که مشابه آنچه در جاوا اسکریپت در دسترس است (از ES6 به بعد)، از دستورات ایمپورت پشتیبانی میکند. با این حال، سالیدیتی مفهوم اکسپورت به صورت پیشفرض را پشتیبانی نمیکند. در سطح جهانی، میتوانید از دستورات ایمپورت به شکل زیر استفاده کنید:
# Import section
import filename
قسمت filename یک import path نامیده می شود. این عبارت همه نمادهای سراسری را از “نام فایل” (و نمادهای وارد شده در آنجا) به دامنه جهانی فعلی وارد می کند (متفاوت با ES6 اما برای Solidity سازگار با گذشته). این فرم برای استفاده توصیه نمیشود، زیرا به طور غیرقابل پیش بینی فضای نام را آلوده میکند. اگر آیتمهای سطح بالای جدیدی را داخل «نام فایل» اضافه کنید، به طور خودکار در همه فایلهایی که مانند این از «نام فایل» وارد میشوند ظاهر میشوند. بهتر است نمادهای خاص را به صراحت وارد کنید.
مثال زیر یک نماد جهانی symbolName ایجاد میکند که اعضای آن همه نمادهای جهانی از “filename ” هستند:
import * as symbolName from "filename";
که منجر به در دسترس بودن همه نمادهای جهانی در قالب symbolName.symbol میشود.
گونهای از این سینتکس که بخشی از ES6 نیست، اما احتمالاً قابل استفاده باشد:
که معادل
; “import * as symbolName from “filename
است.
در صورت تداخل نامگذاری، میتوانید هنگام ایمپورت کردن، نمادها را تغییر نام دهید. به عنوان مثال، کد زیر نمادهای جهانی جدید alias و symbol2 را ایجاد میکند که به ترتیب از داخل “filename ” به symbol1 و symbol2 مراجعه میکند.
import { symbol1 as alias, symbol2 } from "filename";
Import Paths
کامپایلر Solidity برای اینکه بتواند از ساختهای قابل تکرار در همه پلتفرمها پشتیبانی کند، باید جزئیات سیستم فایلی را که فایلهای منبع در آن ذخیره میشوند، انتزاع کند. به همین دلیل مسیرهای واردات (Import Paths) مستقیماً به فایلهای موجود در سیستم فایل میزبان اشاره نمیکنند. در عوض کامپایلر یک پایگاه داده داخلی (فایل سیستم مجازی یا به اختصار VFS) نگهداری می کند که در آن به هر واحد منبع یک نام واحد منبع منحصر به فرد اختصاص داده می شود که یک شناسه غیر شفاف و بدون ساختار است. مسیر واردات مشخص شده در یک عبارت import به نام واحد منبع ترجمه شده و برای یافتن واحد منبع مربوطه در این پایگاه داده استفاده می شود.
با استفاده از استاندارد JSON API می توان مستقیماً نام و محتوای همه فایلهای منبع را به عنوان بخشی از ورودی کامپایلر ارائه داد. در این مورد نام واحد منبع واقعا دلخواه است. با این حال، اگر میخواهید کامپایلر به طور خودکار کد منبع را پیدا کرده و در VFS بارگذاری کند، نام
واحد منبع شما باید به گونهای ساختار یافته باشد که مکان یابی آنها را برای یک بازگشت به تماس وارد کند. هنگامی که از کامپایلر خط فرمان استفاده میکنید، پیشفرض فراخوانی واردات فقط از بارگیری کد منبع از سیستم فایل میزبان پشتیبانی میکند، به این معنی که نام واحد منبع شما باید مسیر باشد. برخی از محیطها تماسهای سفارشی را ارائه میکنند که همه کارهتر هستند. به عنوان مثال Remix IDE یکی را ارائه می دهد که به شما امکان می دهد فایل ها را از HTTP، IPFS و URL های Swarm وارد کنید یا مستقیماً به بسته های موجود در رجیستری NPM مراجعه کنید.
برای توضیح کامل سیستم فایل مجازی و منطق تفکیک مسیر مورد استفاده توسط کامپایلر به Path Resolution مراجعه کنید.
نظرات تک خطی (//) و نظرات چند خطی (/*…*/) امکان پذیر است.
// This is a single-line comment.
/*
This is a
multi-line comment.
*/
توجه داشته باشید
یک کامنت تک خطی توسط هر پایان دهنده خط unicode (LF ، VF ، FF ، CR ، NEL ، LS یا PS) در رمزگذاری UTF-8 خاتمه مییابد. ترمیناتور بعد از کامنت هنوز بخشی از کد منبع است، بنابراین اگر یک نماد ASCII نباشد (اینها NEL ، LS و PS هستند)، منجر به خطای تجزیه میشود.
علاوه بر این، نوع دیگری از کامنت به نام کامنت NatSpec وجود دارد که در راهنمای استایل به تفصیل آورده شده است. آنها با یک اسلش سه گانه (/// ) یا یک بلوک ستاره دوتایی (/** … */ ) نوشته میشوند و باید مستقیماً بالاتر از دستورات یا دستورات تابع استفاده شوند.