همه چیز درباره زبان سالیدیتی برای برنامه‌نویسی بلاکچین

وقتی صحبت از «اتریوم» به میان می‌آید، شاید اولین چیزی که به ذهنتان می‌رسد، قرارداد هوشمند باشد. اگر خیلی با قراردادهای هوشمند آشنا نیستید باید بدانید، قراردادهای هوشمند برنامه‌هایی هستند که روی بلاک چین اتریوم قرار دارند. به‌وسیله چنین قراردادهایی می‌توان برنامه‌هایی غیرمتمرکز ساخت که بدون هیچ واسطه، کنترل و توقفی تا ابد به کار خود ادامه می‌دهند. در این مقاله با زبان برنامه‌نویسی سالیدیتی که زبان مخصوص اتریوم برای قراردادهای هوشمند است، آشنا می‌شوید.

درست مانند برنامه‌های رایانه‌ای، قراردادهای اتریوم به یک زبان برنامه‌نویسی نوشته می‌شوند که «سالیدیتی» (Solidity) نام دارد. لازم به ذکر است که زبان‌های برنامه‌نویسی دیگری هم وجود دارند که می‌توان برای ایجاد قراردادهای هوشمند در شبکه اتریوم، از آنها استفاده کرد، اما این روزها انتخاب اکثر برنامه‌نویسان این حوزه سالیدیتی است. در ادامه قصد داریم به شما بگوییم زبان برنامه‌نویسی سالیدیتی چیست و چطور می‌توانید برنامه‌نویسی با زبان سالیدیتی را یاد بگیرید.

سالیدیتی به‌عنوان یک زبان برنامه‌نویسی

امروزه بیشتر برنامه نویسان از یک یا چند نمونه از شاخه‌های زبان‌های برنامه‌نویسی استفاده می‌کنند. مثلاً برخی از شاخه زبان‌های C که خود شامل چندین زبان C#، C++ و …است، پایتون یا جاوا و … استفاده می‌کنند. سالیدیتی به‌نوعی طراحی‌شده که یادگیری‌اش برای برنامه‌نویسانی که با یک یا چند زبان‌ برنامه‌نویسی کار کرده‌اند، آسان باشد.

اگر قبلا فقط در دوران دانشگاه با زبانی مانند «ویژوال بیسیک» کار کرده‌اید، یادگیری سالیدیتی برایتان کمی مشکل خواهد بود و اما اگر با زبان‌هایی همچون پایتون یا C کار کرده‌ باشید، سالیدیتی تا حد زیادی برای شما آشنا خواهد بود.

سالیدیتی از مفاهیم بسیاری استفاده می‌کند که در دیگر زبان‌های برنامه‌نویسی دیگر مشابه آنها را دیده‌اید. برای مثال سالیدیتی دارای متغیرها، توابع، کلاس‌ها، عملیات‌های محاسباتی، رشته‌ها و … است. در حالی‌ که در یک زبان برنامه‌نویسی مانند C، برنامه‌نویس نوعی تابع اصلی مانند {int main(arg۱, arg2) { //code ایجاد می‌کند، سالیدیتی دارای مفهومی با عنوان «قرارداد» (Contract) است که طی روندی مشابه ساخته می‌شود.

Contract

همان‌طور که در تصویر بالا مشاهده می‌کنید، کدهای سالیدیتی شباهت بسیاری به کدهای C++ یا C# و حتی جاوا اسکریپت دارند. برنامه نویسان پایتون نیز در هنگام کار با سالیدیتی متوجه می‌شوند که نوع متغیرها در این زبان باید به‌‌طور صریح تعیین شوند.

سالیدیتی جدید است با منابع آموزش محدود

معمولاً اگر کسی بخواهد یک زبان برنامه‌نویسی جدید را فرا بگیرد، می‌تواند از میان بی‌نهایت منابع و کتابی که در آن زمینه وجود دارد، انتخاب کند. برای مثال اگر شما بخواهید جاوا اسکریپت یاد بگیرید، صدها کتاب مختلف وجود دارند که می‌توانید به‌طور خودآموز از آنها استفاده کنید. در اکثر این منابع تمرین‌ها و مطالبی وجود دارند که می‌توانید بدون نیاز به کلاس یا دوره خاص از آنها استفاده کنید. برای تعیین کیفیت هر یک نیز می‌توانید به صفحه خرید آن کتاب در اینترنت مراجعه و نظرات دیگران را در موردش مطالعه کنید.

با وجود اینکه مستندات و منابع بسیاری در خصوص یادگیری کدهای سالیدیتی وجود دارد، یادگیری این زبان برای کسی که کاملاً با آن ناآشناست و به زبان برنامه‌نویسی دیگری هم مسلط نیست، آن‌هم از روی چنین مستنداتی مشکل و گاها حتی غیرممکن خواهد بود. به‌عبارت‌دیگر از این جزوه‌ها و منابع باید همانند یک فرهنگ لغت استفاده و در هنگام نیاز به آنها رجوع کرد و نمی‌توان برای یادگیری یک زبان ابتدا به سراغ فرهنگ لغت آن رفت.

اگر فردی وقت کافی برای یادگیری نگذارد و صبر کافی نیز به خرج ندهد، و از طرف دیگر پیش‌زمینه برنامه‌نویسی نیز نداشته باشد، یادگیری سالیدیتی اصلاً آسان نخواهد بود. اما اگر پشتکار داشته باشید، حتی از روی مستندات و کدهای موجود هم می‌توانید این زبان را یاد بگیرید.

دوره‌ها و آموزش‌های سالیدیتی

برای آن دسته از افراد که تجربه برنامه‌نویسی دارند، یکی از گزینه‌های مناسب برای یادگیری سالیدیتی استفاده از وب‌سایت «کریپتو زامبی» (Crypto Zombies) است. این وب‌سایت که شباهت بسیاری با پلتفرم «کد آکادمی» دارد، تکالیف کوچکی را در اختیارتان می‌گذارد که می‌توانید به‌صورت مستقیم در مرورگرتان آنها را انجام دهید. درست یا غلط بودن و اشکالات شما نیز به‌صورت آنی برای شما نمایش داده خواهد شد. این وب‌سایت به شما کمک می‌کند که با استفاده از زبان سالیدیتی یک بازی زامبی بسازید.

Crypto Zombies

انجام فصل اول آموزش چیزی در حدود دو ساعت زمان لازم دارد و اندکی نیز سخت است اما با کمی صبر و دقت می‌توانید از پس آن بر بیایید. توسعه‌دهندگان این وب‌سایت هر چند هفته یک‌بار تکالیف جدیدی را برای کاربران مهیا می‌کنند. با به اتمام رساندن تمامی تکالیف، می‌توانید یک بازی کامل بر پایه سالیدیتی داشته باشید.

صد البته ساخت چنین بازی‌ای نمی‌تواند شما را به یک برنامه‌نویس حرفه‌ای سالیدیتی تبدیل کند، اما برای شروع کار و ایجاد یک پیش‌زمینه ذهنی در ارتباط با این زبان، عالی است چرا که بسیاری از نکات کلیدی و حیاتی که باید برای کار با سالیدیتی بدانید را به شما گوشزد می‌کند.

در صورتی‌ که تجربه خاصی در خصوص برنامه‌نویسی ندارید می‌توانید از دوره‌های رایگان سایت CodeAcademy، استفاده کنید. به یاد داشته باشید که در صورت تسلط بر پایتون یا جاوا اسکریپت، می‌توانید به‌راحتی از کریپتو زامبی استفاده کنید.

اگر به دوره‌های پیشرفته‌تری در این خصوص نیاز داشته باشید، می‌توانید از وب‌سایت «بلاک گیکس» (Block Geeks) استفاده کنید.

دوره‌های غیر رایگان سالیدیتی و گواهینامه‌های آنلاین

در سال‌های اخیر، وب‌سایت های بسیاری دوره‌های غیر رایگان خود را در خصوص یادگیری زبان برنامه‌نویسی سالیدیتی برگزار می‌کنند. «بیت دگری» (BitDegree) ازجمله این وب‌سایت‌هاست که با هدف بالا بردن اطلاعات عموم و آموزش‌های حوزه بلاک چین، فعالیت می‌کند. به‌وسیله این وب‌سایت مهارت آموزان می‌توانند در دوره‌های آنلاین شرکت کنند و در نهایت با به اتمام رساندن آنها، مدرکی آنلاین دریافت کنند که بر روی بلاک چین اتریوم ثبت می‌شود. دوره‌های بیت‌دگری در زمینه‌ی سالیدتی بین ۱۰ تا ۸۰ دلار قیمت دارند. البته شاید دوره‌های رایگان یا با تخفیف قابل‌توجه هم در آن پیدا کنید.

یودمی

از دیگر وب‌سایت ها در این زمینه می‌توان به udemy.com اشاره کرد که دوره‌های ویدیوئی زیادی در زمینه‌های مختلف ارائه می‌کند. هزینه دوره سالیدیتی در این وب‌سایت ۲۰۰ دلار است که به‌تازگی نیز با تخفیف ۹۰ درصدی عرضه می‌شود، البته همیشه این میزان تخفیف را ندارد. گزینه دیگر که با قیمت بسیار بالاتری دوره‌های سالیدیتی برگزار می‌کند B9LAB.com است. دوره‌های توسعه اتریوم این وب‌سایت طی ۹ هفته و هفته‌ای ۶ تا ۱۰ ساعت طول می‌کشد و هزینه‌ای بالغ بر ۱۴۵۰ یورو یا ۱۷۵۰ دلار روی دستتان خواهند گذاشت. به‌علاوه یک دوره رایگان کار با اتریوم با عنوان Ethereum ۱۰۱ نیز در این وب‌سایت موجود است که می‌توانید با گذراندن آن بیشتر با روش‌های تدریس و شیوه‌ی آموزشی آنها آشنا شوید.

آیا سالیدیتی ارزش یادگیری دارد؟

اگر به دنبال یادگیری سالیدیتی برای شغل خود هستید، پیش از یادگیری باید بدانید به چه مهارت‌های دیگری نیاز دارید. بااینکه یاد گرفتن مهارت‌های مربوط به بلاک چین بسیار ارزشمند است، احتمالا لازم باشد کسی که می‌خواهد به این حوزه وارد شود به یکی از زبان‌های برنامه‌نویسی تسلط کامل داشته باشد. مثلا در یک آگهی شغلی در این زمینه عنوان شده است کسی را می‌خواهند که نه‌تنها با سالیدتی، بلکه به زبا‌های ترافل، نودجی‌اس و گولنگ هم آشنا باشد.

اگر حاضرید سال‌ها وقت خود را صرف یادگیری سالیدیتی کنید، می‌توانید امیدوار باشید که در سال‌های آینده به شغلی مناسب نیز دست‌ یابید.

در کنار سالیدیتی زبان برنامه‌نویسی دیگری با عنوان «سرپنت» (Serpent) نیز وجود دارد که بر پایه پایتون ساخته‌شده است. از آنجایی‌ که پایتون زبانی ساده برای یادگیری است، اگر به دنبال چنین زبانی برای ایجاد قراردادهای هوشمند دارید می‌توانید از سرپنت استفاده کنید. این مسئله را نیز به یاد داشته باشید که کدهای نگارش شده به‌وسیله سالیدیتی و سرپنت را می‌توانید به‌راحتی برای اتریوم کلاسیک و RSK و دیگر پلتفرم‌های قراردادهای هوشمند نیز ترجمه کنید.

در حال حاضر سالیدیتی پادشاه زبان‌های برنامه‌نویسی مرتبط با قراردادهای هوشمند است و یادگیری آن می‌تواند به یادگیری دیگر زبان‌های قراردادهای هوشمند نیز کمک کند.

سالیدیتی یک زبان برنامه نویسی برای نوشتن قراردادهای هوشمند روی شبکه بلاکچین اتریوم می باشد. این زبان یک ساختار قرارداد-محور دارد، که یعنی قراردادهای هوشمند مسئولیت ذخیره سازی تمامی منطق برنامه نویسی شده را با تراکنش های بلاکچین دارند. این زبان یک زبان برنامه نویسی high-level است که شباهت بسیاری به زبانی هایی مانند جاوا اسکریپت، پایتون و ++C دارد. این زبان یک هدف اصلی را دنبال می کند و آن هم پیاده سازی روی ماشین مجازی اتریوم یا Ethereum Virtual Machine است که به صورت EVM خلاصه می شود. این ماشین مجازی روی نود (Node) های اتریوم هاست شده و از این طریق به شبکه بلاکچین اتریوم وصل می شود.

این زبان به صورت استاتیک نوشته شده و قابلیت هایی مثل موروثی بودن (inheritance)، کتابخانه ها و خیلی موارد دیگر رو شامل می شود. به طور خلاصه تمامی قابلیت ها و ظرفیت های مورد نیاز برای یک نرم افزار بلاکچینی را دارد.

تصویر IDE Remix متعلق به شبکه اتریوم
تصویر IDE Remix متعلق به شبکه اتریوم

در این دوره آموزشی از محیط توسعه Remix برای نوشتن کدها استفاده می کنیم. رمیکس یک IDE برپایه Browser است که به شما اجازه نوشتن، کامپایل کردن و پیاده سازی قراردادهای هوشمند را دارد. علاوه بر این فیچرهای مختلفی مثل ذخیره فایل را هم داراست.

با استفاده از Remix ما نیازی به نصب برنامه یا ابزارهای توسعه ای نداریم. می توانید با باز کردن همزمان Remix در تب دیگری این دوره را دنبال کنید.

https://remix.ethereum.org/

کد سالیدیتی را با باز کردن یک فایل شروع می کنید. شما می توانید از سمت چپ بالای صفحه فایل جدیدی را باز کنید.


فایل با عنوان MyContract.sol را ایجاد کنید. در خط اول این فایل، نسخه سالیدیتی که می خواهیم از آن استفاده کنیم را وارد می کنیم:

۱pragma solidity ^0.4.24;

در این مرحله قرارداد هوشمد را به شکل زیر می نویسیم:

۱۲۳۴pragma solidity ^0.4.24;
contract MyContract {
    // ...
}

چند مورد را قبل از ادامه توضیح بدم. یک قرارداد هوشمند مجموعه ای کدهایی است که روی شبکه اتریوم پیاده سازی می شود. به شکلی شبیه API در microservice ها عمل می کند، با این تفاوت که دسترسی را برای عموم کاربران فراهم می کند. همه کد قراردادهای هوشمند به صورت عمومی در دسترس است و هر کسی می تواند با اتصال به شبکه به قرارداد هوشمند وصل شده و قرارداد را بازخوانی کند.

اکنون می توانیم توسعه قرارداد هوشمند را ادامه بدیم. اول از همه، ما یک Storage ساده قرارداد هوشمند را برنامه ریزی می کنیم، تا با استفاده از آن بتوانیم:

  • داده ها را ذخیره کنیم
  • داده ها را بازخوانی کنیم

با ساخت یک رشته داده در قرارداد هوشمند شبیه این تصویر شروع می کنیم و با متغیری به اسم value شروع می کنیم. سالیدیتی یک زبان استاتیک است، برای همین باید در ابتدا نوع متغیر را در زمان تعریف کردن آن مشخص کنیم:

۱۲۳۴۵pragma solidity ^0.4.24;
contract MyContract {
    string value;

}

این متغیر “state variable” نامیده می شود چون دقیقا داده را روی بلاکچین حفظ می کند. هز زمان که داده ای را به این متغیر تخصیص بدیم، رشته ای روی شبکه بلاکچین ثبت می شود. دقت کنیم که این داده روی Storage ذخیره می شود نه روی حافظه (Memory). این متغیر ویژگی دیگری هم دارد، توسط تمام قرارداد هوشمند قابل دسترس است، برعکس local variable هایی که فقط درون function شناسایی می شوند و داده ها را عملکرد function ذخیره نمی کنند، این نوع از متغیر رفتاری کاملا بلاکچینی دارد. در ادامه این دوره مثال های بیشتری را با هم مرور خواهیم کرد.

اکنون می توانیم یک function برای بازخوانی داده ذخیره شده بسازیم. در این مرحله function با نام get() تعریف می کنیم:

۱۲۳function get() {
    // ...
}

حالا داده دریافت شده را از State متغیر با استفاده از return بازخوانی می کنیم:

۱۲۳function get() {
    return value;
}

اکنون باید شفافیت یا “visibility” این function را در وضعیت public قرار دهیم تا هر کسی در شبکه بلاکچین بتواند آن را صدا کند (نه فقط خود قرارداد هوشمند):

۱۲۳function get() public view {
    return value;
}

در انتها، ما نوع داده برگشتی را در حالت string برای function مشخص می کنیم:

۱۲۳function get() public view returns(string) {
    return value;
}

عالی! حالا باید روشی داشته باشیم که این داده را از قرارداد هوشمند بازخوانی کنیم. در ادامه شما می بینید که چطور این فرآیند کامپایل را انجام می دهیم، ولی قبل از آن باید راهی برای تعریف این داده خارج از قرارداد هوشمند بسازیم. به همین منظور function ای با نام set مانند شکل زیر تعریف می کنیم:

۱۲۳function set(string _value) public {
    // ...
}

به همین سادگی function ساختیم که argument با نام _value و از نوع string دارد. این function علاوه بر اینکه به طور عمومی دیده می شود، توسط تمامی افراد شبکه بلاکچین هم قابل بازخوانی است. حالا به طور عملی می توانیم value قرارداد هوشمند را به شکل زیر به روز رسانی کنیم:

۱۲۳function set(string _value) public {
    value = _value;
}

در اینجا به شکل خیلی ساده داده را از طریق _valueدریافت کرده و به وضعیت متغیر value نسبت دادیم. دقت کنید که _value توسط یک زیرخط (underline) به سادگی به یک متغیر local تبدیل شده است. این روش تبدیل کردن در زبان سالیدیتی بسیار رایج است.

اکنون می توانیم داده ای را به صورت پیش فرض برای وضعیت متغیر value تعریف کنیم. می توانیم این کار را درون constructor function خود قرارداد هوشمند به شکل زیر انجام دهیم:

۱۲۳constructor() public {
    value = "myValue"
}

در ابتدا باید constructor function با عنوان constructor ایجاد کنیم. این function فقط یک بار اجرا شده و دقیقا زمانی که قرارداد هوشمند پیاده سازی می شود. علاوه بر این همیشه باید شفافیت public را داشته باشد.

در این مرحله کد ما کامل شده است. با کامپایل کردن و deploy کردن این قرارداد هوشمند آن را تست می کنیم. اول از همه ما نسخه compiler را تعریف می کنیم که در سمت راست browser قرار دارد. به طور مثال نسخه ۰٫۴٫۲۵ را برای کامپایل این کد انتخاب کنید.

اکنون، محیط مورد نظر را انتخاب می کنیم. به شخصه JavaScript virtual machine را انتخاب میکنم، که به من امکان یک محیط شبیه سازی شده درون browser را می دهد.

اکنون می توانیم به سادگی و با یک کلیک کد را deploy کنیم:

عالی! شما اولین قرارداد هوشمند خود را پیاده کردید. با بازخوانی function های زیر شما می توانید با مطابق با فرم هایی که تولید می شود با قرارداد هوشمند تعامل داشته باشید.

در ابتدا، داده را بازخوانی کنیم. با کلیک گردن روی عملگر get() این اتفاق رخ می دهد. شما باید داده پیش فرض"myValue"که در constructor تعریف شده بود را ببینید.

اکنون می توانیم عملگر set()را با داده جدید آپدیت کنیم. داده جدیدی را در فیلد فرم وارد کنید و حتما آن را با quotation وارد کنید مانند: "New Value"

اکنون کد را اجرا کنید و داده جدید را بخوانید، باید به "New Value"تغییر کرده باشد.


ممکن است که به پنجره تراکنش که زیر text editor وجود دارد هم دقت کرده باشید. این لیست کاملی از تمامی تراکنش هایی است که در این بلاکچین مجازی Virtual blcokchain وجود دارد. به یاد داشته باشیم، شبکه بلاکچین اتریوم از اتصال رکوردهایی با عنوان بلاک ها که به هم زنجیر شده اند ایجاد شده که یک دفترکل توزیع شده عمومی را ایجاد کند. واحد پایه همه این بلاک ها تراکنش ها هستند.

فوق العاده، شما اولین قرارداد هوشمند خود را روی شبکه اتریوم با استفاده از زبان سالیدیتی نوشتید! در قسمت بعدی شما می بینید که از این کد چگونه استفاده کنیم و درباره این زبان بیشتر یاد می گیرید.

نوع و ساختار داده ها

قبل از اینکه شروع کنیم، نسخه سالیدیتی را در کد قرارداد هوشمند به روز رسانی کنید تا بتوانیم از امکانات آن استفاده کنیم. البته الان که این مطلب در حال نگارش است، نسخه ۰٫۶٫۰ برای سالیدیت موجود است ولی ما با ۰٫۵٫۱ کار می کنیم. لذا اولین خط را به شکل زیر تغییر دهید.

۱pragma solidity ^0.5.1;

این کار باعث توسعه همزمان قدرت برنامه نویسی با توسعه سالیدیتی خواهد شد.

اکنون، برای جلوگیری از برخی هشدارها در نسخه جدید سالدیتی، function مربوط به get() را به شکل زیر تغییر می دهیم:

۱۲۳function get() public view returns(string memory) { 
    return value;
}

همین تغییرات را برای function مربوط به set() هم انجام می دهیم:

۱۲۳function set(string memory _value) public {
    value = _value;
}

فوق العاده، هم کانون کد ما منطبق با تغییرات و به روز است است. در این مرحله در خصوص اصول پایه و انواع داده ها و ساختارهای آنها بررسی کوتاهی داریم. این موارد به شما کمک می کند که استفاده بهتری در هنگام پیاده سازی کد قرارداد هوشمند اتریوم خود داشته باشید.

در ابتدا، با state variable شروع می کنیم، سالیدتی امکانات خیلی خوبی برای این نوع از متغیر ارائه داده است. در ابتدا ما value را به state variable اختصاص می دهیم و از عملگر get() برای داده مقدار به آن استفاده می کنیم. سالیدیتی یک روش خیلی ساده برای این کار تعریف کرده که در زیر می بینید:

۱string public value;

این روش وضعیت متغیر را به صورت دسترسی public تعریف می کند و این اجازه را می دهد که از خارج از قرارداد هوشمند هم بتوان آن را به صورت دسترسی read بازخوانی کرد. در عمل سالیدیتی عملگر value() را خیلی سریع صدا کرده و دیگر نیازی به استفاده از get() نیست. برای همین خیلی راحت می توان state variable به شکل زیر تعریف کرد:

۱string public value = "myValue"

عملا ما دیگر نیازی به استفاده از عملگر constructor هم نداریم، که باعث کاهش زمان و حجم کد نوشته شده خواهد شد. باز هم می توانیم با تعریف کردن متغیر به شکل ثابت از تغییرهای بعدی آن جلوگیری کنیم، مثل این حالت:

۱string public constant value = "myValue"

اکنون، باید عملگر set()را حذف کنیم چرا که سالیدیتی به شما اجازه نمی دهد که در حالت constant روی آن تغییری ایجاد شود.

آنچه در بالا دیدید مروری بر خلاصه سازی بود که سالیدیتی ایجاد کرده و کار را ساده کرده است. اکنون می توان state variable ها را برای انواع دیگری از داده ها بررسی کنیم. همانطور که در حالت string دیدیم، ما می توانیم میزان عمومی یا visibility را به نام متغییر تخصیص دهیم. برای همین ما با ساختن یک متغیر boolean به شکل زیر شروع می کنیم:

۱bool public myBool = true;

این متغییر می تواند true یا false باشد.

اکنون یک متغیر عددی integer به شکل زیر می سازیم:

۱int public myInt = 1;

متغیر های عددی می توانند مثبت یا منفی باشند. اگر می خواهید اعداد حتما مثبت باشند، از روش زیر استفاده کنید:

۱uint public myUint = 1;

حتی ما می توانیم تعداد خاصی از بیت ها را برای اعداد در نظر بگیریم. در مثال بالا به صورت پیش فرض ۲۵۶ بیت در نظر گرفته شده که به شکل زیر باز شده است:

۱uint256 public myUint256 = 9999;

شما می توانید به صورت ۸ بیت هم آن را محدود کنید، مثل این:

۱uint8 public myUint8 = 8;

Enums

اکنون، بررسی کوتاهی روی ساختار داده سالیدیتی داشته باشیم. در ابتدا به ساختار داده Enum نگاه کنید، این ساختار داده روشی برای نگهداری لیست های تجمیع شده یا enumerated lists است. یک enum در قرارداد هوشمند به شکل زیر است:

۱enum State { Waiting, Ready, Active }

به طور مثال، این موضوع می تواند وضعیت active را در قرارداد هوشمند به شکل گزینه های Waiting, Ready, and Activeنشان دهد. ما می توانیم وضعیت فعلی قرارداد هوشمند را از طریق زیر چک کنیم:

۱State public state;

اکنون، می توانیم وضعیت پیش فرض در constructor را به شکل زیر تعریف کنیم:

۱۲۳constructor() public {
    state = State.Waiting;
}

یا اینکه به حالت active تغییر دهیم:

۱۲۳function activate() public {
    state = State.Active;
}

و در انتها، می توانیم لیست enum را چک کرده و ببینیم که آیا وضعیت قرارداد به صورت فعال است یا خیر؟

۱۲۳function isActive() public view returns(bool) {
    return state == State.Active;
}

در این مرحله، قرارداد هوشمند ما باید به شکل زیر باشد:

۱۲۳۴۵۶۷۸۹۱۰۱۱۱۲۱۳۱۴۱۵۱۶۱۷۱۸pragma solidity 0.5.1;

contract MyContract {
    enum State { Waiting, Ready, Active }
    State public state;

    constructor() public {
        state = State.Waiting;
    }

    function activate() public {
        state = State.Active;
    }

    function isActive() public view returns(bool) {
        return state == State.Active;
    }
}

این یک مثال از روشی استفاده از enums بود که بررسی وضعیت را درون قرارداد هوشمند انجام می دهد.

در آینده در خصوص استفاده از این عملگر برای قراردادهای هوشمند برگزاری عرضه توکن اولیه یا ICO ها و وضعیت open یا closed آن بیشتر توضیح خواهم داد.

Structs

سالیدیتی به شما اجازه می دهد که ساختار داده خاص خودتان را به روش Structs بسازید و داشته باشید. به طور کلی شما هر نوع داده ای که بخواهید می توانید مدل کرده و با خاصیت های دلخواه و ترکیبی از انواع داده داشته باشید. یک نگاهی به این ساختار داشته باشیم و از مثال struct people استفاده می کنیم:

۱۲۳۴struct Person {
    string _firstName;
    string _lastName;
}

خوب چه کاری کردیم؟ ما “فردی” را مدل کردیم که _firstNameو _lastNameدارد. دقت کنید که ما قادریم هر نوع داده ای که دوست داریم را وارد کنیم. ما از strings برای هر دو attribute استفاده کردیم. در عین حال می توانیم تا ۱۷ ویژگی متفاوت را در اینجا برای هر نوع داده ای داشته باشیم. فعلا سعی کنیم همین طور ساده حفظ کرده و با همین مدل دو attribute برای فرد استفاده کنیم.

آرایه ها – Arrays

اکنون لازم است که محلی برای ذخیره سازی در این ساختار فرد داشته باشیم، برای همین ما از آرایه استفاده می کنیم. مثال people را به صورت آرایه ببینید:

۱Person[] public people;

دقت کردید که ما یک آرایه به نام people را برای people تعریف کردیم. علاوه بر این دسترسی خارجی را به شکل public قرار می دهیم و به وضعیت متغیر people آن را وصل می کنیم. این روش باعث ایجاد عملگری شده که به افراد درون آرایه دسترسی لازم را می دهد. این را باید اشاره می کردم، که بازخوانی عملگر
people()خارج از قرارداد هوشمند کل اطلاعات آرایه را برنمی گرداند. در عوض عملگر people() می تواند argument مثل index را قبول کرده و از این طریق به افراد داخل آرایه بر اساس اجازه دسترسی می دهد. دقت شود که این یک آرایه بر پایه صفر است. برای مثال ما برای دسترسی به اولین نفر در آرایه به این شکل بازخوانی می کنیم:

۱people(0)

اکنون، میتوانیم روشی بسازیم که “فرد” جدیدی به این آرایه اضافه کنیم. عملگر addPerson()را به شکل زیر تعریف می کنیم:

۱۲۳۴function addPerson(string memory _firstName, string memory _lastName) public {
    people.push(Person(_firstName, _lastName));
    peopleCount += 1;
}

این عملگر بر اساس ساختار ویژگی های person درخواست های جدیدی را قبول می کند و بعد از آن یک instantiate جدید برای ایجاد کرده و با استفاده از روش عملگر push به آرایه people اضافه می کند. علاوه بر این وضعیت peopleCount را هم به عدد ۱ تغییر می دهد. می توانیم وضعیت متغیر را در قرارداد هوشمند به شکل زیر تعریف کنیم:

۱uint256 public peopleCount;

ما از این داده به عنوان cache شمارنده استفاده می کنیم. یادتون که گفتم شما نمی تونید کل آرایه peopleرا با استفاده از عملگر people()بازخوانی کنید؟ با این روش که بدانید چند نفر درون آرایه هستند، شاید بهتر بتوانیم از عملگر people() برای بازخوانی person استفاده کنیم.

خوب الان کد قرارداد هوشمند ما باید به شکل زیر باشد:

۱۲۳۴۵۶۷۸۹۱۰۱۱۱۲۱۳۱۴۱۵۱۶۱۷pragma solidity 0.5.1;

contract MyContract {
    Person[] public people;

    uint256 public peopleCount;

    struct Person {
        string _firstName;
        string _lastName;
    }

    function addPerson(string memory _firstName, string memory _lastName) public {
        people.push(Person(_firstName, _lastName));
        peopleCount += 1;
    }
}

Mappings

سالیدیتی یک ساختار داده دیگر هم دارد که عنوان mapping دارد، این ساختار داده به شما اجازه ذخیره سازی زوج کلیدها را می دهد. این ساختار داده شبیه یک آرایه اشتراکی و یا یک جدول هش Hash table در دیگر عملگرها رفتار می کند. ما از mapping به شکل زیر میتوانیم استفاده کنیم:

mapping(uint => Person) public people;

این روش mapping را در ساختار person ذخیره می کندو جایگرین آرایه people که در مثال قبل استفاده کردیم. این کلید یک integer امضا نشده است و داده آن به عنوان struct در person استفاده می شود. نوع استفاده از این کلید دقیقا مثل id در پایگاه داده استفاده می کنیم. ما می توانیم struct را در person به شکل زیر به روزسانی و آپدیت کنیم:

struct Person { uint _id; string _firstName; string _lastName; }

اکنون میتوانیم عملگر addPerson()را برای به روز رسانی و mapping در people به شکل زیر استفاده کنیم:

۱۲۳۴function addPerson(string memory _firstName, string memory _lastName) public {
    peopleCount += 1;
    people[peopleCount] = Person(peopleCount, _firstName, _lastName);
}

در این مرحله از cache شمارنده peopleCountبرای ساخت id برای person استفاده میکنیم. بعد این فرآیند یک struct جدید با id پیدا شده برای person ایجاد می کند و ویژگی های آن را هم دریافت و انتقال می دهد. سپس این را به mapping مربوط به people اضافه می کند. قرارداد هوشمند کامل شده به شکل زیر خواهد بود:

۱۲۳۴۵۶۷۸۹۱۰۱۱۱۲۱۳۱۴۱۵۱۶۱۷۱۸pragma solidity 0.5.1;

contract MyContract {
    uint256 peopleCount = 0;

    mapping(uint => Person) public people;

    struct Person {
        uint _id;
        string _firstName;
        string _lastName;
    }

    function addPerson(string memory _firstName, string memory _lastName) public {
        peopleCount += 1;
        people[peopleCount] = Person(peopleCount, _firstName, _lastName);
    }
}

عالی. یک مرور کلی روی مفاهیم اولیه انواع داده ها و ساختار داده ها در سالیدیتی داشتیم.

در بخش بعدی در مورد عملگرها، modifiers و زمان صحبت میکنیم. برای اطلاعات بیشتر در خصوص انواع ساختار داده ها خود کتابخانه سالیدیتی را بخوانید:

دیدگاهتان را بنویسید

logo-samandehi