٪85 تخفیف

دانلود کتاب آموزشی کار با Cosmos SDK و Polkadot Substrate جلد اول

دسته‌بندی: برچسب: تاریخ به روز رسانی: 28 مهر 1404 تعداد بازدید: 412 بازدید
ویژگی های محصول: پشتیبانی واتساپ

قیمت اصلی: ۲,۰۰۰,۰۰۰ تومان بود.قیمت فعلی: ۳۰۰,۰۰۰ تومان.

torobpay
هر قسط با ترب‌پی: ۷۵,۰۰۰ تومان
۴ قسط ماهانه. بدون سود، چک و ضامن.

این دوره به توسعه‌دهندگان کمک می‌کند تا با ایجاد بلاکچین‌های ماژولار و سفارشی با استفاده از Cosmos SDK و Polkadot Substrate آشنا شوند. این دو فریمورک محبوب، امکان توسعه بلاکچین‌های قابل تعامل و بهینه‌شده را فراهم می‌کنند.


بخش ۱: مقدمه‌ای بر Cosmos SDK و Polkadot Substrate

 

فصل 1. معرفی Cosmos SDK و Substrate

  • مفهوم بلاکچین‌های ماژولار و اهمیت آن‌ها در توسعه شبکه‌های سفارشی
  • مروری بر Cosmos SDK: هدف، ویژگی‌ها و معماری
  • مروری بر Polkadot Substrate: هدف، ویژگی‌ها و معماری
  • تفاوت رویکرد Cosmos SDK و Substrate در ساخت بلاکچین‌های سفارشی

فصل 2. بررسی معماری Cosmos SDK

  • معرفی Cosmos Hub و زنجیره‌های مستقل (Zones)
  • مفهوم Tendermint و نقش آن در Cosmos SDK
  • IBC (Inter-Blockchain Communication) و اهمیت آن در ارتباط بین زنجیره‌ها
  • معرفی ماژول‌های استاندارد Cosmos SDK (مانند Auth، Bank، Staking)

فصل 3. بررسی معماری Polkadot Substrate

  • معرفی Relay Chain و نقش آن در اکوسیستم Polkadot
  • مفهوم Parachains و نحوه تعامل آن‌ها
  • بررسی FRAME و نقش Pallets در Substrate
  • مقایسه Proof-of-Stake در Polkadot و Cosmos

فصل 4. مقایسه Cosmos SDK و Polkadot Substrate

  • نحوه مدیریت امنیت و اجماع در هر دو فریمورک
  • مقایسه مدل تعامل بین زنجیره‌ها: IBC در Cosmos و XCMP در Substrate
  • توسعه و گسترش‌پذیری در Cosmos SDK در مقابل Substrate
  • تفاوت‌های زبان‌های برنامه‌نویسی (Go در Cosmos SDK و Rust در Substrate)

فصل 5. بررسی پروژه‌های موفق پیاده‌سازی‌شده با Cosmos و Substrate

  • پروژه‌های مطرح مبتنی بر Cosmos SDK (مانند Binance Chain، Terra، Osmosis)
  • پروژه‌های موفق ساخته‌شده با Substrate (مانند Moonbeam، Acala، Phala)
  • بررسی موارد استفاده (Use Cases) برای انتخاب Cosmos SDK یا Substrate
  • چالش‌ها و فرصت‌های استفاده از این فریمورک‌ها در توسعه بلاکچین‌های سفارشی

بخش ۲: شروع کار با Cosmos SDK

 

فصل 1. نصب و راه‌اندازی محیط توسعه Cosmos SDK

  • پیش‌نیازهای نصب (Go، Node.js، Docker، Rust)
  • نصب Cosmos SDK از طریق GitHub
  • پیکربندی مسیرهای محیطی و متغیرهای موردنیاز
  • بررسی ابزار Starport و نصب آن برای توسعه سریع
  • تست صحت نصب با اجرای یک بلاکچین نمونه

فصل 2. معماری ماژولار در Cosmos SDK

  • معرفی مفهوم ماژولار در Cosmos SDK
  • بررسی ساختار کلی یک بلاکچین مبتنی بر Cosmos SDK
  • معرفی بخش‌های اصلی (BaseApp، Store، Keeper، Handler)
  • نحوه مدیریت ذخیره‌سازی و State در Cosmos SDK
  • نقش Validatorها و نحوه تأیید تراکنش‌ها

فصل 3. معرفی ابزارهای کلیدی در Cosmos SDK

  • معرفی Tendermint و نحوه عملکرد آن به‌عنوان مکانیزم اجماع
  • بررسی Starport و نحوه ایجاد سریع یک بلاکچین
  • معرفی IBC (Inter-Blockchain Communication) برای ارتباط بین زنجیره‌ای
  • کار با Cosmovisor برای مدیریت به‌روزرسانی‌های بلاکچین
  • استفاده از gRPC و REST API برای تعامل با بلاکچین

فصل 4. ایجاد اولین بلاکچین با Cosmos SDK

  • ایجاد یک پروژه جدید با Starport
  • بررسی ساختار دایرکتوری پروژه
  • تعریف اولین ماژول سفارشی در Cosmos SDK
  • کامپایل و اجرای بلاکچین محلی
  • ثبت اولین تراکنش و بررسی لاگ‌های سیستم

فصل 5. مدیریت کیف پول و کلیدهای رمزنگاری در Cosmos SDK

  • ایجاد کیف پول و مدیریت کلیدها با cosmosd keys
  • تولید و بازیابی کلیدهای خصوصی و عمومی
  • ارسال توکن‌های آزمایشی و بررسی وضعیت حساب‌ها
  • بررسی نحوه امضای تراکنش‌ها و امنیت کلیدهای خصوصی

فصل 6. مدیریت نودها و اجرای شبکه آزمایشی (Testnet)

  • راه‌اندازی یک Full Node و همگام‌سازی با شبکه
  • اجرای Validator Node و ثبت در شبکه
  • مدیریت فایل genesis.json و تنظیمات اولیه شبکه
  • بررسی لاگ‌های شبکه و دیباگ تراکنش‌ها

بخش ۳: طراحی و پیاده‌سازی ماژول‌های سفارشی در Cosmos SDK

 

فصل 1. مقدمه‌ای بر ماژول‌های سفارشی در Cosmos SDK

  • مفهوم ماژول در معماری ماژولار Cosmos SDK
  • نحوه تعامل ماژول‌ها با بلاکچین
  • معرفی ساختار کلی یک ماژول سفارشی

فصل 2. ایجاد یک ماژول جدید در Cosmos SDK

  • ایجاد ساختار اولیه ماژول
  • تعریف پیام‌ها (Messages) و انواع تراکنش
  • پیاده‌سازی منطق Handler برای پردازش تراکنش‌ها
  • رجیستر کردن ماژول در بلاکچین

فصل 3. مدیریت State در ماژول‌های سفارشی

  • مفهوم Store و Key-Value Storage در Cosmos SDK
  • استفاده از Keeper برای خواندن و نوشتن داده‌ها
  • بررسی MultiStore و نحوه تعامل ماژول‌ها با State

فصل 4. تعریف و مدیریت پیام‌ها و رویدادها

  • طراحی انواع پیام‌های سفارشی (Msg)
  • ثبت و اعتبارسنجی پیام‌ها
  • ایجاد و ارسال رویدادها (Events) در بلاکچین

فصل 5. مدیریت تراکنش‌ها و اجرای آنها در ماژول

  • نحوه پردازش تراکنش‌ها و ثبت تغییرات
  • پیاده‌سازی روش‌های اعتبارسنجی تراکنش‌ها
  • اجرای تراکنش‌های سفارشی و بررسی خروجی آن‌ها

فصل 6. ایجاد و مدیریت Queryها برای خواندن داده‌ها

  • پیاده‌سازی Endpoints برای خواندن اطلاعات از بلاکچین
  • تعریف Queryها برای دریافت اطلاعات از Store
  • تعامل با gRPC و REST API در Cosmos SDK

فصل 7. اتصال ماژول به IBC (Inter-Blockchain Communication)

  • معرفی پروتکل IBC و نحوه ارتباط بین بلاکچین‌ها
  • پیاده‌سازی قابلیت ارسال و دریافت پیام‌های IBC
  • بررسی کاربرد IBC در تعامل بین ماژول‌های مختلف

فصل 8. تست و دیباگ ماژول سفارشی

  • اجرای تست‌های واحد (Unit Tests) برای ماژول
  • استفاده از ابزارهای Cosmos SDK برای خطایابی
  • بررسی لاگ‌ها و دیباگ تراکنش‌ها

فصل 9. استقرار و استفاده از ماژول در بلاکچین سفارشی

  • اضافه کردن ماژول به بلاکچین سفارشی
  • راه‌اندازی نود برای اجرای ماژول
  • بررسی عملکرد ماژول در شبکه آزمایشی

فصل 10. بهینه‌سازی و ارتقای ماژول‌های سفارشی

  • بهینه‌سازی عملکرد و کاهش مصرف منابع
  • اعمال تغییرات و ارتقا بدون ایجاد هارد فورک
  • مدیریت نسخه‌بندی و مهاجرت ماژول‌ها

بخش ۴: آشنایی با Polkadot Substrate و نصب محیط توسعه

 

فصل 1. مقدمه‌ای بر Substrate و ویژگی‌های کلیدی آن

  • Substrate چیست و چه کاربردهایی دارد؟
  • تفاوت Substrate با Cosmos SDK و سایر فریمورک‌های بلاکچین
  • بررسی معماری و اجزای Substrate (Runtime، FRAME، Pallets، Off-chain Workers)
  • معرفی Substrate Node Template و عملکرد آن

فصل 2. نصب و راه‌اندازی محیط توسعه برای Substrate

  • پیش‌نیازهای سخت‌افزاری و نرم‌افزاری
  • نصب Rust و ابزارهای مرتبط
  • پیکربندی Rust برای بهینه‌سازی عملکرد (Rustup، Cargo، nightly toolchain)
  • دریافت و نصب Substrate Node Template از GitHub

فصل 3. ساختار و اجزای Node Template در Substrate

  • بررسی ساختار فایل‌ها و فولدرهای پروژه Substrate
  • آشنایی با فایل‌های اصلی:
    • Cargo.toml و مدیریت وابستگی‌ها
    • runtime/src/lib.rs و تعریف Palletها
    • node/src/chain_spec.rs و تنظیمات شبکه
  • نحوه کامپایل و اجرای Node Template

فصل 4. اجرای اولین بلاکچین با Substrate

  • راه‌اندازی یک نود محلی و بررسی لاگ‌ها
  • تعامل با بلاکچین از طریق Substrate UI
  • اجرای تراکنش‌های آزمایشی در شبکه
  • استفاده از subkey برای ایجاد کلیدهای جدید

فصل 5. مدیریت و تنظیمات نود در Substrate

  • راه‌اندازی Full Node و Archive Node
  • اتصال به شبکه‌های آزمایشی Substrate
  • تنظیمات Chain Spec برای سفارشی‌سازی بلاکچین
  • بررسی نحوه ایجاد یک Genesis Block

بخش ۵: توسعه ماژول‌های سفارشی در Substrate (Pallets)

 

فصل 1. مقدمه‌ای بر FRAME و Palletها در Substrate

  • تعریف FRAME و نقش آن در توسعه بلاکچین‌های ماژولار
  • ساختار Palletها و نحوه تعامل آن‌ها با Runtime
  • بررسی نقش Metadata در Substrate

فصل 2. ایجاد یک Pallet سفارشی در Substrate

  • ایجاد یک پروژه جدید با استفاده از Substrate Node Template
  • افزودن یک Pallet سفارشی به پروژه
  • ساختار فایل‌های یک Pallet و معرفی فایل‌های کلیدی

فصل 3. مدیریت State Storage در Palletها

  • معرفی Storage در Substrate و نحوه ذخیره داده‌ها
  • تعریف Storage Map و Storage Value در Pallet
  • بهینه‌سازی ذخیره‌سازی با استفاده از Storage Migration

فصل 4. تعریف و مدیریت Extrinsicها در Pallet سفارشی

  • معرفی Extrinsicها و نحوه ارسال تراکنش‌ها در Substrate
  • تعریف توابع قابل‌اجرا (Call Functions) در یک Pallet
  • مدیریت خطاها و وضعیت تراکنش‌ها در Pallet

فصل 5. رویدادها (Events) و خطاها (Errors) در Palletها

  • معرفی Events و نحوه تعریف آن‌ها در Pallet
  • ارسال و دریافت Eventها در شبکه
  • مدیریت خطاها و تعریف Error Handling سفارشی

فصل 6. مدیریت سطح دسترسی و امضاها در Palletها

  • کنترل دسترسی به توابع Pallet با استفاده از Origin
  • بررسی Signerها و تأیید هویت کاربران
  • مدیریت سطوح دسترسی کاربران و نقش‌های مختلف در Substrate

فصل 7. ایجاد و مدیریت Hooks در Runtime

  • معرفی Lifecycle Hooks در Substrate
  • استفاده از Hooks برای اجرای عملیات زمان‌بندی‌شده
  • پیاده‌سازی on_initialize و on_finalize در Pallet سفارشی

فصل 8. ادغام Palletهای مختلف و تعامل بین آنها

  • نحوه ارتباط بین چند Pallet در یک Runtime
  • استفاده از Dependency Injection برای ترکیب قابلیت‌های Palletها
  • بررسی سیستم‌های Cross-Pallet Messaging در Substrate

فصل 9. تست و دیباگ کردن Palletهای Substrate

  • راه‌اندازی محیط تست و نوشتن تست‌های واحد برای Pallet
  • استفاده از ابزار Substrate Test Runtime برای شبیه‌سازی شبکه
  • بررسی لاگ‌ها و دیباگ کردن اجرای Palletها

فصل 10. بهینه‌سازی عملکرد و استقرار Pallet سفارشی

  • بهینه‌سازی مصرف حافظه و پردازش در Pallet
  • استفاده از Benchmarking برای ارزیابی عملکرد Pallet
  • راه‌اندازی Pallet سفارشی در یک شبکه آزمایشی
[cdb_course_lessons title=”دانلود فایل PDF”][cdb_course_lesson icon=”fas fa-arrow-circle-down” badge=”attachments” private_lesson=”true” title=”دانلود جلد اول کتاب” download_lesson=”https://dl.faraznetwork.ir/book/bit/Cosmos-SDK-Polkadot-Substrate-djnwrtu7457912-1.pdf”][/cdb_course_lesson][/cdb_course_lessons]
[cdb_course_lessons title=”بخش ۱: مقدمه‌ای بر Cosmos SDK و Polkadot Substrate”][cdb_course_lesson title=”فصل 1. معرفی Cosmos SDK و Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مفهوم بلاکچین‌های ماژولار و اهمیت آن‌ها در توسعه شبکه‌های سفارشی” subtitle=”توضیحات کامل”]بلاکچین‌های ماژولار یکی از پیشرفت‌های جدید در دنیای بلاکچین‌ها هستند که به شدت در حال تغییر نحوه توسعه و ساخت شبکه‌های بلاکچینی سفارشی و مقیاس‌پذیر می‌باشند. در این بخش به تحلیل مفهوم بلاکچین‌های ماژولار، ساختار آن‌ها، نحوه عملکرد و اهمیتشان در توسعه شبکه‌های بلاکچینی سفارشی پرداخته خواهد شد.

بلاکچین ماژولار چیست؟

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

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

اجزای اصلی بلاکچین‌های ماژولار

  1. ماژول اجماع: این ماژول مسئول تأمین اجماع شبکه است. در بلاکچین‌های ماژولار، شما می‌توانید از مکانیزم‌های اجماع مختلف مانند PoW (Proof of Work)، PoS (Proof of Stake)، یا ترکیبی از هر دو استفاده کنید.
  2. ماژول اجرای قراردادهای هوشمند: این ماژول مسئول اجرای قراردادهای هوشمند است که به کاربران امکان ایجاد و اجرای برنامه‌های غیرمتمرکز را می‌دهد.
  3. ماژول ذخیره‌سازی: این ماژول وظیفه ذخیره‌سازی داده‌ها را بر عهده دارد و به بلاکچین امکان می‌دهد داده‌ها را به شکلی امن و مقیاس‌پذیر ذخیره کند.
  4. ماژول دسترسی به داده‌ها (Data Availability): این ماژول مسئول فراهم کردن داده‌ها برای سایر ماژول‌ها و شرکت‌کنندگان شبکه است و اطمینان می‌دهد که داده‌ها به‌طور دائم در دسترس هستند.

مزایای بلاکچین‌های ماژولار

  1. مقیاس‌پذیری: به دلیل تقسیم وظایف بین ماژول‌های مختلف، بلاکچین‌های ماژولار می‌توانند مقیاس‌پذیری بهتری را نسبت به بلاکچین‌های تک‌ماژولار ارائه دهند. هر ماژول می‌تواند به‌طور مستقل مقیاس‌پذیری خود را بهبود بخشد.
  2. سفارشی‌سازی: کاربران می‌توانند ماژول‌ها را با توجه به نیازهای خاص خود سفارشی‌سازی کنند. برای مثال، می‌توانند مکانیزم اجماع خود را بر اساس نیازهای امنیتی یا عملکرد شبکه تغییر دهند.
  3. استقلال ماژول‌ها: هر ماژول می‌تواند به‌طور مستقل توسعه یابد، ارتقا یابد و حتی جایگزین شود، بدون اینکه تاثیر منفی بر سایر بخش‌های شبکه بگذارد.
  4. استفاده بهینه از منابع: بلاکچین‌های ماژولار به کاربران این امکان را می‌دهند که تنها از آن بخش‌هایی از شبکه استفاده کنند که برای نیازهایشان ضروری است، که باعث استفاده بهینه از منابع و کاهش هزینه‌ها می‌شود.

بلاکچین‌های ماژولار و توسعه شبکه‌های سفارشی

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

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

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

برای پیاده‌سازی یک بلاکچین ماژولار، ابتدا باید انتخاب کنیم که کدام ماژول‌ها را برای شبکه خود استفاده می‌کنیم. سپس می‌توانیم تنظیمات مختلف هر ماژول را با توجه به نیازهای خاص خود پیکربندی کنیم. در اینجا نمونه‌ای از دستوراتی که برای تنظیم بلاکچین ماژولار و پیکربندی ماژول‌های مختلف به کار می‌روند، آورده شده است:

  1. تنظیمات ماژول اجماع: برای استفاده از مکانیزم اجماع PoS (Proof of Stake) می‌توانید از کد زیر استفاده کنید:
# ویرایش فایل تنظیمات اجماع
nano /path/to/blockchain/config/consensus.conf

# در این فایل، می‌توانید مکانیزم اجماع را تنظیم کنید
consensus_method=PoS
  1. تنظیمات ماژول قراردادهای هوشمند: برای فعال‌سازی ماژول قراردادهای هوشمند، باید کدهای زیر را در تنظیمات قراردادهای هوشمند وارد کنید:
# ویرایش تنظیمات ماژول قراردادهای هوشمند
nano /path/to/blockchain/config/smart_contracts.conf

# تنظیمات مربوط به قراردادهای هوشمند
smart_contracts_enabled=true
  1. تنظیمات ذخیره‌سازی داده‌ها: برای تنظیم ماژول ذخیره‌سازی داده‌ها به شکل مقیاس‌پذیر، از دستورات زیر استفاده می‌شود:
# ویرایش تنظیمات ذخیره‌سازی داده‌ها
nano /path/to/blockchain/config/storage.conf

# انتخاب روش ذخیره‌سازی مقیاس‌پذیر
storage_method=distributed

جمع بندی

بلاکچین‌های ماژولار با ارائه اجزای قابل تنظیم و مقیاس‌پذیر، امکان ساخت شبکه‌های بلاکچینی سفارشی را فراهم می‌آورند. این شبکه‌ها به کاربران این اجازه را می‌دهند که تنها بخش‌هایی از بلاکچین را که نیاز دارند استفاده کنند و در نتیجه از کارایی و مقیاس‌پذیری بالاتری برخوردار شوند. از طرفی دیگر، این نوع بلاکچین‌ها قابلیت تطبیق‌پذیری و ارتقای آسان دارند که به توسعه‌دهندگان این امکان را می‌دهد که شبکه‌های خود را متناسب با نیازهای خاصشان پیاده‌سازی کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مروری بر Cosmos SDK: هدف، ویژگی‌ها و معماری” subtitle=”توضیحات کامل”]Cosmos SDK یکی از چارچوب‌های پیشرفته برای توسعه بلاکچین‌های سفارشی است که هدف آن فراهم کردن یک ساختار مقیاس‌پذیر و قابل گسترش برای ایجاد بلاکچین‌های مختلف با کارکردهای خاص است. در این بخش، به تحلیل هدف، ویژگی‌ها و معماری Cosmos SDK پرداخته خواهد شد.

هدف Cosmos SDK

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

ویژگی‌های Cosmos SDK

  1. ماژولار بودن: یکی از ویژگی‌های برجسته Cosmos SDK، ماژولار بودن آن است. توسعه‌دهندگان می‌توانند تنها ماژول‌های مورد نیاز خود را انتخاب کنند و آن‌ها را در ساختار بلاکچین خود پیاده‌سازی نمایند. این ماژول‌ها شامل اجماع، توکن‌ها، قراردادهای هوشمند و بسیاری دیگر هستند.
  2. پشتیبانی از اجماع‌های مختلف: Cosmos SDK از اجماع‌های مختلف پشتیبانی می‌کند. برای مثال، از اجماع BFT (Byzantine Fault Tolerant) استفاده می‌کند که یکی از محبوب‌ترین مکانیزم‌های اجماع در بلاکچین‌های نسل جدید است.
  3. یکپارچگی با شبکه‌های دیگر (IBC): یکی از ویژگی‌های بسیار مهم Cosmos SDK، پشتیبانی از پروتکل ارتباطی بین بلاکچین‌ها (IBC) است. این پروتکل به بلاکچین‌ها این امکان را می‌دهد که با یکدیگر ارتباط برقرار کرده و تراکنش‌ها و داده‌ها را بین بلاکچین‌ها منتقل کنند.
  4. قابلیت ارتقاء و انعطاف‌پذیری: Cosmos SDK به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین خود را به راحتی ارتقا دهند. این چارچوب به طور مداوم به‌روز می‌شود و برای هر نوع پروژه‌ای قابل تنظیم است.
  5. امنیت بالا: Cosmos SDK از استانداردهای امنیتی بالایی برخوردار است و از ویژگی‌های امنیتی مانند اثبات ذخیره‌سازی داده‌ها و جلوگیری از حملات Byzantine استفاده می‌کند.
  6. سفارشی‌سازی بالا: با استفاده از Cosmos SDK، می‌توان بلاکچین‌هایی با ویژگی‌های کاملاً سفارشی ایجاد کرد. از تغییر در الگوریتم‌های اجماع گرفته تا طراحی ساختار توکن‌ها، هر چیزی قابل تغییر است.

معماری Cosmos SDK

معماری Cosmos SDK به‌صورت لایه‌ای طراحی شده است که هر لایه مسئولیت خاص خود را دارد. در زیر، اجزای اصلی معماری Cosmos SDK و عملکرد هر یک شرح داده شده است:

  1. لایه Application: این لایه مسئول پردازش تراکنش‌ها و اجرا کردن منطق کسب‌وکار است. این لایه شامل کدهای خاص برای بلاکچین شما می‌باشد و تمام تعاملات بلاکچین از این لایه عبور می‌کنند. کدهای مربوط به قراردادهای هوشمند، انتقال توکن‌ها و دیگر عملیات‌ها در این لایه قرار می‌گیرند.
  2. لایه Consensus: این لایه مسئول مدیریت اجماع و تضمین توافق در شبکه است. در Cosmos SDK، اجماع معمولاً از الگوریتم Tendermint BFT استفاده می‌کند که به‌طور ویژه برای بلاکچین‌هایی با امنیت بالا طراحی شده است. این لایه تضمین می‌کند که همه گره‌ها (Nodes) در شبکه به یک نسخه از تاریخچه بلاکچین متفق‌القول برسند.
  3. لایه Networking: لایه شبکه مسئول ارتباطات و هماهنگی میان گره‌ها در شبکه است. این لایه، از پروتکل‌های ارتباطی مانند TCP/IP برای ارسال و دریافت پیام‌ها و بلاک‌ها استفاده می‌کند.
  4. لایه Data Storage: این لایه وظیفه ذخیره‌سازی داده‌ها در شبکه بلاکچین را بر عهده دارد. Cosmos SDK از پایگاه داده‌های مختلفی مانند LevelDB برای ذخیره‌سازی داده‌ها استفاده می‌کند و به‌طور مؤثری داده‌ها را از نظر امنیتی و مقیاس‌پذیری مدیریت می‌کند.
  5. لایه ABCI (Application Blockchain Interface): این لایه رابط میان لایه‌های بالا و پایین است و ارتباط میان لایه Application و لایه Consensus را مدیریت می‌کند. ABCI استانداردی است که اجازه می‌دهد Cosmos SDK از هر مکانیزم اجماع دلخواهی استفاده کند.
  6. ماژول‌ها: هر بلاکچین ساخته‌شده با استفاده از Cosmos SDK می‌تواند ماژول‌های مختلفی را انتخاب و اضافه کند. این ماژول‌ها ممکن است شامل مواردی مانند مدیریت توکن‌ها، کیف پول، قابلیت‌های خاص قراردادهای هوشمند و حتی پروتکل‌های پیچیده‌تر باشند.

پیاده‌سازی یک بلاکچین با Cosmos SDK

برای پیاده‌سازی بلاکچینی با استفاده از Cosmos SDK، باید ابتدا کدهای مربوط به بلاکچین خود را نوشته و سپس ماژول‌ها و تنظیمات مختلف را انتخاب و پیکربندی کنید. در اینجا چند گام ابتدایی برای شروع پیاده‌سازی آورده شده است:

  1. نصب Cosmos SDK: ابتدا باید Cosmos SDK را نصب کنید. برای این کار از دستور زیر استفاده می‌شود:
# نصب Go (بستری برای Cosmos SDK)
sudo apt install golang-go

# دانلود و نصب Cosmos SDK
git clone https://github.com/cosmos/cosmos-sdk.git
cd cosmos-sdk
make
  1. ساخت پروژه جدید: برای ساخت پروژه جدید، از دستور زیر استفاده کنید:
# ساخت پروژه جدید با استفاده از Cosmos SDK
cosmos-sdk init myblockchain
  1. پیکربندی اجماع و ماژول‌ها: در فایل‌های پیکربندی پروژه، می‌توانید اجماع و ماژول‌های مورد نظر خود را تنظیم کنید. برای مثال، تنظیمات اجماع در فایل زیر قرار دارند:
# ویرایش تنظیمات اجماع در فایل config.toml
nano /path/to/myblockchain/config/config.toml

# تنظیم مکانیزم اجماع
consensus.method=PoS

جمع بندی

Cosmos SDK چارچوبی قدرتمند و مقیاس‌پذیر برای ساخت بلاکچین‌های سفارشی است که به توسعه‌دهندگان امکان می‌دهد بلاکچین‌های خود را با استفاده از ماژول‌های آماده و قابل سفارشی‌سازی بسازند. با ویژگی‌هایی مانند اجماع قابل انتخاب، پشتیبانی از پروتکل IBC برای ارتباط بلاکچین‌ها و امکان ارتقاء آسان، Cosmos SDK ابزاری مناسب برای ایجاد بلاکچین‌های مقیاس‌پذیر و ایمن است. معماری ماژولار Cosmos SDK به توسعه‌دهندگان این امکان را می‌دهد که تنها از بخش‌های مورد نیاز خود استفاده کنند و شبکه‌هایی با عملکرد بالا و امنیت قوی ایجاد نمایند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مروری بر Polkadot Substrate: هدف، ویژگی‌ها و معماری” subtitle=”توضیحات کامل”]Polkadot Substrate یکی از فریم‌ورک‌های پیشرفته برای ساخت بلاکچین‌های سفارشی و مقیاس‌پذیر است که هدف آن ایجاد یک شبکه بلاکچینی چند زنجیره‌ای است. این چارچوب به توسعه‌دهندگان اجازه می‌دهد که بلاکچین‌های سفارشی خود را با استفاده از ابزارهای قدرتمند و ماژول‌های قابل تنظیم بسازند. در این بخش، به تحلیل هدف، ویژگی‌ها و معماری Polkadot Substrate پرداخته خواهد شد.

هدف Polkadot Substrate

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

ویژگی‌های Polkadot Substrate

  1. ماژولار بودن: مانند Cosmos SDK، Polkadot Substrate نیز ماژولار است. این به معنای این است که توسعه‌دهندگان می‌توانند از ماژول‌های آماده استفاده کنند یا ماژول‌های جدیدی را برای رفع نیازهای خاص پروژه‌های خود بسازند. این ماژول‌ها شامل اجماع، امنیت، توکن‌ها و بسیاری دیگر هستند.
  2. پشتیبانی از اجماع‌های مختلف: یکی از ویژگی‌های برجسته Substrate، پشتیبانی از مکانیزم‌های اجماع مختلف است. در واقع، Substrate به توسعه‌دهندگان این امکان را می‌دهد که مکانیزم اجماع دلخواه خود را برای بلاکچین خود پیاده‌سازی کنند.
  3. ارتباط میان بلاکچین‌ها (Interoperability): Polkadot Substrate به دلیل اتصال به شبکه Polkadot، امکان برقراری ارتباط و تعامل میان بلاکچین‌های مختلف را فراهم می‌کند. این ویژگی به‌ویژه برای پروژه‌هایی که نیاز به انتقال داده و تراکنش بین بلاکچین‌ها دارند، بسیار حائز اهمیت است.
  4. پشتیبانی از ارتقاء بدون فورک (Forkless Upgrades): Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین خود را بدون نیاز به فورک کردن ارتقاء دهند. این ویژگی باعث می‌شود که بلاکچین‌ها بتوانند به‌صورت پیوسته و بدون وقفه به روز رسانی شوند.
  5. قابلیت ایجاد بلاکچین‌های سفارشی: Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی با ویژگی‌های خاص خود را بسازند. به‌عنوان مثال، می‌توانند اجماع، توکن‌ها، قراردادهای هوشمند و حتی الگوریتم‌های خاص خود را در بلاکچین خود پیاده‌سازی کنند.
  6. امنیت بالا: Substrate از مکانیزم‌های امنیتی پیشرفته‌ای برای محافظت از بلاکچین‌ها استفاده می‌کند. از جمله این مکانیزم‌ها می‌توان به اثبات ذخیره‌سازی داده‌ها و مکانیزم‌های جلوگیری از حملات Byzantine اشاره کرد.

معماری Polkadot Substrate

معماری Polkadot Substrate نیز به‌صورت لایه‌ای طراحی شده است که هر لایه مسئولیت خاص خود را دارد. در زیر، اجزای اصلی معماری Polkadot Substrate و عملکرد هر یک شرح داده شده است:

  1. لایه Runtime: این لایه شامل کدهای اجرایی بلاکچین است و مسئول اجرای تراکنش‌ها و منطق کسب‌وکار می‌باشد. توسعه‌دهندگان می‌توانند کدهای مختلفی را برای بلاکچین خود پیاده‌سازی کنند و در این لایه قرار دهند.
  2. لایه Consensus: این لایه مسئول مدیریت اجماع و توافق بر روی وضعیت شبکه است. Polkadot Substrate از مکانیزم اجماع Nominated Proof of Stake (NPoS) استفاده می‌کند که به‌طور ویژه برای بلاکچین‌های چند زنجیره‌ای طراحی شده است.
  3. لایه Network: لایه شبکه مسئول ارتباطات و هماهنگی میان گره‌ها در شبکه است. این لایه از پروتکل‌های ارتباطی برای ارسال و دریافت پیام‌ها، تراکنش‌ها و بلاک‌ها استفاده می‌کند.
  4. لایه Data Storage: این لایه برای ذخیره‌سازی داده‌ها و وضعیت شبکه طراحی شده است. Substrate از پایگاه داده‌های مختلفی برای ذخیره‌سازی داده‌ها استفاده می‌کند و به‌طور مؤثری مقیاس‌پذیری و امنیت را مدیریت می‌کند.
  5. لایه Pallet: این لایه شامل ماژول‌های مختلف است که می‌توانند به بلاکچین افزوده شوند. برای مثال، می‌توان ماژول‌هایی برای مدیریت توکن‌ها، ایجاد قراردادهای هوشمند، یا حتی اجماع خاص خود ایجاد کرد. Palletها به‌صورت آماده و سفارشی در اختیار توسعه‌دهندگان قرار می‌گیرند.
  6. لایه Transaction Queue: این لایه مسئول مدیریت صف تراکنش‌ها است. تمامی تراکنش‌هایی که از طریق شبکه ارسال می‌شوند، ابتدا وارد این صف شده و سپس پردازش می‌شوند.

پیاده‌سازی بلاکچین با Polkadot Substrate

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

  1. نصب Polkadot Substrate: برای نصب Substrate و شروع به کار، باید ابتدا Rust (زبان برنامه‌نویسی) را نصب کرده و سپس Substrate را دانلود کنید:
# نصب Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# دانلود و نصب Polkadot Substrate
git clone https://github.com/paritytech/substrate.git
cd substrate
cargo build --release
  1. ساخت پروژه جدید: پس از نصب، می‌توانید پروژه جدید خود را با استفاده از دستور زیر ایجاد کنید:
# ساخت پروژه جدید
cargo new --bin myblockchain
cd myblockchain
  1. پیکربندی اجماع و ماژول‌ها: پس از ایجاد پروژه، می‌توانید اجماع و ماژول‌های مختلف را پیکربندی کرده و بلاکچین خود را آماده کنید. برای این کار باید فایل‌های پیکربندی را ویرایش کنید.
# ویرایش تنظیمات اجماع در فایل config.toml
nano /path/to/myblockchain/config/config.toml

# تنظیم مکانیزم اجماع
consensus.method=NPoS

جمع بندی

Polkadot Substrate یکی از فریم‌ورک‌های پیشرفته برای ساخت بلاکچین‌های سفارشی و مقیاس‌پذیر است که به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خود را با ویژگی‌های خاص و مقیاس‌پذیر بسازند. این چارچوب به‌ویژه برای پروژه‌هایی که نیاز به ارتباط میان بلاکچین‌ها دارند، مناسب است و با پشتیبانی از مکانیزم‌های اجماع مختلف و توانایی ارتقاء بدون فورک، به‌طور مؤثر در ایجاد بلاکچین‌های ایمن، مقیاس‌پذیر و انعطاف‌پذیر کمک می‌کند. معماری لایه‌ای و ماژولار Polkadot Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خود را به‌صورت سفارشی و با کارایی بالا پیاده‌سازی کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تفاوت رویکرد Cosmos SDK و Substrate در ساخت بلاکچین‌های سفارشی” subtitle=”توضیحات کامل”]Cosmos SDK و Polkadot Substrate هر دو فریم‌ورک‌های قدرتمند برای ساخت بلاکچین‌های سفارشی و مقیاس‌پذیر هستند. این دو ابزار دارای ویژگی‌های خاص خود هستند که آن‌ها را از یکدیگر متمایز می‌کند. در این بخش، به بررسی تفاوت‌های کلیدی بین Cosmos SDK و Substrate پرداخته خواهد شد.

1. معماری و ماژولار بودن

  • Cosmos SDK:
    Cosmos SDK یک فریم‌ورک ماژولار است که به توسعه‌دهندگان این امکان را می‌دهد تا بلاکچین‌های سفارشی خود را با استفاده از ماژول‌های آماده بسازند. این ماژول‌ها می‌توانند شامل اجماع، توکن‌ها، مدیریت تراکنش‌ها و حتی ویژگی‌های خاص مانند حاکمیت باشند. یکی از ویژگی‌های برجسته Cosmos SDK، استفاده از مدل “Hub-and-Spoke” (هاب و پره) است که در آن بلاکچین‌های مختلف به یک هاب مرکزی متصل می‌شوند.
  • Polkadot Substrate:
    Substrate نیز ماژولار است، اما برخلاف Cosmos SDK که از مدل Hub-and-Spoke پیروی می‌کند، Substrate به‌طور مستقیم به شبکه Polkadot متصل می‌شود و اجازه می‌دهد بلاکچین‌ها با استفاده از مکانیزم اجماع مشترک با هم ارتباط برقرار کنند. این چارچوب از اجزای مختلفی مانند لایه‌های مختلف برای اجماع، ذخیره‌سازی داده‌ها و اجرای تراکنش‌ها استفاده می‌کند و به توسعه‌دهندگان انعطاف بیشتری می‌دهد تا بلاکچین‌های کاملاً سفارشی بسازند.

2. مکانیزم اجماع

  • Cosmos SDK:
    Cosmos SDK از پروتکل اجماع Tendermint استفاده می‌کند که یک سیستم اجماع Byzantine Fault Tolerant (BFT) است. Tendermint یک مکانیزم اجماع Proof-of-Stake (PoS) است که امنیت بالا و سرعت تراکنش‌های بالا را فراهم می‌آورد. این پروتکل به‌ویژه برای پروژه‌هایی که نیاز به توافق سریع بین گره‌ها دارند، مناسب است.
  • Polkadot Substrate:
    Substrate به‌طور پیش‌فرض از مکانیزم اجماع Nominated Proof of Stake (NPoS) استفاده می‌کند که برای بلاکچین‌های چند زنجیره‌ای طراحی شده است. در این مکانیزم، اعتبارسنج‌ها توسط نودها انتخاب می‌شوند و مسئول تولید بلوک‌ها و حفظ امنیت شبکه هستند. این روش در شبکه‌های Polkadot و parachainها (زنجیره‌های فرعی) به‌طور خاص استفاده می‌شود.

3. مقیاس‌پذیری و ارتباط بین بلاکچین‌ها

  • Cosmos SDK:
    یکی از ویژگی‌های برجسته Cosmos SDK، ارتباط میان بلاکچین‌ها است که به‌وسیله پروتکل IBC (Inter-Blockchain Communication) انجام می‌شود. با استفاده از IBC، بلاکچین‌های مختلف در شبکه Cosmos می‌توانند به‌طور امن و بی‌نیاز از واسطه با هم ارتباط برقرار کنند. این ارتباط به بلاکچین‌ها امکان می‌دهد که داده‌ها و تراکنش‌ها را بین خود منتقل کنند.
  • Polkadot Substrate:
    در Polkadot، ارتباط بین بلاکچین‌ها از طریق parachains (زنجیره‌های فرعی) انجام می‌شود. هر parachain می‌تواند یک بلاکچین خاص با ویژگی‌های خاص خود باشد که از طریق Relay Chain (زنجیره اصلی Polkadot) به یکدیگر متصل می‌شوند. این معماری به Polkadot اجازه می‌دهد که شبکه‌ای از بلاکچین‌های متنوع و مستقل ایجاد کند که به‌طور همزمان از یک مکانیزم اجماع مشترک بهره‌مند هستند.

4. قابلیت ارتقاء بلاکچین‌ها

  • Cosmos SDK:
    Cosmos SDK به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خود را ارتقاء دهند، اما در مواردی که نیاز به تغییرات عمده است، ممکن است نیاز به فورک کردن شبکه باشد. این کار ممکن است چالش‌هایی برای حفظ سازگاری شبکه و جلوگیری از شکاف‌های احتمالی ایجاد کند.
  • Polkadot Substrate:
    یکی از ویژگی‌های برجسته Polkadot Substrate، ارتقاء بدون فورک است. این بدین معناست که بلاکچین‌های ساخته شده با Substrate می‌توانند بدون نیاز به قطع شبکه، به‌طور پیوسته ارتقاء یابند. این ویژگی به‌ویژه برای پروژه‌هایی که نیاز به ارتقاء‌های مکرر دارند، بسیار مناسب است.

5. زبان برنامه‌نویسی و توسعه

  • Cosmos SDK:
    Cosmos SDK از زبان برنامه‌نویسی Go استفاده می‌کند که به دلیل سادگی و کارایی بالای خود، یکی از زبان‌های محبوب در بین توسعه‌دهندگان بلاکچین است. استفاده از Go به توسعه‌دهندگان این امکان را می‌دهد که سریع‌تر کد بزنند و به راحتی با سایر سیستم‌ها تعامل داشته باشند.
  • Polkadot Substrate:
    Substrate از زبان Rust برای توسعه بلاکچین‌ها استفاده می‌کند که به دلیل امنیت بالا و سرعت اجرای عالی‌اش شناخته می‌شود. Rust همچنین به توسعه‌دهندگان این امکان را می‌دهد که کدهای پیچیده‌تری را پیاده‌سازی کنند و از ویژگی‌های خاص آن مانند مدیریت حافظه بدون نیاز به گاربیج کالکتور استفاده کنند.

6. مستندات و پشتیبانی

  • Cosmos SDK:
    Cosmos SDK به‌واسطه جامعه فعال و مستندات گسترده خود، پشتیبانی خوبی برای توسعه‌دهندگان فراهم می‌کند. این مستندات شامل راهنماها، مثال‌ها و منابع آنلاین است که به توسعه‌دهندگان کمک می‌کند تا پروژه‌های خود را سریع‌تر راه‌اندازی کنند.
  • Polkadot Substrate:
    Polkadot Substrate نیز دارای مستندات بسیار خوبی است که شامل راهنماها، کتابخانه‌ها و مثال‌های متعدد است. جامعه Polkadot نیز بسیار فعال است و توسعه‌دهندگان می‌توانند از پشتیبانی آنلاین و انجمن‌های مختلف استفاده کنند.

جمع بندی

در نهایت، انتخاب بین Cosmos SDK و Polkadot Substrate بستگی به نیازهای پروژه و نوع شبکه‌ای دارد که قصد دارید ایجاد کنید. Cosmos SDK بیشتر برای ایجاد شبکه‌های بلاکچینی مستقل و ارتباط بین بلاکچین‌ها با استفاده از IBC مناسب است، در حالی که Polkadot Substrate برای ساخت بلاکچین‌های چند زنجیره‌ای و مقیاس‌پذیر با استفاده از parachains و مکانیزم اجماع NPoS مناسب‌تر است. هر دو فریم‌ورک ویژگی‌های خاص خود را دارند که می‌توانند برای پروژه‌های مختلف بلاکچین مناسب باشند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. بررسی معماری Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی Cosmos Hub و زنجیره‌های مستقل (Zones)” subtitle=”توضیحات کامل”]در اکوسیستم Cosmos، ساختار کلی شبکه شامل دو جزء اصلی است: Cosmos Hub و زنجیره‌های مستقل یا Zones. این دو جزء به‌طور کلی با همکاری یکدیگر، شبکه‌ای مقیاس‌پذیر، قابل‌گسترش و قابل‌انعطاف ایجاد می‌کنند که در آن بلاکچین‌ها می‌توانند به‌طور مستقل فعالیت کنند و در عین حال با یکدیگر ارتباط برقرار کنند. در این بخش، به معرفی هر یک از این اجزاء و نحوه تعامل آن‌ها پرداخته خواهد شد.

1. Cosmos Hub

Cosmos Hub اولین و مهم‌ترین بلاکچین در اکوسیستم Cosmos است که به‌عنوان هاب مرکزی برای شبکه عمل می‌کند. این بلاکچین در ابتدا برای مدیریت و هماهنگی بین سایر بلاکچین‌ها طراحی شده است. به عبارت دیگر، Cosmos Hub به‌عنوان نقطه اتصال برای سایر بلاکچین‌ها عمل می‌کند و این بلاکچین‌ها می‌توانند از طریق Cosmos Hub با یکدیگر ارتباط برقرار کنند.

  • مکانیزم اجماع: Cosmos Hub از پروتکل اجماع Tendermint استفاده می‌کند. این پروتکل اجماع Byzantine Fault Tolerant (BFT) است که برای عملکرد سریع و ایمن طراحی شده است.
  • توکن ATOM: Cosmos Hub از توکن بومی ATOM استفاده می‌کند که برای استیکینگ و امنیت شبکه کاربرد دارد. دارندگان توکن‌های ATOM می‌توانند در فرآیند اجماع شرکت کرده و از طریق استیکینگ، امنیت شبکه را حفظ کنند.
  • نقش Cosmos Hub: Cosmos Hub به‌عنوان هاب مرکزی، مسئول مدیریت ارتباطات میان بلاکچین‌ها و مدیریت امنیت عمومی است. این هاب به بلاکچین‌ها امکان می‌دهد تا از طریق پروتکل IBC (Inter-Blockchain Communication) با یکدیگر ارتباط برقرار کنند و داده‌ها و تراکنش‌ها را منتقل کنند.

2. زنجیره‌های مستقل (Zones)

زنجیره‌های مستقل یا Zones، بلاکچین‌های خاصی هستند که به‌طور مستقل از Cosmos Hub عمل می‌کنند، اما در عین حال می‌توانند با استفاده از پروتکل IBC با یکدیگر ارتباط برقرار کنند. این زنجیره‌ها معمولاً برای نیازهای خاص طراحی می‌شوند و می‌توانند ویژگی‌ها و قوانین خود را داشته باشند.

  • استقلال و انعطاف‌پذیری: هر Zone می‌تواند یک بلاکچین کاملاً مستقل باشد که ویژگی‌های خاص خود را داشته باشد. این به توسعه‌دهندگان امکان می‌دهد تا بلاکچین‌هایی با ویژگی‌های خاص و نیازهای سفارشی ایجاد کنند. به‌عنوان‌مثال، یک Zone ممکن است برای پردازش تراکنش‌های مالی طراحی شده باشد، در حالی که دیگری ممکن است برای مدیریت هویت دیجیتال یا اجرای قراردادهای هوشمند استفاده شود.
  • ارتباط از طریق IBC: Zones می‌توانند از پروتکل IBC برای ارسال داده‌ها و انجام تراکنش‌ها با دیگر Zones و Cosmos Hub استفاده کنند. این ارتباط بدون نیاز به واسطه‌های اضافی و به‌طور مستقیم بین بلاکچین‌ها انجام می‌شود که به مقیاس‌پذیری و کارایی شبکه کمک می‌کند.
  • استقلال از Cosmos Hub: در حالی که Cosmos Hub نقش مدیریت و هماهنگی را ایفا می‌کند، Zones به‌طور مستقل از Cosmos Hub عمل می‌کنند و می‌توانند تصمیم‌گیری‌های خود را انجام دهند. این امر به‌ویژه برای پروژه‌های خاص که نیاز به مقیاس‌پذیری، سرعت یا ویژگی‌های خاص دارند، بسیار مفید است.

3. ارتباط میان Cosmos Hub و Zones

یکی از ویژگی‌های کلیدی Cosmos این است که Cosmos Hub و Zones می‌توانند به‌طور فعال با یکدیگر ارتباط برقرار کنند. در اینجا نحوه ارتباط و تعامل این دو بخش توضیح داده می‌شود:

  • پروتکل IBC: با استفاده از پروتکل IBC، Zones می‌توانند داده‌ها و تراکنش‌ها را با Cosmos Hub و سایر Zones منتقل کنند. این پروتکل به‌طور استاندارد برای ارتباطات بین بلاکچین‌ها در اکوسیستم Cosmos طراحی شده است.
  • امنیت و مقیاس‌پذیری: در Cosmos، هر Zone می‌تواند اجماع و امنیت خاص خود را داشته باشد، در حالی که Cosmos Hub امنیت و هماهنگی میان بلاکچین‌ها را تضمین می‌کند. این معماری باعث می‌شود که شبکه Cosmos هم از نظر امنیت و هم از نظر مقیاس‌پذیری بسیار قوی باشد.
  • نظارت و حاکمیت: در حالی که Cosmos Hub مسئول مدیریت ارتباطات میان بلاکچین‌ها است، Zones می‌توانند قوانین و ویژگی‌های خاص خود را پیاده‌سازی کنند. این امکان برای توسعه‌دهندگان بلاکچین فراهم می‌آید که بر اساس نیازهای خاص پروژه خود، بلاکچین‌های مستقل و مقیاس‌پذیر ایجاد کنند.

4. مزایا و چالش‌ها

مزایا:

  • مقیاس‌پذیری: با ایجاد بلاکچین‌های مستقل (Zones)، شبکه Cosmos قادر است مقیاس‌پذیری بسیار بالاتری داشته باشد. هر بلاکچین می‌تواند به‌طور مستقل مقیاس‌پذیری خود را تنظیم کند.
  • انعطاف‌پذیری: Cosmos Hub و Zones به‌طور همزمان امنیت و انعطاف‌پذیری را در اختیار توسعه‌دهندگان قرار می‌دهند. توسعه‌دهندگان می‌توانند بلاکچین‌های سفارشی برای نیازهای خاص خود ایجاد کنند.
  • تعامل میان بلاکچین‌ها: استفاده از پروتکل IBC موجب می‌شود که بلاکچین‌ها بتوانند بدون هیچ‌گونه واسطه‌ای با یکدیگر ارتباط برقرار کنند و داده‌ها و تراکنش‌ها را به‌طور امن منتقل کنند.

چالش‌ها:

  • پیچیدگی در مدیریت: اگرچه Cosmos Hub و Zones به توسعه‌دهندگان آزادی عمل می‌دهند، اما مدیریت و هماهنگی بین بسیاری از بلاکچین‌های مستقل می‌تواند پیچیده باشد.
  • محدودیت‌های فنی IBC: استفاده از پروتکل IBC برای ارتباطات بین بلاکچین‌ها، ممکن است برخی محدودیت‌های فنی مانند تأخیر در تراکنش‌ها یا مسائل مربوط به امنیت را به‌دنبال داشته باشد.

جمع بندی

در نهایت، Cosmos Hub و Zones ساختارهای کلیدی اکوسیستم Cosmos هستند که به توسعه‌دهندگان امکان می‌دهند بلاکچین‌های سفارشی و مقیاس‌پذیر بسازند و در عین حال، این بلاکچین‌ها می‌توانند به‌طور امن با یکدیگر ارتباط برقرار کنند. Cosmos Hub به‌عنوان هاب مرکزی مسئول هماهنگی و امنیت شبکه است، در حالی که Zones به‌طور مستقل عمل می‌کنند و به توسعه‌دهندگان آزادی عمل می‌دهند تا بلاکچین‌هایی با ویژگی‌های خاص بسازند. این معماری باعث می‌شود که شبکه Cosmos هم از نظر مقیاس‌پذیری و هم از نظر انعطاف‌پذیری، یک راه‌حل ایده‌آل برای ایجاد بلاکچین‌های متنوع و پیچیده باشد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مفهوم Tendermint و نقش آن در Cosmos SDK” subtitle=”توضیحات کامل”]Tendermint یک موتور اجماع (consensus engine) است که برای استفاده در بلاکچین‌های با مقیاس‌پذیری بالا و نیاز به ایمنی طراحی شده است. این موتور اجماع یکی از اجزای کلیدی در Cosmos SDK است و به‌عنوان زیرساختی برای پیاده‌سازی بلاکچین‌ها در اکوسیستم Cosmos عمل می‌کند. Tendermint ترکیبی از بلاک‌چین‌ها و پروتکل‌های اجماع است که هدف آن فراهم‌سازی مقیاس‌پذیری، امنیت، و سرعت بالا برای شبکه‌های بلاکچینی است.

در این بخش، به بررسی مفهوم Tendermint و نقش حیاتی آن در Cosmos SDK پرداخته خواهد شد.

1. مفهوم Tendermint

Tendermint به‌طور کلی شامل دو بخش اصلی است:

  • Tendermint Core: این بخش مسئول اجماع، پردازش تراکنش‌ها، و هماهنگی شبکه است. وظیفه آن اجماع بین گره‌ها (nodes) و ترتیب‌دهی تراکنش‌ها برای تشکیل بلاک‌های جدید است.
  • BFT (Byzantine Fault Tolerance): Tendermint از پروتکل BFT برای اجماع استفاده می‌کند که می‌تواند در برابر شکست‌های بدخواهانه یا رفتارهای غیراخلاقی در شبکه مقاوم باشد. این ویژگی باعث می‌شود که سیستم در برابر حملات مختلف و گره‌های بدخواه مقاومت بالایی داشته باشد.

2. نقش Tendermint در Cosmos SDK

Tendermint به‌عنوان موتور اجماع در Cosmos SDK نقش بسیار مهمی دارد. این سیستم اجماع به بلاکچین‌ها این امکان را می‌دهد که بتوانند به‌طور سریع و ایمن تراکنش‌ها را تأیید و بلاک‌های جدید را ایجاد کنند. در واقع، یکی از دلایل موفقیت Cosmos SDK و اکوسیستم Cosmos، استفاده از Tendermint برای مدیریت اجماع است.

نقش Tendermint در Cosmos SDK به این صورت است:

  • اجماع سریع و امن: Tendermint اجماع را در زمان ثابت و با تاخیر کم به انجام می‌رساند. این امر به بلاکچین‌ها امکان می‌دهد که در یک مدت زمان کوتاه تراکنش‌ها را تأیید کنند و به‌طور مداوم بلاک‌های جدید ایجاد کنند.
  • افزایش مقیاس‌پذیری: Tendermint امکان مقیاس‌پذیری را با پشتیبانی از تعداد زیادی گره فراهم می‌کند. در این شبکه، گره‌های بیشتری می‌توانند به‌طور همزمان به پردازش تراکنش‌ها بپردازند و در نتیجه سرعت شبکه به میزان قابل‌توجهی افزایش یابد.
  • مدیریت تراکنش‌ها: در Cosmos SDK، همه تراکنش‌ها قبل از اضافه شدن به بلاک‌ها از طریق Tendermint تأیید می‌شوند. این فرایند باعث می‌شود که تراکنش‌ها به‌طور قابل اعتمادی تأیید شوند و هیچ‌گونه اشتباهی در ذخیره‌سازی یا ترتیب تراکنش‌ها وجود نداشته باشد.
  • مقاومت در برابر خطای بیزانسی: استفاده از پروتکل BFT باعث می‌شود که حتی در صورت وجود گره‌های خراب یا بدخواه در شبکه، روند اجماع و عملکرد شبکه به‌طور صحیح ادامه یابد. این ویژگی به‌ویژه برای بلاکچین‌های عمومی که به امنیت بالا نیاز دارند، بسیار حیاتی است.
  • ساختار ساده و کاربرپسند: یکی از ویژگی‌های مهم Tendermint این است که ساختار آن نسبتاً ساده است و این امر به توسعه‌دهندگان این امکان را می‌دهد که از آن به‌راحتی استفاده کنند. توسعه‌دهندگان می‌توانند بدون نیاز به پیچیدگی‌های زیاد، بلاکچین‌هایی با امنیت و مقیاس‌پذیری بالا ایجاد کنند.

3. ویژگی‌های مهم Tendermint در Cosmos SDK

در اینجا به ویژگی‌های کلیدی Tendermint در Cosmos SDK اشاره می‌شود:

  • زمان بلاک ثابت (Fixed Block Time): در Tendermint، زمان بلاک‌ها ثابت است (معمولاً حدود 1 ثانیه) که این ویژگی باعث می‌شود تراکنش‌ها سریعاً تأیید شوند و سرعت شبکه بهبود یابد.
  • مقاومت در برابر خطای بیزانسی (Byzantine Fault Tolerance): Tendermint قادر است در برابر از کار افتادن یک تعداد از گره‌ها یا رفتارهای نادرست آن‌ها به‌طور صحیح عمل کند. این ویژگی باعث می‌شود که حتی در شرایط بدخواهانه، شبکه همچنان امن و قابل‌اعتماد باشد.
  • زیرساخت عمومی و خصوصی: Tendermint می‌تواند برای ساخت بلاکچین‌های عمومی یا خصوصی استفاده شود. در بلاکچین‌های عمومی، همه شرکت‌کنندگان به‌طور آزادانه می‌توانند به شبکه بپیوندند، در حالی که در بلاکچین‌های خصوصی، دسترسی محدودتر است.
  • مدیریت گره‌ها و تأسیس شبکه‌های مقیاس‌پذیر: Tendermint به‌طور مؤثر می‌تواند تعداد زیادی گره را مدیریت کند و باعث می‌شود که شبکه‌ها مقیاس‌پذیرتر شوند. گره‌ها می‌توانند به‌راحتی به شبکه اضافه یا از آن حذف شوند بدون اینکه تأثیری بر عملکرد کلی شبکه داشته باشد.

4. نقش Tendermint در Cosmos SDK و توسعه بلاکچین‌های سفارشی

  • ایجاد بلاکچین‌های سفارشی: با استفاده از Cosmos SDK و Tendermint، توسعه‌دهندگان می‌توانند بلاکچین‌های سفارشی با ویژگی‌ها و پروتکل‌های خاص خود بسازند. این بلاکچین‌ها می‌توانند برای هر نوع کاربرد خاص مانند پرداخت، هویت دیجیتال، یا قراردادهای هوشمند طراحی شوند.
  • حاکمیت و اجماع: یکی از ویژگی‌های مهم Cosmos SDK این است که توسعه‌دهندگان می‌توانند حاکمیت و اجماع شبکه خود را به‌طور سفارشی تنظیم کنند. این کار با استفاده از Tendermint به‌راحتی قابل انجام است.
  • ارتباط بین بلاکچین‌ها: Tendermint در Cosmos SDK با استفاده از پروتکل IBC به بلاکچین‌های مختلف امکان می‌دهد که بدون نیاز به واسطه‌های اضافی با یکدیگر ارتباط برقرار کنند و داده‌ها و تراکنش‌ها را منتقل کنند.

جمع بندی

Tendermint یکی از اجزای کلیدی در Cosmos SDK است که به بلاکچین‌ها امکان می‌دهد تا اجماع را به‌طور سریع، امن و با مقیاس‌پذیری بالا انجام دهند. استفاده از پروتکل BFT باعث می‌شود که Tendermint مقاوم در برابر خطاهای بیزانسی باشد و حتی در شرایط بدخواهانه، عملکرد شبکه حفظ شود. این ویژگی‌ها به‌ویژه در بلاکچین‌های سفارشی ساخته‌شده با Cosmos SDK اهمیت زیادی دارند، زیرا امنیت، سرعت و مقیاس‌پذیری را به‌طور هم‌زمان تأمین می‌کنند. در نهایت، Tendermint بستری ایده‌آل برای توسعه‌دهندگان فراهم می‌کند تا بلاکچین‌هایی مقیاس‌پذیر و قابل‌اعتماد ایجاد کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”IBC (Inter-Blockchain Communication) و اهمیت آن در ارتباط بین زنجیره‌ها” subtitle=”توضیحات کامل”]IBC یا ارتباطات بین زنجیره‌ای (Inter-Blockchain Communication) یک پروتکل برای انتقال داده‌ها و تراکنش‌ها بین بلاکچین‌های مختلف است. این پروتکل به‌ویژه در اکوسیستم Cosmos و سایر شبکه‌های مبتنی بر بلاکچین‌های ماژولار اهمیت زیادی دارد. با استفاده از IBC، بلاکچین‌ها می‌توانند به‌صورت مؤثر و امن با یکدیگر ارتباط برقرار کنند، که به‌طور چشم‌گیری مقیاس‌پذیری و قابلیت تعامل بین شبکه‌های مختلف را بهبود می‌بخشد.

در این بخش، به مفهوم IBC و نقش آن در ارتباطات بین بلاکچین‌ها پرداخته خواهد شد.

1. مفهوم IBC

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

IBC از دو بخش اصلی تشکیل شده است:

  • میزبان‌های IBC: بلاکچین‌هایی که قادر به ارسال و دریافت پیام‌ها از بلاکچین‌های دیگر هستند. این بلاکچین‌ها باید از پروتکل IBC پشتیبانی کنند تا بتوانند ارتباط برقرار کنند.
  • کانال‌های IBC: برای انتقال داده‌ها بین بلاکچین‌ها از کانال‌ها استفاده می‌شود. این کانال‌ها باید بین بلاکچین‌ها برقرار شوند تا بتوانند اطلاعات را منتقل کنند.

2. نقش IBC در اکوسیستم Cosmos

Cosmos یکی از مهم‌ترین پلتفرم‌هایی است که از پروتکل IBC برای ارتباط بین بلاکچین‌های مختلف استفاده می‌کند. در این اکوسیستم، بلاکچین‌ها می‌توانند از طریق IBC به‌صورت امن و مؤثر با یکدیگر ارتباط برقرار کنند و داده‌ها و دارایی‌ها را به‌طور مستقیم منتقل کنند. ویژگی‌های اصلی IBC در Cosmos عبارتند از:

  • ارتباط امن: IBC از رمزنگاری پیشرفته برای اطمینان از امنیت داده‌ها و تراکنش‌های منتقل‌شده بین بلاکچین‌ها استفاده می‌کند. این پروتکل از تاییدیه‌ها (proofs) برای اطمینان از صحت داده‌های منتقل‌شده استفاده می‌کند.
  • قابلیت مقیاس‌پذیری: IBC به بلاکچین‌ها این امکان را می‌دهد که مقیاس‌پذیرتر شوند و به‌طور هم‌زمان تراکنش‌ها و داده‌ها را از بلاکچین‌های مختلف پردازش کنند.
  • سازگاری با بلاکچین‌های مختلف: با استفاده از IBC، بلاکچین‌ها می‌توانند بدون توجه به تفاوت‌های فنی، با یکدیگر ارتباط برقرار کنند. این ویژگی باعث می‌شود که Cosmos به یک اکوسیستم ارتباطی گسترده برای بلاکچین‌های مختلف تبدیل شود.

3. کاربردهای IBC

  • انتقال دارایی‌ها: یکی از کاربردهای اصلی IBC، انتقال دارایی‌ها بین بلاکچین‌ها است. به‌عنوان مثال، یک کاربر می‌تواند دارایی‌های خود را از یک بلاکچین به بلاکچین دیگر منتقل کند. این قابلیت به توسعه‌دهندگان و کاربران این امکان را می‌دهد که از مزایای مختلف بلاکچین‌های مختلف بهره‌برداری کنند.
  • پشتیبانی از قراردادهای هوشمند بین زنجیره‌ای: IBC به بلاکچین‌ها این امکان را می‌دهد که قراردادهای هوشمند بین زنجیره‌ای (cross-chain smart contracts) ایجاد کنند. این قابلیت باعث می‌شود که قراردادهای هوشمند بتوانند از منابع و داده‌های مختلف بلاکچین‌ها استفاده کنند.
  • ایجاد شبکه‌های چند زنجیره‌ای (Multichain Networks): IBC به‌طور مستقیم به بلاکچین‌ها این امکان را می‌دهد که شبکه‌های چند زنجیره‌ای ایجاد کنند. در این شبکه‌ها، بلاکچین‌ها می‌توانند به‌صورت مستقل عمل کنند، اما در عین حال با یکدیگر تعامل داشته باشند و داده‌ها را به اشتراک بگذارند.
  • تقویت مقیاس‌پذیری و عملکرد: با استفاده از IBC، بلاکچین‌ها می‌توانند مقیاس‌پذیرتر شوند و تراکنش‌ها و داده‌ها را در سطح جهانی به‌طور مؤثرتر پردازش کنند.

4. مزایای IBC

  • افزایش تعامل بین بلاکچین‌ها: IBC این امکان را فراهم می‌آورد که بلاکچین‌های مختلف بتوانند با یکدیگر تعامل داشته باشند. این ویژگی باعث می‌شود که بلاکچین‌ها قادر باشند از خدمات و ویژگی‌های سایر بلاکچین‌ها بهره‌برداری کنند.
  • تسهیل انتقال دارایی‌ها و داده‌ها: یکی از مزایای بزرگ IBC این است که کاربران می‌توانند دارایی‌های خود را از بلاکچین‌های مختلف منتقل کنند بدون اینکه نیازی به واسطه‌های شخص ثالث باشد.
  • امنیت بالا: IBC از پروتکل‌های رمزنگاری برای تضمین امنیت تراکنش‌ها و داده‌ها استفاده می‌کند. این ویژگی باعث می‌شود که IBC به‌عنوان یک پروتکل امن برای انتقال داده‌ها بین بلاکچین‌ها شناخته شود.
  • افزایش مقیاس‌پذیری: با انتقال داده‌ها و تراکنش‌ها بین بلاکچین‌ها، IBC باعث می‌شود که شبکه‌ها مقیاس‌پذیرتر و سریع‌تر شوند. بلاکچین‌ها می‌توانند منابع خود را به‌طور مؤثرتر مدیریت کنند و بدون کاهش عملکرد، مقیاس‌پذیری خود را افزایش دهند.

5. چالش‌های IBC

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

جمع بندی

پروتکل IBC (Inter-Blockchain Communication) به‌عنوان یکی از مهم‌ترین ابزارها برای تسهیل ارتباط بین بلاکچین‌ها در اکوسیستم‌های بلاکچینی مانند Cosmos شناخته می‌شود. این پروتکل به بلاکچین‌ها امکان می‌دهد که به‌طور امن و مؤثر داده‌ها و دارایی‌ها را منتقل کنند و از قابلیت‌های بلاکچین‌های مختلف بهره‌برداری کنند. با استفاده از IBC، مقیاس‌پذیری، امنیت و تعامل بین بلاکچین‌ها به‌طور چشم‌گیری بهبود می‌یابد و توسعه شبکه‌های چند زنجیره‌ای را ممکن می‌سازد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی ماژول‌های استاندارد Cosmos SDK (مانند Auth، Bank، Staking)” subtitle=”توضیحات کامل”]Cosmos SDK یک فریم‌ورک قدرتمند برای ساخت بلاکچین‌های سفارشی است که از ماژول‌های مختلفی برای ارائه ویژگی‌ها و خدمات مختلف به بلاکچین‌ها استفاده می‌کند. این ماژول‌ها به توسعه‌دهندگان این امکان را می‌دهند که بلاکچین‌های خود را به‌طور سریع و آسان ایجاد کنند و آن‌ها را با ویژگی‌های مختلفی مانند تأسیس حساب‌های کاربری، انجام تراکنش‌های مالی و مدیریت استیکینگ تجهیز کنند. در این بخش، به معرفی برخی از مهم‌ترین ماژول‌های استاندارد Cosmos SDK، مانند Auth، Bank، و Staking پرداخته خواهد شد.

1. ماژول Auth

ماژول Auth در Cosmos SDK مسئول مدیریت حساب‌ها و احراز هویت تراکنش‌ها است. این ماژول به‌طور خاص وظیفه ذخیره‌سازی اطلاعات مربوط به حساب‌های کاربران، بررسی مجوزهای لازم برای تراکنش‌ها و مدیریت کلیدهای خصوصی و عمومی را بر عهده دارد. ماژول Auth این امکان را می‌دهد که بلاکچین‌ها امنیت و دسترسی محدود به منابع خود را فراهم کنند.

ویژگی‌ها و عملکردهای اصلی ماژول Auth:

  • مدیریت حساب‌ها: این ماژول مسئول نگهداری اطلاعات کاربران و موجودی‌های آن‌ها است. همچنین وضعیت فعلی حساب‌ها را ذخیره می‌کند.
  • احراز هویت تراکنش‌ها: هنگام ارسال تراکنش‌ها به بلاکچین، ماژول Auth صحت تراکنش را بررسی می‌کند و مطمئن می‌شود که تنها کاربران مجاز قادر به انجام آن‌ها هستند.
  • حفظ امنیت: ماژول Auth از کلیدهای عمومی و خصوصی برای امنیت تراکنش‌ها استفاده می‌کند و از امضای دیجیتال برای تأیید اصالت تراکنش‌ها بهره می‌برد.

مسیر فایل مربوطه: این ماژول معمولاً در فایل‌هایی مانند x/auth/ در ساختار پروژه Cosmos SDK قرار دارد. برای مثال، ممکن است فایل‌های مربوط به این ماژول در مسیر زیر قرار گیرند:

/x/auth/module.go

2. ماژول Bank

ماژول Bank یکی دیگر از ماژول‌های اساسی در Cosmos SDK است که مسئول مدیریت انتقال ارزها بین حساب‌ها و ذخیره‌سازی موجودی‌ها است. این ماژول برای انجام تراکنش‌های مالی، مانند ارسال و دریافت توکن‌ها، به‌کار می‌رود و عملکردهای متعددی را برای مدیریت دارایی‌های دیجیتال فراهم می‌آورد.

ویژگی‌ها و عملکردهای اصلی ماژول Bank:

  • انتقال ارزها: این ماژول برای انجام تراکنش‌های بین حساب‌ها استفاده می‌شود و به‌طور معمول برای انتقال توکن‌ها از یک حساب به حساب دیگر طراحی شده است.
  • مدیریت موجودی‌ها: ماژول Bank مسئول ذخیره و مدیریت موجودی‌های کاربران است. همچنین این ماژول اطلاعات مربوط به انتقال ارز را در بلاکچین ثبت می‌کند.
  • پشتیبانی از ارزهای مختلف: این ماژول می‌تواند از انواع مختلف توکن‌ها پشتیبانی کند و به‌طور معمول از ارزهای بومی شبکه، مانند ATOM در شبکه Cosmos، استفاده می‌شود.

مسیر فایل مربوطه: این ماژول معمولاً در مسیر x/bank/ قرار دارد. برای مثال، فایل‌های مربوط به این ماژول می‌توانند در مسیر زیر قرار گیرند:

/x/bank/module.go

3. ماژول Staking

ماژول Staking مسئول مدیریت فرآیند استیکینگ و مکانیسم اجماع در بلاکچین‌های Cosmos است. این ماژول به کاربران اجازه می‌دهد تا توکن‌های خود را برای دریافت پاداش و شرکت در فرآیند اجماع به اشتراک بگذارند. همچنین، ماژول Staking شامل توابعی برای مدیریت اعتبارسنجی‌ها (validators) و فرآیندهای مربوط به آن‌ها است.

ویژگی‌ها و عملکردهای اصلی ماژول Staking:

  • مدیریت اعتبارسنجی‌ها: ماژول Staking مسئول اضافه کردن و حذف اعتبارسنجی‌ها از شبکه است. اعتبارسنجی‌ها در شبکه Cosmos مسئول تأسیس بلوک‌ها و تأیید تراکنش‌ها هستند.
  • استیکینگ و Unstaking: کاربران می‌توانند توکن‌های خود را به اعتبارسنجی‌ها استیک کنند تا در فرآیند اجماع مشارکت داشته باشند. این ماژول همچنین به کاربران این امکان را می‌دهد که توکن‌های استیک‌شده خود را بازپس بگیرند (unstake).
  • پاداش استیکینگ: کاربران پاداش‌هایی را برای استیکینگ توکن‌ها دریافت می‌کنند. ماژول Staking این پاداش‌ها را محاسبه و توزیع می‌کند.

مسیر فایل مربوطه: ماژول Staking معمولاً در مسیر x/staking/ قرار دارد. برای مثال، فایل‌های مربوط به این ماژول می‌توانند در مسیر زیر قرار گیرند:

/x/staking/module.go

جمع بندی

ماژول‌های استاندارد Cosmos SDK مانند Auth، Bank و Staking اجزای اساسی هستند که به توسعه‌دهندگان این امکان را می‌دهند تا بلاکچین‌های سفارشی و مقیاس‌پذیر ایجاد کنند. ماژول Auth برای مدیریت حساب‌ها و امنیت تراکنش‌ها، ماژول Bank برای انجام تراکنش‌های مالی و مدیریت دارایی‌ها و ماژول Staking برای مدیریت فرآیندهای استیکینگ و اجماع طراحی شده است. با استفاده از این ماژول‌ها، توسعه‌دهندگان می‌توانند بلاکچین‌های خود را با ویژگی‌های پیشرفته تجهیز کنند و شبکه‌هایی امن، مقیاس‌پذیر و کارآمد بسازند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. بررسی معماری Polkadot Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی Relay Chain و نقش آن در اکوسیستم Polkadot” subtitle=”توضیحات کامل”]Polkadot یک شبکه چند زنجیره‌ای است که هدف آن اتصال بلاکچین‌های مختلف به یکدیگر و فراهم کردن تبادل داده و ارز بین آن‌ها است. در این اکوسیستم، Relay Chain نقش محوری را ایفا می‌کند. Relay Chain قلب شبکه Polkadot است که بلاکچین‌های مختلف را به هم متصل کرده و از تعاملات آن‌ها پشتیبانی می‌کند. این بخش از شبکه به‌عنوان نقطه مرکزی برای هماهنگ‌سازی و تبادل داده‌ها در سراسر بلاکچین‌های متصل به آن عمل می‌کند.

1. نقش Relay Chain در اکوسیستم Polkadot

Relay Chain در Polkadot مسئول هماهنگی و مدیریت کل اکوسیستم است. این بلاکچین مرکزی، تراکنش‌ها و ارتباطات بین زنجیره‌های مختلف را هماهنگ می‌کند و از یکپارچگی و امنیت شبکه اطمینان حاصل می‌کند. در واقع، Relay Chain به‌عنوان هسته‌ای است که از تمام زنجیره‌های متصل (parachains) پشتیبانی می‌کند.

ویژگی‌های کلیدی Relay Chain:

  • هماهنگی بین Parachains: Relay Chain ارتباط و هماهنگی بین بلاکچین‌های مختلف (Parachains) را فراهم می‌کند. هر پاراچین یک بلاکچین مستقل است که می‌تواند ویژگی‌های خاص خود را داشته باشد، اما با کمک Relay Chain می‌تواند از امنیت و ویژگی‌های سایر بلاکچین‌ها بهره ببرد.
  • امنیت و اجماع: یکی از ویژگی‌های مهم Relay Chain استفاده از مدل اجماع Nominated Proof of Stake (NPoS) است که برای تأمین امنیت شبکه از اعتبارسنجی‌ها (validators) استفاده می‌کند. این مدل به اعتبارسنجی‌ها اجازه می‌دهد تا به‌صورت جمعی از امنیت کل اکوسیستم Polkadot محافظت کنند.
  • اشتراک‌گذاری منابع: Relay Chain منابعی را که توسط parachains مورد نیاز است، به اشتراک می‌گذارد. به این معنی که تمام زنجیره‌ها از قدرت محاسباتی و منابع مشترک استفاده می‌کنند که باعث کاهش هزینه‌ها و افزایش کارایی شبکه می‌شود.
  • اجماع در سطح شبکه: برخلاف بلاکچین‌های معمولی که فقط از یک الگوریتم اجماع برای خود استفاده می‌کنند، در Polkadot، Relay Chain از الگوریتم‌های اجماع مختلف برای مدیریت تعاملات بین زنجیره‌ها استفاده می‌کند.

2. ساختار و عملکرد Relay Chain

Relay Chain به‌طور خاص برای هماهنگی و امنیت بلاکچین‌های متصل طراحی شده است. این بلاکچین از دو بخش اصلی تشکیل شده است:

  • Consensus Layer (لایه اجماع): این لایه مسئول مدیریت فرآیند اجماع در Polkadot است. الگوریتم NPoS برای انتخاب اعتبارسنجی‌ها و تأمین امنیت شبکه به‌کار می‌رود. اعتبارسنجی‌ها وظیفه تولید بلوک‌های جدید و تأیید بلوک‌های دریافتی از parachains را دارند.
  • Cross-chain Message Passing (XCMP): این سیستم اجازه می‌دهد تا بلاکچین‌ها به‌صورت امن و سریع با یکدیگر ارتباط برقرار کنند. با استفاده از این سیستم، زنجیره‌های مختلف می‌توانند داده‌ها را به‌طور مستقیم و بدون نیاز به واسطه‌ها یا مراحل پیچیده انتقال دهند.

3. نحوه تعامل Relay Chain با Parachains

Relay Chain به‌طور خاص برای مدیریت و هماهنگ‌سازی بلاکچین‌های Parachain طراحی شده است. Parachains می‌توانند بلاکچین‌های مستقل با ویژگی‌های خاص خود باشند، اما برای اتصال به اکوسیستم Polkadot و استفاده از منابع مشترک، باید به Relay Chain متصل شوند. این ارتباط از طریق فرایندهای خاص مانند Parachain Slot Auctions (مزایده‌های فضای پاراچین) انجام می‌شود.

  • Parachain Slot Auctions: برای اینکه یک پاراچین بتواند به شبکه Polkadot متصل شود، باید در مزایده‌ها شرکت کند و یکی از اسلات‌های پاراچین در Relay Chain را برنده شود. این اسلات‌ها به‌طور محدود هستند و به‌این‌ترتیب رقابت بین بلاکچین‌ها برای اتصال به شبکه افزایش می‌یابد.
  • Cross-chain Communication: با استفاده از XCMP، parachains می‌توانند به‌صورت مستقیم و امن با یکدیگر ارتباط برقرار کنند. این قابلیت به بلاکچین‌ها اجازه می‌دهد تا داده‌ها و تراکنش‌ها را بدون نیاز به انجام فرآیندهای پیچیده یا استفاده از سرویس‌های واسطه‌ای انتقال دهند.

4. مزایا و چالش‌های استفاده از Relay Chain

مزایا:

  • مقیاس‌پذیری: با استفاده از مدل چند زنجیره‌ای، Polkadot می‌تواند میلیون‌ها تراکنش را به‌طور هم‌زمان پردازش کند. این مقیاس‌پذیری باعث می‌شود که Polkadot برای استفاده در پروژه‌های بزرگ و پیچیده مناسب باشد.
  • امنیت مشترک: تمام بلاکچین‌های متصل به Relay Chain از یک لایه امنیتی مشترک بهره می‌برند. این امنیت به‌وسیله مدل NPoS و همکاری اعتبارسنجی‌ها تأمین می‌شود.
  • انعطاف‌پذیری: هر پاراچین می‌تواند ویژگی‌ها و الگوریتم‌های اجماع خاص خود را داشته باشد، در حالی که همچنان به شبکه Polkadot متصل و از منابع مشترک بهره می‌برد.

چالش‌ها:

  • هزینه اسلات‌ها: مزایده‌ها برای اسلات‌های پاراچین ممکن است به‌طور قابل‌توجهی هزینه‌بر باشد و این می‌تواند برای برخی از پروژه‌ها مانع ایجاد کند.
  • پیچیدگی در توسعه: توسعه بلاکچین‌هایی که با استفاده از Polkadot و Relay Chain ارتباط دارند، نیازمند دانش فنی پیچیده‌تری است که ممکن است برای توسعه‌دهندگان مبتدی چالش‌برانگیز باشد.

جمع بندی

Relay Chain هسته و قلب اکوسیستم Polkadot است که بلاکچین‌های مختلف را به‌یکدیگر متصل می‌کند و از تبادل داده و امنیت آن‌ها پشتیبانی می‌کند. با استفاده از مدل اجماع NPoS و ویژگی‌های Cross-chain Message Passing (XCMP)، این بلاکچین می‌تواند مقیاس‌پذیری بالا، امنیت مشترک و انعطاف‌پذیری را برای بلاکچین‌های متصل فراهم کند. Relay Chain امکان ایجاد یک اکوسیستم بلاکچینی متحد و منسجم را فراهم کرده و به پروژه‌ها اجازه می‌دهد که به‌طور مستقل اما با همکاری یکدیگر عمل کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مفهوم Parachains و نحوه تعامل آن‌ها” subtitle=”توضیحات کامل”]Parachains بلاکچین‌های خاص و مستقل در اکوسیستم Polkadot هستند که می‌توانند ویژگی‌ها و اجماع خاص خود را داشته باشند. برخلاف بلاکچین‌های معمولی که به‌طور مستقل عمل می‌کنند، پاراچین‌ها به یک بلاکچین مرکزی به نام Relay Chain متصل می‌شوند و از منابع و امنیت مشترک آن بهره می‌برند. این ساختار به بلاکچین‌های مختلف این امکان را می‌دهد که به‌طور مؤثر و امن با یکدیگر ارتباط برقرار کنند و از مزایای اکوسیستم Polkadot استفاده کنند.

1. ویژگی‌های Parachains

  • استقلال: هر پاراچین می‌تواند ویژگی‌های خاص خود را داشته باشد و حتی از الگوریتم اجماع متفاوتی نسبت به Relay Chain استفاده کند. این استقلال باعث می‌شود که پاراچین‌ها برای استفاده در موارد خاص و با نیازهای خاص مناسب باشند.
  • امنیت مشترک: پاراچین‌ها با اتصال به Relay Chain از یک لایه امنیتی مشترک بهره می‌برند. این به این معنی است که هر پاراچین با کمک مدل اجماع Nominated Proof of Stake (NPoS) در Polkadot می‌تواند امنیت خود را تقویت کند بدون نیاز به راه‌اندازی سیستم امنیتی جداگانه.
  • مقیاس‌پذیری بالا: پاراچین‌ها به‌صورت موازی عمل می‌کنند، به این معنا که می‌توانند به‌طور همزمان تراکنش‌ها و فرآیندهای مختلف را پردازش کنند. این مقیاس‌پذیری موجب افزایش کارایی شبکه می‌شود.
  • استفاده از منابع مشترک: برخلاف بلاکچین‌های مستقل که برای هر بلاکچین نیاز به منابع و زیرساخت‌های جداگانه دارند، پاراچین‌ها می‌توانند از منابع مشترک موجود در Relay Chain استفاده کنند. این ویژگی به کاهش هزینه‌ها و بهبود عملکرد کمک می‌کند.

2. نحوه تعامل Parachains

در اکوسیستم Polkadot، Parachains از طریق چندین مکانیسم با یکدیگر و با Relay Chain ارتباط برقرار می‌کنند. این تعاملات از طریق سیستم‌های خاصی مانند Cross-Chain Message Passing (XCMP) و Shared Security انجام می‌شود.

  • Cross-Chain Message Passing (XCMP): این سیستم به پاراچین‌ها این امکان را می‌دهد که به‌طور مستقیم با یکدیگر ارتباط برقرار کنند و داده‌ها را انتقال دهند. به‌عنوان مثال، یک پاراچین می‌تواند داده‌هایی را از پاراچین دیگر دریافت کند بدون اینکه نیاز به سیستم‌های پیچیده یا واسطه‌ها باشد. این ارتباطات باعث می‌شود که بلاکچین‌ها به‌طور مؤثر و بدون ایجاد اختلال در عملکرد یکدیگر، داده‌ها را به اشتراک بگذارند.
  • Shared Security: یکی از ویژگی‌های کلیدی اکوسیستم Polkadot این است که تمام پاراچین‌ها از امنیت مشترک در Relay Chain بهره می‌برند. این بدان معناست که پاراچین‌ها از اعتبارسنجی‌های مشترک برای تأمین امنیت شبکه استفاده می‌کنند. در واقع، برای هر پاراچین اعتبارسنجی‌ها از یک فرآیند انتخابی به نام Nominated Proof of Stake (NPoS) استفاده می‌کنند تا بلوک‌های جدید را تولید کنند و در صورت وقوع اشتباه یا حمله، امنیت شبکه حفظ شود.

3. نحوه پیوستن Parachains به Polkadot

برای اینکه یک پاراچین به شبکه Polkadot متصل شود، باید Parachain Slot را به دست آورد. این کار از طریق فرآیندی به نام Parachain Slot Auction انجام می‌شود.

  • Parachain Slot Auction: در این مزایده‌ها، پروژه‌های مختلف باید برای بدست آوردن اسلات‌های پاراچین در Relay Chain رقابت کنند. این اسلات‌ها محدود هستند و به هر پاراچین اجازه می‌دهند تا به شبکه Polkadot متصل شود و از منابع مشترک و امنیت آن بهره‌برداری کند. پروژه‌ها باید از طریق crowdloan یا مشارکت با سایر پروژه‌ها در این مزایده‌ها شرکت کنند.

4. مزایای Parachains

  • مقیاس‌پذیری و کارایی بالا: به‌خاطر این‌که هر پاراچین می‌تواند به‌طور مستقل تراکنش‌های خود را پردازش کند و از منابع مشترک استفاده می‌کند، کارایی و مقیاس‌پذیری کلی شبکه Polkadot به‌طور چشم‌گیری افزایش می‌یابد.
  • انعطاف‌پذیری بالا: هر پاراچین می‌تواند اجماع و الگوریتم‌های خاص خود را داشته باشد، به این معنی که توسعه‌دهندگان می‌توانند بلاکچین‌هایی با ویژگی‌های خاص و متناسب با نیازهای خود ایجاد کنند.
  • امنیت تضمین‌شده: با استفاده از مدل امنیت مشترک و NPoS، تمام پاراچین‌ها از امنیت لازم برخوردارند بدون نیاز به ایجاد سیستم‌های امنیتی مجزا.
  • ارتباطات راحت و سریع: با استفاده از XCMP، پاراچین‌ها می‌توانند به‌طور مستقیم با یکدیگر ارتباط برقرار کنند و داده‌ها را بدون نیاز به واسطه‌ها منتقل کنند.

5. چالش‌های پاراچین‌ها

  • هزینه‌های مزایده: هزینه‌های شرکت در مزایده‌های Parachain Slot Auction می‌تواند برای برخی پروژه‌ها بالا باشد و این می‌تواند محدودیتی برای پروژه‌های کوچک‌تر باشد.
  • پیچیدگی در طراحی: طراحی یک پاراچین با استفاده از Substrate و اتصال آن به شبکه Polkadot نیازمند دانش فنی بالایی است و ممکن است برای توسعه‌دهندگان جدید پیچیده باشد.

جمع بندی

Parachains در Polkadot بلاکچین‌های مستقل و خاصی هستند که به‌طور مستقیم به Relay Chain متصل می‌شوند و از منابع مشترک و امنیت آن بهره می‌برند. این بلاکچین‌های مستقل می‌توانند ویژگی‌های خاص خود را داشته باشند و از اجماع متفاوتی نسبت به Relay Chain استفاده کنند. با استفاده از ویژگی‌های Cross-Chain Message Passing (XCMP) و Shared Security، پاراچین‌ها می‌توانند به‌طور مؤثر و امن با یکدیگر و با Relay Chain ارتباط برقرار کنند. سیستم Parachain Slot Auction به پروژه‌ها این امکان را می‌دهد که برای دریافت اسلات‌های پاراچین رقابت کنند و به شبکه Polkadot متصل شوند. این ویژگی‌ها موجب می‌شود که Polkadot یک اکوسیستم بلاکچینی مقیاس‌پذیر، انعطاف‌پذیر و امن باشد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی FRAME و نقش Pallets در Substrate” subtitle=”توضیحات کامل”]FRAME یکی از مفاهیم بنیادی و کلیدی در Substrate است که به‌عنوان چارچوبی برای ساخت بلاکچین‌های سفارشی عمل می‌کند. این چارچوب به توسعه‌دهندگان اجازه می‌دهد که بدون نیاز به بازنویسی کدهای پایه و پیچیده، به‌سرعت بلاکچین‌های موردنظر خود را طراحی و پیاده‌سازی کنند. یکی از اجزای اصلی FRAME، Pallets هستند که به‌عنوان بلوک‌های ساختمانی اصلی در Substrate عمل می‌کنند و قابلیت‌های مختلفی را برای بلاکچین‌ها فراهم می‌آورند.

1. FRAME چیست؟

FRAME (Framework for Runtime Aggregation of Modularized Entities) یک چارچوب ساختاری است که در Substrate برای توسعه بلاکچین‌های سفارشی طراحی شده است. این چارچوب به‌طور خاص برای ایجاد اجزای اجرایی (runtime) در بلاکچین‌ها به کار می‌رود و به‌طور خلاصه به توسعه‌دهندگان این امکان را می‌دهد که فقط بخش‌های خاص موردنیاز خود را پیاده‌سازی کنند و نیازی به نوشتن کدهای پیچیده برای اجزای پایه و اساسی سیستم نداشته باشند.

FRAME به توسعه‌دهندگان این امکان را می‌دهد که از Pallets استفاده کنند که به‌عنوان ماژول‌های قابل تنظیم برای اضافه کردن قابلیت‌ها به بلاکچین‌ها عمل می‌کنند. این پلتفرم به‌طور پیش‌فرض شامل مجموعه‌ای از Pallets است که عملکردهای اساسی مانند اجماع، ارسال تراکنش‌ها، ذخیره‌سازی و مدیریت دارایی‌ها را فراهم می‌کنند.

2. Pallets چیست؟

Pallets ماژول‌هایی هستند که در Substrate برای ایجاد قابلیت‌های مختلف به بلاکچین‌ها اضافه می‌شوند. هر Pallet مسئولیت انجام یک عمل خاص یا پیاده‌سازی یک ویژگی خاص را بر عهده دارد. به‌طور کلی، Pallets برای افزودن ویژگی‌های مختلف مانند سیستم‌های استیکینگ، مدیریت دارایی‌ها، دسترسی به قراردادهای هوشمند، رای‌گیری و بسیاری از قابلیت‌های دیگر استفاده می‌شوند.

هر Pallet در Substrate می‌تواند شامل چندین بخش باشد:

  • Storage: نحوه ذخیره‌سازی داده‌ها و اطلاعات.
  • Call: دستورات و عملیات‌هایی که می‌توانند توسط کاربران یا سیستم فراخوانی شوند.
  • Events: وقایعی که به‌عنوان نتیجه اقدامات مختلف ثبت می‌شوند.
  • Errors: کدهای خطا برای مدیریت شرایط مختلف.

3. ویژگی‌های Pallets

  • قابلیت استفاده مجدد: Pallets می‌توانند به‌صورت ماژولار استفاده شوند. این یعنی توسعه‌دهندگان می‌توانند تنها با انتخاب و پیکربندی Pallets موردنیاز خود، بلاکچین‌های سفارشی بسازند بدون نیاز به نوشتن مجدد کدهای پیچیده.
  • انعطاف‌پذیری: Pallets می‌توانند ویژگی‌های خاص خود را در شبکه‌ها پیاده‌سازی کنند. به‌عنوان مثال، یک Pallet می‌تواند ویژگی‌های قرارداد هوشمند را فراهم کند، در حالی که دیگری می‌تواند سیستم استیکینگ را مدیریت کند.
  • قابلیت توسعه: به‌راحتی می‌توان Pallets جدیدی را به Substrate اضافه کرد. توسعه‌دهندگان می‌توانند ویژگی‌های جدید را به بلاکچین خود اضافه کنند یا Pallets سفارشی خود را ایجاد کنند.
  • مدیریت ذخیره‌سازی: Pallets می‌توانند سیستم ذخیره‌سازی خاص خود را برای نگهداری داده‌ها و وضعیت بلاکچین‌ها مدیریت کنند.

4. نحوه کارکرد Pallets در Substrate

در Substrate، هنگام طراحی یک بلاکچین، می‌توان از FRAME برای ساختن اجزای مختلف سیستم استفاده کرد و Pallets مختلف را برای ایجاد ویژگی‌های خاص به این سیستم اضافه کرد. به‌عنوان مثال، اگر قصد دارید سیستم استیکینگ در بلاکچین خود داشته باشید، می‌توانید از Pallet Staking استفاده کنید. برای اضافه کردن قابلیت مدیریت دارایی‌ها می‌توانید از Pallet Balances بهره ببرید.

هر Pallet از طریق runtime در بلاکچین شما پیاده‌سازی می‌شود و رفتار بلاکچین را تعریف می‌کند. به‌عنوان مثال، در هنگام انجام تراکنش‌ها یا اجرای عملیات‌های مختلف، Palletها در زمینه‌های مختلف مانند استیکینگ، تراکنش‌ها، ذخیره‌سازی داده‌ها و سایر موارد، وظیفه خود را انجام می‌دهند.

5. انواع رایج Pallets در Substrate

در Substrate تعداد زیادی Pallet استاندارد برای استفاده وجود دارد. برخی از رایج‌ترین این Pallets شامل موارد زیر است:

  • Pallet Balances: این Pallet برای مدیریت دارایی‌ها و موجودی حساب‌ها استفاده می‌شود. این Pallet به‌طور پیش‌فرض برای ایجاد سیستم‌های مالی یا کیف پول‌های دیجیتال استفاده می‌شود.
  • Pallet Staking: این Pallet برای ایجاد سیستم‌های استیکینگ و انتخاب اعتبارسنج‌ها استفاده می‌شود. این قابلیت برای اجرای اجماع و امنیت در بلاکچین‌ها ضروری است.
  • Pallet Democracy: برای ایجاد سیستم‌های رای‌گیری و دموکراتیک در بلاکچین‌ها استفاده می‌شود. این Pallet می‌تواند برای ساخت سیستم‌های حاکمیتی استفاده شود.
  • Pallet Contracts: برای پشتیبانی از قراردادهای هوشمند و اجرای کدهای قرارداد هوشمند در بلاکچین استفاده می‌شود.
  • Pallet Treasury: برای مدیریت خزانه‌داری و منابع مالی در بلاکچین‌ها طراحی شده است.

6. نحوه توسعه Pallet سفارشی

اگر بخواهید یک Pallet سفارشی برای بلاکچین خود ایجاد کنید، مراحل اصلی به شرح زیر است:

  1. ایجاد یک پروژه جدید: ابتدا باید یک پروژه جدید در Substrate ایجاد کنید و سپس کدهای اولیه را برای بلاکچین خود بنویسید.
  2. ساختن Pallet: در داخل پروژه، می‌توانید کدی برای ساخت Pallet بنویسید که رفتار و ویژگی‌های خاص بلاکچین شما را پیاده‌سازی کند. به‌عنوان مثال، می‌توانید تراکنش‌ها یا سیستم‌های خاص را مدیریت کنید.
  3. پیکربندی Pallet: باید اطمینان حاصل کنید که Pallet موردنظر شما به‌درستی پیکربندی شده است و به‌درستی با سایر بخش‌های بلاکچین شما ارتباط برقرار می‌کند.
  4. تست Pallet: پس از نوشتن کد Pallet، باید آن را تست کنید تا مطمئن شوید که به‌طور صحیح و مؤثر عمل می‌کند.

جمع بندی

FRAME و Pallets در Substrate ابزارهای کلیدی برای ایجاد بلاکچین‌های سفارشی هستند. FRAME به توسعه‌دهندگان این امکان را می‌دهد که بدون نوشتن کدهای پیچیده، بلاکچین‌های خود را بسازند و از ماژول‌های قابل تنظیم به نام Pallets استفاده کنند. Pallets به‌عنوان بلوک‌های ساختاری برای افزودن قابلیت‌های مختلف به بلاکچین‌ها عمل می‌کنند و می‌توانند ویژگی‌هایی مانند مدیریت دارایی‌ها، استیکینگ، قراردادهای هوشمند و بسیاری از قابلیت‌های دیگر را به بلاکچین‌ها اضافه کنند. توسعه‌دهندگان می‌توانند به‌راحتی Pallets سفارشی خود را ایجاد کرده و آن‌ها را به بلاکچین خود اضافه کنند تا نیازهای خاص خود را برآورده سازند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مقایسه Proof-of-Stake در Polkadot و Cosmos” subtitle=”توضیحات کامل”]Proof-of-Stake (PoS) یکی از الگوریتم‌های اجماع است که در بسیاری از بلاکچین‌های مدرن برای تأمین امنیت و انجام تراکنش‌ها استفاده می‌شود. در این الگوریتم، اعتبارسنج‌ها به‌جای حل مسائل پیچیده ریاضی (مانند Proof-of-Work)، با استفاده از دارایی‌های خود (توکن‌های بلاکچین) به اعتبارسنجی تراکنش‌ها و تأمین امنیت شبکه کمک می‌کنند. در این بخش، به مقایسه پیاده‌سازی PoS در Polkadot و Cosmos خواهیم پرداخت.

1. Proof-of-Stake در Polkadot

در Polkadot، سیستم اجماع به‌نام Nominated Proof-of-Stake (NPoS) پیاده‌سازی شده است. NPoS ترکیبی از ویژگی‌های PoS استاندارد و مکانیسم‌هایی برای اعتبارسنجی و انتخاب اعتبارسنج‌های قابل اعتماد است.

  • Nominated Proof-of-Stake (NPoS): در NPoS، دو نوع شرکت‌کننده وجود دارند: نامزدها (Nominators) و اعتبارسنج‌ها (Validators). اعتبارسنج‌ها وظیفه تأمین امنیت شبکه و تأیید تراکنش‌ها را بر عهده دارند. در حالی که نامزدها، کسانی هستند که توکن‌های خود را به اعتبارسنج‌ها اختصاص می‌دهند و از طریق این کار، به اعتبارسنج‌ها رأی می‌دهند.
    • اعتبارسنج‌ها: اعتبارسنج‌ها وظیفه تولید بلاک‌ها و تایید تراکنش‌ها را بر عهده دارند. برای انجام این کار، اعتبارسنج‌ها باید توکن‌های DOT (توکن بومی Polkadot) را استیک کنند.
    • نامزدها: نامزدها توکن‌های خود را به اعتبارسنج‌های موردنظر اختصاص می‌دهند تا بتوانند رأی در انتخاب اعتبارسنج‌ها داشته باشند و در عین حال، درصدی از جوایز کسب‌شده توسط اعتبارسنج‌ها را دریافت کنند.
  • ویژگی‌ها:
    • تنظیم دقیق و شفاف: اعتبارسنج‌ها با توجه به میزان استیک‌شده، رتبه‌بندی می‌شوند و شبکه به‌صورت خودکار، اعتبارسنج‌ها را انتخاب می‌کند.
    • امنیت بالا: اعتبارسنج‌هایی که به‌طور نادرست رفتار کنند یا بخواهند از سیستم سوءاستفاده کنند، توکن‌های استیک‌شده خود را از دست می‌دهند.
    • رای‌گیری از سوی نامزدها: سیستم NPoS به نامزدها اجازه می‌دهد که در انتخاب اعتبارسنج‌ها نقش داشته باشند، به‌این‌ترتیب، توکن‌های استیک‌شده توسط نامزدها، نقش مؤثری در فرآیند انتخاب اعتبارسنج‌ها دارند.
  • فرآیند استیکینگ و اعتبارسنجی: اعتبارسنج‌ها برای تولید بلاک‌ها باید از توکن‌های خود به‌عنوان وثیقه استفاده کنند. اگر اعتبارسنج‌ها به‌طور صحیح عمل نکنند یا تلاش کنند تا شبکه را فریب دهند، بخش‌هایی از توکن‌های استیک‌شده آن‌ها از دست می‌رود. این مکانیسم، از اعتبارسنج‌ها می‌خواهد که به‌درستی عمل کنند و امنیت شبکه را حفظ کنند.

2. Proof-of-Stake در Cosmos

در Cosmos، سیستم اجماع به‌نام Tendermint Core استفاده می‌شود که به‌عنوان یک الگوریتم PoS عمل می‌کند. Tendermint برای ایجاد اجماع سریع و امن بین نودهای شبکه به کار می‌رود. این الگوریتم به‌طور ویژه برای شبکه‌های بلاکچینی ساخته شده است که به دنبال مقیاس‌پذیری و امنیت بالا هستند.

  • Proof-of-Stake در Cosmos: در Cosmos، اعتبارسنج‌ها برای شرکت در فرآیند اجماع، توکن‌های ATOM (توکن بومی شبکه Cosmos) را استیک می‌کنند. این سیستم از اجماع BFT (Byzantine Fault Tolerant) استفاده می‌کند که به‌صورت خاص برای تحمل خطاها و حملات احتمالی طراحی شده است.
    • اعتبارسنج‌ها: اعتبارسنج‌ها در سیستم PoS نقش کلیدی در فرآیند اجماع دارند. آن‌ها از طریق استیک کردن توکن‌های ATOM خود، قدرت رأی در شبکه را دارند و وظیفه دارند که بلاک‌ها را تولید کرده و تراکنش‌ها را تأیید کنند.
    • نکته جالب: اعتبارسنج‌ها در Cosmos باید برای تولید بلاک‌ها بر اساس رتبه‌بندی و میزان توکن‌های استیک‌شده، انتخاب شوند.
  • ویژگی‌ها:
    • امنیت و کارآیی بالا: سیستم Tendermint، با توجه به استفاده از الگوریتم BFT، به شبکه امکان تحمل نقص‌های احتمالی و رفتارهای بد از نودها را می‌دهد.
    • توزیع مکافات: اعتبارسنج‌ها بر اساس میزان توکن‌هایی که استیک کرده‌اند، درصدی از جوایز شبکه را دریافت می‌کنند.
    • حاکمیت دموکراتیک: در Cosmos، اعتبارسنج‌ها به‌صورت دموکراتیک انتخاب می‌شوند و دارندگان توکن ATOM می‌توانند در تصمیم‌گیری‌های شبکه مشارکت کنند.
  • فرآیند استیکینگ و اعتبارسنجی: اعتبارسنج‌ها باید توکن‌های ATOM خود را در فرآیند استیکینگ به‌طور مستقیم در شبکه قرار دهند. این استیکینگ، نه تنها برای امنیت شبکه، بلکه برای تصمیم‌گیری‌های مربوط به تغییرات پروتکل و حاکمیت شبکه نیز استفاده می‌شود.

3. مقایسه میان PoS در Polkadot و Cosmos

ویژگی Polkadot (Nominated Proof-of-Stake) Cosmos (Tendermint PoS)
نوع الگوریتم اجماع Nominated Proof-of-Stake (NPoS) Proof-of-Stake با Tendermint
نقش اعتبارسنج‌ها تولید بلاک‌ها و تأیید تراکنش‌ها تولید بلاک‌ها و تأیید تراکنش‌ها
نقش نامزدها انتخاب اعتبارسنج‌ها و اختصاص توکن‌ها به آن‌ها ندارد (تمامی قدرت رأی در دست اعتبارسنج‌ها)
امنیت استفاده از نامزدها برای انتخاب بهترین اعتبارسنج‌ها الگوریتم BFT برای تحمل خطاها
مکانیسم رأی‌گیری رأی‌دهی به‌وسیله نامزدها برای انتخاب اعتبارسنج‌ها نودها بر اساس میزان استیکینگ انتخاب می‌شوند
فرآیند استیکینگ استیک توکن‌ها به اعتبارسنج‌ها برای رأی‌دهی استیک توکن‌ها برای اعتبارسنجی و اجماع
جوایز و تقسیم مکافات تقسیم جوایز بر اساس میزان استیک‌شده و رتبه‌بندی تقسیم جوایز بر اساس میزان استیک‌شده
حاکمیت نهادهای حاکمیتی با نظارت از سوی نودها تصمیم‌گیری‌های شبکه از طریق رأی‌گیری توسط دارندگان توکن

جمع بندی

در حالی که هر دو Polkadot و Cosmos از Proof-of-Stake برای تأمین امنیت و اجماع در شبکه‌های خود استفاده می‌کنند، رویکردهای متفاوتی در این دو اکوسیستم وجود دارد. در Polkadot از Nominated Proof-of-Stake استفاده می‌شود که نقش قابل‌توجهی برای نامزدها در انتخاب اعتبارسنج‌ها قائل است، در حالی که در Cosmos، Tendermint از الگوریتم Byzantine Fault Tolerant (BFT) برای تأمین اجماع استفاده می‌کند و تمرکز بیشتر بر روی اعتبارسنج‌ها است. این تفاوت‌ها منجر به ساختار حاکمیتی، فرآیند انتخاب اعتبارسنج‌ها و نحوه تقسیم جوایز در هر کدام می‌شود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. مقایسه Cosmos SDK و Polkadot Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نحوه مدیریت امنیت و اجماع در Polkadot و Cosmos” subtitle=”توضیحات کامل”]امنیت و اجماع یکی از جنبه‌های حیاتی در هر شبکه بلاکچینی است. این مفاهیم نه تنها به حفظ یکپارچگی شبکه کمک می‌کنند، بلکه از حملات و دستکاری‌های احتمالی در شبکه جلوگیری می‌کنند. در این بخش، به بررسی نحوه مدیریت امنیت و اجماع در دو فریمورک Polkadot و Cosmos پرداخته می‌شود.

1. امنیت و اجماع در Polkadot

Polkadot از یک ساختار چند زنجیره‌ای استفاده می‌کند که امنیت و اجماع را به‌طور مرکزی از طریق Relay Chain تأمین می‌کند. Relay Chain نقش هسته اصلی شبکه را ایفا کرده و امنیت و اجماع کل شبکه را مدیریت می‌کند. هر زنجیره‌ای که به Polkadot متصل است، به‌عنوان Parachain شناخته می‌شود و از امنیت شبکه Relay Chain بهره می‌برد.

  • مکانیسم اجماع: Nominated Proof-of-Stake (NPoS)
    در Polkadot، Nominated Proof-of-Stake (NPoS) برای اجماع و تأمین امنیت استفاده می‌شود. در این مکانیزم، اعتبارسنج‌ها و نامزدها (Nominators) به‌طور مشترک در فرآیند اجماع مشارکت دارند.

    • اعتبارسنج‌ها: اعتبارسنج‌ها مسئول تولید بلاک‌ها و تأیید تراکنش‌ها هستند. این اعتبارسنج‌ها توکن‌های DOT خود را به‌عنوان وثیقه برای مشارکت در اجماع و تأمین امنیت شبکه استیک می‌کنند.
    • نامزدها: نامزدها، توکن‌های خود را به اعتبارسنج‌ها اختصاص می‌دهند و به این طریق در انتخاب اعتبارسنج‌ها و در فرآیند اجماع نقش دارند.
  • امنیت با استفاده از انتخاب اعتبارسنج‌ها: در NPoS، اعتبارسنج‌ها با توجه به میزان توکن‌هایی که از نامزدها به‌عنوان رأی دریافت می‌کنند، انتخاب می‌شوند. این مکانیزم، از اعتبارسنج‌ها می‌خواهد که همیشه به‌درستی عمل کنند، زیرا اگر در تأسیس بلاک‌ها خطا کنند یا سعی کنند از سیستم سوءاستفاده کنند، توکن‌های استیک‌شده‌شان از دست می‌رود.
  • امنیت Relay Chain و Parachains:
    • Relay Chain: امنیت اصلی شبکه از طریق Relay Chain تأمین می‌شود. تمام Parachain‌ها برای امنیت و اجماع به این زنجیره مرکزی متکی هستند. Relay Chain، اجماع را از طریق الگوریتم NPoS پیاده‌سازی می‌کند.
    • Parachains: هر Parachain برای انجام عملیات خود نیاز به استفاده از اجماع و امنیت Relay Chain دارد. این مدل باعث می‌شود که امنیت شبکه چند زنجیره‌ای (Multichain) از طریق یک هسته واحد تضمین شود.
  • امنیت در برابر حملات:
    • اگر اعتبارسنج‌ها شروع به رفتار نادرست کنند یا سعی در دستکاری تراکنش‌ها داشته باشند، مکانیسم slashing فعال می‌شود و بخش‌هایی از توکن‌های استیک‌شده اعتبارسنج‌ها از دست می‌رود. این کار باعث می‌شود که اعتبارسنج‌ها از انجام فعالیت‌های مخرب خودداری کنند.

2. امنیت و اجماع در Cosmos

در Cosmos، Tendermint Core به‌عنوان الگوریتم اجماع اصلی برای مدیریت امنیت و اجماع شبکه‌های مختلف (که به‌عنوان زنجیره‌های مستقل یا Zones شناخته می‌شوند) به‌کار می‌رود. این الگوریتم مبتنی بر Proof-of-Stake است و از نظر امنیت و اجماع به‌طور خاص طراحی شده تا تحمل خطاهای بیزانسی (Byzantine Fault Tolerant) را داشته باشد.

  • مکانیسم اجماع: Tendermint (BFT PoS)
    در Cosmos، Tendermint از الگوریتم Byzantine Fault Tolerant (BFT) استفاده می‌کند که می‌تواند حتی در صورت وجود نقص در برخی از نودها، اجماع را حفظ کند. این الگوریتم به شبکه این امکان را می‌دهد که در حضور تا یک‌سوم نودهای خراب یا فریب‌کار هم امنیت شبکه حفظ شود.

    • اعتبارسنج‌ها: در Cosmos، اعتبارسنج‌ها باید توکن‌های ATOM خود را استیک کنند تا بتوانند در اجماع و تأسیس بلاک‌ها مشارکت کنند.
    • فرآیند اجماع: در الگوریتم BFT، اعتبارسنج‌ها برای تولید بلاک‌ها و تأیید تراکنش‌ها باید به توافق برسند. پس از تأسیس بلاک، بقیه نودها آن را تأیید می‌کنند و پس از آن بلاک به زنجیره اضافه می‌شود.
  • امنیت با استفاده از BFT: الگوریتم BFT به این معنی است که حتی اگر یک‌سوم اعتبارسنج‌ها رفتار نادرست انجام دهند، شبکه همچنان قادر به اجماع خواهد بود. این ویژگی به شبکه Cosmos امنیت بالایی می‌بخشد.
  • حاکمیت و امنیت:
    در Cosmos، تصمیمات مربوط به تغییرات پروتکل و سایر مسائل شبکه از طریق حاکمیت مبتنی بر توکن (Token-based Governance) اتخاذ می‌شود. دارندگان توکن‌های ATOM می‌توانند در تصمیمات شبکه رأی دهند و از این طریق، شبکه می‌تواند در برابر تهدیدات و حملات احتمالی مقاومت کند.
  • امنیت در برابر حملات:
    مشابه Polkadot، در Cosmos نیز اگر اعتبارسنج‌ها تلاش کنند که به شبکه آسیب برسانند یا رفتار نادرست داشته باشند، مکانیسم slashing فعال می‌شود. در این مکانیسم، بخشی از توکن‌های استیک‌شده اعتبارسنج‌ها جریمه می‌شود تا از سوءاستفاده جلوگیری شود.

3. مقایسه امنیت و اجماع در Polkadot و Cosmos

ویژگی Polkadot Cosmos
الگوریتم اجماع Nominated Proof-of-Stake (NPoS) Tendermint (Byzantine Fault Tolerant PoS)
نوع شبکه شبکه چند زنجیره‌ای با Relay Chain و Parachains شبکه تک زنجیره‌ای و متصل‌کننده چند زنجیره
نقش اعتبارسنج‌ها تولید بلاک‌ها و تأیید تراکنش‌ها تولید بلاک‌ها و تأیید تراکنش‌ها
مکانیسم رأی‌دهی نامزدها به اعتبارسنج‌ها رأی می‌دهند اعتبارسنج‌ها در فرآیند اجماع مشارکت دارند
حفاظت در برابر حملات مکانیسم Slashing برای جریمه اعتبارسنج‌ها مکانیسم Slashing برای جریمه اعتبارسنج‌ها
امنیت در برابر نقص‌ها استفاده از NPoS و تأمین امنیت توسط Relay Chain استفاده از BFT برای تحمل خطاهای بیزانسی
مشارکت در حاکمیت از طریق NPoS و رأی‌دهی نامزدها از طریق رأی‌دهی دارندگان توکن ATOM

جمع بندی

در هر دو اکوسیستم Polkadot و Cosmos، امنیت و اجماع به‌طور خاص و با الگوریتم‌های متفاوتی مدیریت می‌شود. Polkadot از Nominated Proof-of-Stake برای ایجاد اجماع استفاده می‌کند که شامل انتخاب اعتبارسنج‌ها توسط نامزدها است و از یک شبکه چند زنجیره‌ای برای تأمین امنیت استفاده می‌کند. در مقابل، Cosmos از Tendermint BFT برای اجماع استفاده می‌کند که به آن اجازه می‌دهد در صورت وجود نقص در نودها، اجماع را حفظ کند. هر دو شبکه از مکانیسم slashing برای تأمین امنیت و جلوگیری از سوءاستفاده‌ها استفاده می‌کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مقایسه مدل تعامل بین زنجیره‌ها: IBC در Cosmos و XCMP در Substrate” subtitle=”توضیحات کامل”]تعامل بین زنجیره‌ها یکی از جنبه‌های مهم در اکوسیستم‌های بلاکچینی است که امکان انتقال داده‌ها و ارزش میان شبکه‌های مختلف را فراهم می‌کند. در این بخش، به مقایسه دو مدل اصلی تعامل بین زنجیره‌ها، یعنی IBC (Inter-Blockchain Communication) در Cosmos و XCMP (Cross-Chain Message Passing) در Substrate خواهیم پرداخت.

1. مدل IBC در Cosmos

IBC یکی از فناوری‌های کلیدی در Cosmos است که هدف آن ایجاد ارتباط و تعامل میان زنجیره‌های مختلف در اکوسیستم Cosmos Hub است. IBC به‌عنوان یک پروتکل برای انتقال داده‌ها، توکن‌ها، و اطلاعات بین زنجیره‌ای عمل می‌کند.

  • ساختار IBC:
    • Hub-and-Spoke: در Cosmos، معماری IBC از یک مدل Hub-and-Spoke استفاده می‌کند. در این مدل، Cosmos Hub به‌عنوان هاب مرکزی عمل کرده و زنجیره‌های مختلف (که به‌عنوان Zones شناخته می‌شوند) به آن متصل می‌شوند.
    • انتقال توکن‌ها و داده‌ها: IBC امکان ارسال توکن‌ها و داده‌ها از یک زنجیره به زنجیره دیگر را فراهم می‌کند. این ارتباط از طریق ارسال پیام‌ها بین زنجیره‌ها برقرار می‌شود و از لحاظ امنیتی تضمین می‌شود که پیام‌ها صحیح و معتبر هستند.
  • مکانیسم انتقال IBC:
    • برای ارسال داده‌ها بین زنجیره‌ها، Relayers نقش واسط را ایفا می‌کنند. Relayers اطلاعات مربوط به تراکنش‌ها و پیام‌ها را از یک زنجیره به زنجیره دیگر منتقل می‌کنند. این پیام‌ها می‌توانند شامل انتقال توکن‌ها، تغییرات وضعیت، یا حتی پیام‌های خاص دیگری باشند.
    • پیام‌های IBC از طریق کانال‌های اختصاصی بین دو زنجیره ارسال می‌شوند. این کانال‌ها به‌صورت دوطرفه ایجاد می‌شوند و هر دو طرف (زنجیره فرستنده و گیرنده) باید به توافق برسند تا پیام‌ها معتبر شناخته شوند.
  • امنیت IBC:
    • IBC از پروتکل‌های امنیتی پیچیده‌ای استفاده می‌کند تا اطمینان حاصل شود که پیام‌ها به‌طور صحیح و بدون دستکاری منتقل می‌شوند. این پروتکل‌ها مبتنی بر Tendermint هستند و از امنیت بلاکچین‌های اجماعی برای تضمین صحت پیام‌ها استفاده می‌کنند.
    • علاوه بر این، پروتکل light clients در هر زنجیره برای نظارت بر وضعیت بلاکچین دیگر مورد استفاده قرار می‌گیرد و از این طریق امنیت تراکنش‌ها و پیام‌ها تأمین می‌شود.

2. مدل XCMP در Substrate

XCMP (Cross-Chain Message Passing) یک پروتکل ارتباطی است که در Substrate برای برقراری تعامل بین پاراچین‌ها و زنجیره‌های مختلف طراحی شده است. هدف اصلی XCMP، تسهیل ارتباط و تعامل بی‌درنگ بین زنجیره‌ها (Parachains) در اکوسیستم Polkadot است.

  • ساختار XCMP:
    • Relay Chain: در Polkadot، تمام پاراچین‌ها به Relay Chain متصل هستند و از آن برای تأمین امنیت و اجماع استفاده می‌کنند. در مدل XCMP، این Relay Chain به‌عنوان یک پل ارتباطی بین پاراچین‌ها عمل می‌کند.
    • انتقال پیام‌ها: XCMP به پاراچین‌ها این امکان را می‌دهد که پیام‌ها و داده‌ها را به‌طور مستقیم با یکدیگر مبادله کنند. این پیام‌ها می‌توانند شامل توکن‌ها، وضعیت‌ها یا داده‌های دیگر باشند.
    • برخلاف IBC که بیشتر به Hub-and-Spoke متکی است، XCMP امکان ارتباط مستقیم و peer-to-peer بین پاراچین‌ها را فراهم می‌کند.
  • مکانیسم انتقال XCMP:
    • در XCMP، ارسال پیام‌ها بین پاراچین‌ها از طریق سیستم Queued Cross-Chain Message Passing (QXCMP) انجام می‌شود. این پیام‌ها در یک صف (queue) قرار می‌گیرند و به‌طور امن و همزمان بین پاراچین‌ها منتقل می‌شوند.
    • این صف‌ها به‌گونه‌ای طراحی شده‌اند که بتوانند بار زیاد و تراکنش‌های پیچیده را به‌طور مؤثر پردازش کنند. هر پاراچین می‌تواند پیام‌های خود را ارسال کند و در صورت دریافت پیام از پاراچین دیگر، اقدام مناسب را انجام دهد.
  • امنیت XCMP:
    • در XCMP، امنیت بر اساس اعتبارسنج‌های موجود در Relay Chain تأمین می‌شود. هر پاراچین برای ارسال پیام از Relay Chain استفاده می‌کند تا اطمینان حاصل شود که پیام‌ها صحیح و تأسیس شده‌اند.
    • مشابه IBC، برای اطمینان از صحت پیام‌ها و جلوگیری از دستکاری، از light clients برای نظارت بر وضعیت‌های پاراچین‌ها استفاده می‌شود.

3. مقایسه IBC و XCMP

ویژگی IBC (Cosmos) XCMP (Substrate)
ساختار Hub-and-Spoke (Cosmos Hub و Zones) پاراچین‌ها به‌طور مستقیم به‌یکدیگر متصل می‌شوند
مکانیسم انتقال پیام‌ها از طریق کانال‌های IBC و Relayers از طریق Queued Cross-Chain Message Passing (QXCMP)
امنیت استفاده از Tendermint و پروتکل‌های light clients تأمین امنیت از طریق Relay Chain و light clients
نوع ارتباط ارتباط دوطرفه بین زنجیره‌ها ارتباط مستقیم و peer-to-peer بین پاراچین‌ها
نوع شبکه شبکه چند زنجیره‌ای با هاب مرکزی (Cosmos Hub) شبکه چند زنجیره‌ای با Relay Chain مرکزی (Polkadot)
استفاده از Relayers بله، برای انتقال پیام‌ها و تراکنش‌ها خیر، پیام‌ها به‌طور مستقیم بین پاراچین‌ها منتقل می‌شود

جمع بندی

IBC و XCMP هر دو پروتکل‌هایی برای تعامل و ارتباط میان زنجیره‌ها هستند، اما از لحاظ طراحی و نحوه عملکرد متفاوت هستند. IBC در Cosmos بر اساس مدل Hub-and-Spoke کار می‌کند و از Relayers برای انتقال پیام‌ها بین زنجیره‌ها استفاده می‌کند. در مقابل، XCMP در Substrate برای پاراچین‌ها به‌طور مستقیم ارتباط ایجاد می‌کند و از یک سیستم صف‌بندی برای ارسال پیام‌ها استفاده می‌کند. امنیت در هر دو پروتکل از طریق استفاده از light clients و اجماع‌های موجود در هر شبکه تأمین می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”توسعه و گسترش‌پذیری در Cosmos SDK در مقابل Substrate” subtitle=”توضیحات کامل”]توسعه و گسترش‌پذیری از مهم‌ترین جنبه‌های طراحی بلاکچین‌ها هستند. در دنیای بلاکچین‌های سفارشی، دو فریمورک محبوب که در زمینه توسعه شبکه‌های مقیاس‌پذیر و قابل سفارشی شدن پیشرفت‌های زیادی داشته‌اند، Cosmos SDK و Substrate هستند. هرکدام از این فریمورک‌ها رویکردهای متفاوتی برای توسعه و گسترش‌پذیری دارند که در این بخش به بررسی تفاوت‌های این دو فریمورک خواهیم پرداخت.

1. توسعه در Cosmos SDK

Cosmos SDK یک فریمورک متن‌باز است که هدف آن ایجاد بلاکچین‌های سفارشی و مقیاس‌پذیر است. این فریمورک به‌طور خاص برای توسعه بلاکچین‌های متصل به یک اکوسیستم بزرگ‌تر (مانند Cosmos Hub) طراحی شده است.

  • مدل ماژولار:
    • Cosmos SDK از معماری ماژولار برای ساخت بلاکچین‌ها استفاده می‌کند. هر بلاکچین در Cosmos از مجموعه‌ای از ماژول‌ها ساخته می‌شود که می‌توانند به راحتی اضافه، حذف یا سفارشی شوند. این ماژول‌ها شامل ماژول‌هایی برای مدیریت Staking، Bank، Governance و غیره هستند.
    • این ویژگی به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خاص خود را با ویژگی‌های سفارشی ایجاد کنند بدون اینکه نیازی به تغییر در هسته اصلی بلاکچین باشد.
  • سهولت استفاده و توسعه:
    • Cosmos SDK به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی بسازند و بر اساس نیاز خود از ماژول‌های مختلف استفاده کنند. همچنین، توسعه‌دهندگان می‌توانند به راحتی در محیط توسعه (Development Environment) با استفاده از زبان Go، کدهای خود را نوشته و اجرا کنند.
    • با توجه به ویژگی‌هایی مانند IBC (Inter-Blockchain Communication)، Cosmos SDK به راحتی امکان تعامل بین بلاکچین‌ها را فراهم می‌کند، که یکی از مزایای اصلی برای ایجاد اکوسیستم‌های بزرگ و گسترش‌پذیر است.
  • گسترش‌پذیری:
    • Cosmos SDK به‌طور طبیعی برای گسترش‌پذیری طراحی شده است. از آنجا که بلاکچین‌ها به‌صورت مستقل (Zones) کار می‌کنند و می‌توانند به راحتی به Cosmos Hub متصل شوند، شبکه‌های جدید می‌توانند به‌طور مستقل از دیگر شبکه‌ها توسعه یابند و با شبکه‌های دیگر تعامل داشته باشند.
    • همچنین، پروتکل Tendermint که در Cosmos SDK استفاده می‌شود، مقیاس‌پذیری بالایی را به‌ویژه در اجماع بلاکچین فراهم می‌کند.

2. توسعه در Substrate

Substrate یک فریمورک ساخت بلاکچین است که توسط Parity Technologies برای ایجاد بلاکچین‌های سفارشی با هدف مقیاس‌پذیری بالا طراحی شده است. این فریمورک در قلب اکوسیستم Polkadot قرار دارد و به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خاص خود را بسازند و آن‌ها را در شبکه‌های دیگر با استفاده از پروتکل XCMP (Cross-Chain Message Passing) به اشتراک بگذارند.

  • مدل ماژولار و FRAME:
    • Substrate نیز به‌طور مشابه با Cosmos SDK، از مدل ماژولار برای ساخت بلاکچین‌ها استفاده می‌کند. این ماژول‌ها با استفاده از FRAME (Framework for Runtime Aggregation of Modularized Entities) طراحی شده‌اند که مجموعه‌ای از پالت‌ها (Pallets) را ارائه می‌دهد. هر پالت می‌تواند عملکرد خاصی را ارائه دهد، مانند Staking، Governance، و Balances.
    • استفاده از این پالت‌ها به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خود را بر اساس نیاز خود تنظیم کنند و هر پالت می‌تواند به‌صورت مستقل توسعه یابد.
  • گسترش‌پذیری:
    • Substrate به‌گونه‌ای طراحی شده که بلاکچین‌های ایجاد شده با آن قادر به برقراری ارتباط با یکدیگر و با دیگر بلاکچین‌ها هستند. این ارتباط از طریق Polkadot Relay Chain امکان‌پذیر است که امنیت و اجماع بین بلاکچین‌ها را فراهم می‌کند.
    • یکی از ویژگی‌های مهم Substrate این است که بلاکچین‌ها می‌توانند در یک شبکه به‌صورت موازی فعالیت کنند و از یکدیگر جدا باشند. این امر باعث می‌شود که قابلیت گسترش و مقیاس‌پذیری بسیار بالا باشد، چرا که هر پاراچین می‌تواند در مورد نیازهای خاص خود به‌طور مستقل کار کند و از منابع مشترک شبکه بهره‌برداری کند.
  • سهولت توسعه و سفارشی‌سازی:
    • Substrate از زبان برنامه‌نویسی Rust استفاده می‌کند که به دلیل سرعت بالا و ایمنی، برای ساخت بلاکچین‌های پیچیده مناسب است. Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی خود را با عملکردهای پیچیده و پیشرفته طراحی کنند.
    • از آنجا که Substrate خود از Polkadot استفاده می‌کند، توسعه‌دهندگان می‌توانند به راحتی از Relay Chain برای تعامل بین بلاکچین‌ها استفاده کنند.

3. مقایسه توسعه و گسترش‌پذیری در Cosmos SDK و Substrate

ویژگی Cosmos SDK Substrate
ساختار ماژولار ماژول‌های مختلف برای سفارشی‌سازی بلاکچین‌ها ماژول‌ها و پالت‌ها برای سفارشی‌سازی و توسعه بلاکچین‌ها
سهولت توسعه استفاده از زبان Go و ماژول‌های آماده استفاده از زبان Rust برای توسعه پیچیده‌تر بلاکچین‌ها
گسترش‌پذیری اتصال بلاکچین‌ها به Cosmos Hub از طریق IBC بلاکچین‌ها می‌توانند به‌طور مستقل در Polkadot یا Relay Chain کار کنند
مقیاس‌پذیری مقیاس‌پذیری از طریق Tendermint و بلاکچین‌های مستقل مقیاس‌پذیری از طریق Polkadot و استفاده از پاراچین‌ها
ارتباط بین بلاکچین‌ها از طریق IBC و ارتباطات میان زنجیره‌ای از طریق XCMP و ارتباطات میان پاراچین‌ها

جمع بندی

هر دو فریمورک Cosmos SDK و Substrate برای ساخت بلاکچین‌های سفارشی و مقیاس‌پذیر طراحی شده‌اند، اما در رویکردهای خود تفاوت‌های اساسی دارند. Cosmos SDK با استفاده از معماری ماژولار و IBC امکان اتصال بلاکچین‌های مستقل به یکدیگر را فراهم می‌کند. در مقابل، Substrate به توسعه‌دهندگان این امکان را می‌دهد که از Polkadot برای ایجاد شبکه‌های مقیاس‌پذیر و تعامل بین پاراچین‌ها استفاده کنند. هر دو فریمورک قابلیت گسترش‌پذیری بالایی دارند و به توسعه‌دهندگان ابزارهایی برای ساخت بلاکچین‌های سفارشی ارائه می‌دهند، اما انتخاب فریمورک مناسب به نیاز خاص پروژه بستگی دارد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تفاوت‌های زبان‌های برنامه‌نویسی (Go در Cosmos SDK و Rust در Substrate)” subtitle=”توضیحات کامل”]زبان‌های برنامه‌نویسی انتخابی برای توسعه بلاکچین‌ها نقش بسیار مهمی در عملکرد، امنیت، و قابلیت‌های توسعه آن‌ها دارند. در فریمورک‌های Cosmos SDK و Substrate، به‌ترتیب از زبان‌های Go و Rust برای توسعه استفاده می‌شود. این دو زبان به دلیل ویژگی‌های خاص خود تفاوت‌های زیادی دارند که در ادامه به بررسی آن‌ها خواهیم پرداخت.

1. زبان برنامه‌نویسی Go در Cosmos SDK

Go (که به‌عنوان Golang نیز شناخته می‌شود) یک زبان برنامه‌نویسی سطح بالا و متن‌باز است که توسط Google طراحی شده و به‌ویژه برای کاربردهای شبکه‌ای، سیستم‌های توزیع‌شده و برنامه‌های مقیاس‌پذیر بسیار مناسب است.

  • سادگی و یادگیری سریع:
    • Go به‌خاطر سینتکس ساده و کم‌پیچیدگی که دارد، برای توسعه‌دهندگان تازه‌کار و حرفه‌ای به راحتی قابل یادگیری است. این زبان به‌ویژه برای پروژه‌های سریع و مقیاس‌پذیر طراحی شده و هیچ‌گونه پیچیدگی زیادی در ساختار زبان ندارد.
    • از آنجا که Go یک زبان کاربردی است، توسعه‌دهندگان می‌توانند به سرعت برنامه‌های خود را ایجاد کنند و آن‌ها را به‌صورت سریع‌تری نسبت به سایر زبان‌ها دیباگ کنند.
  • مقیاس‌پذیری و کارایی:
    • Go در زمینه سیستم‌های توزیع‌شده و شبکه‌ای به‌طور خاص طراحی شده است و به همین دلیل در Cosmos SDK برای ایجاد بلاکچین‌های مقیاس‌پذیر و سریع استفاده می‌شود. این زبان از Concurrency یا هم‌زمانی بسیار خوبی بهره می‌برد که امکان پردازش همزمان درخواست‌ها را فراهم می‌کند.
    • Go به دلیل داشتن Garbage Collection (جمع‌آوری زباله) باعث می‌شود که مدیریت حافظه ساده‌تر و مؤثرتر باشد، هرچند که این ویژگی ممکن است در برخی مواقع سرعت پردازش را کاهش دهد.
  • اجرا و عملکرد:
    • Go کدهای کامپایل‌شده را به‌صورت باینری اجرا می‌کند که این امر باعث می‌شود که سرعت اجرای آن نسبت به زبان‌هایی مثل Python و Ruby بیشتر باشد. با این حال، از زبان‌هایی مانند C++ و Rust کندتر است.
  • مناسب برای شبکه‌های توزیع‌شده:
    • یکی از دلایل انتخاب Go برای Cosmos SDK این است که این زبان به‌طور خاص برای توسعه سیستم‌های توزیع‌شده و شبکه‌ای طراحی شده و دارای کتابخانه‌های داخلی برای مدیریت درخواست‌ها، پروتکل‌های شبکه‌ای و API‌ها است.

2. زبان برنامه‌نویسی Rust در Substrate

Rust یک زبان برنامه‌نویسی سیستمی و سطح پایین است که بر روی عملکرد، ایمنی و هم‌زمانی تأکید دارد. این زبان به‌طور خاص برای سیستم‌های پیچیده، امن و با کارایی بالا طراحی شده است و برای توسعه بلاکچین‌ها در Substrate به‌کار می‌رود.

  • امنیت و جلوگیری از خطاها:
    • Rust به‌عنوان یک زبان امن شناخته می‌شود و یکی از اصلی‌ترین ویژگی‌های آن سیستم مالکیت حافظه است که به‌طور خودکار از بروز مشکلات رایج در مدیریت حافظه مانند دسترسی به حافظه آزاد شده و شرایط رقابتی جلوگیری می‌کند. این ویژگی برای توسعه بلاکچین‌ها بسیار حیاتی است، چرا که امنیت بلاکچین نیازمند دقت و کنترل دقیق بر منابع سیستم است.
    • Rust همچنین ابزارهای قدرتمندی برای بررسی نوع داده‌ها و اطمینان از صحت عملکرد کد فراهم می‌آورد که باعث می‌شود توسعه‌دهندگان از وقوع بسیاری از خطاهای رایج جلوگیری کنند.
  • کارایی بالا:
    • Rust به دلیل کدنویسی به‌صورت کامپایل‌شده به کد ماشین، دارای عملکرد بسیار بالا و کارایی بهینه است. این زبان به‌خصوص برای برنامه‌هایی که نیاز به پردازش‌های پیچیده یا عملکرد بالا دارند، بسیار مناسب است.
    • در مقایسه با Go، Rust به‌طور کلی عملکرد بالاتری دارد، چرا که فاقد Garbage Collection است و از مدیریت حافظه دستی بهره می‌برد. این ویژگی باعث می‌شود که Rust برای پروژه‌های حساس به عملکرد مانند بلاکچین‌ها انتخابی عالی باشد.
  • مقیاس‌پذیری و هم‌زمانی:
    • Rust برای توسعه برنامه‌هایی که نیاز به پردازش‌های هم‌زمان و مقیاس‌پذیر دارند، بسیار مناسب است. این زبان به توسعه‌دهندگان این امکان را می‌دهد که به راحتی پردازش‌های هم‌زمان و موازی را مدیریت کنند و برنامه‌هایی با عملکرد بالا بسازند.
    • Substrate از این ویژگی‌ها برای ساخت بلاکچین‌های مقیاس‌پذیر و قابل اطمینان بهره می‌برد.
  • یادگیری و پیچیدگی:
    • Rust نسبت به Go پیچیده‌تر است و دارای منحنی یادگیری تندتری می‌باشد. این زبان به‌ویژه برای توسعه‌دهندگان مبتدی ممکن است چالش‌برانگیز باشد زیرا مفاهیمی مانند مالکیت حافظه، قرضی‌داری (Borrowing) و مراجع متغیر برای درک نیازمند تمرین هستند.
    • با این حال، ویژگی‌های امنیتی و عملکرد بالای آن، Rust را برای پروژه‌های پیچیده و حساس به عملکرد به یک انتخاب عالی تبدیل می‌کند.

3. مقایسه Go و Rust در توسعه بلاکچین

ویژگی Go (در Cosmos SDK) Rust (در Substrate)
سادگی و یادگیری سینتکس ساده و یادگیری سریع پیچیدگی بیشتر و منحنی یادگیری تند
امنیت امنیت پایین‌تر نسبت به Rust (با وجود Garbage Collection) امنیت بالا به‌خصوص در زمینه مدیریت حافظه و جلوگیری از خطاها
عملکرد سرعت متوسط، مناسب برای پروژه‌های مقیاس‌پذیر عملکرد بالا و بهینه، انتخابی عالی برای پروژه‌های حساس به عملکرد
مدیریت حافظه استفاده از Garbage Collection (ممکن است در برخی موارد کند شود) مدیریت دستی حافظه با سیستم مالکیت حافظه
مقیاس‌پذیری و هم‌زمانی مقیاس‌پذیری بالا و قابلیت هم‌زمانی خوب مقیاس‌پذیری عالی و پشتیبانی از پردازش‌های هم‌زمان پیچیده
مناسب برای توسعه بلاکچین مناسب برای ساخت بلاکچین‌های سریع و مقیاس‌پذیر مناسب برای ساخت بلاکچین‌های پیچیده و حساس به عملکرد

جمع بندی

در نهایت، Go و Rust هرکدام ویژگی‌های خاص خود را دارند که می‌تواند بر اساس نیازهای پروژه انتخاب شود. Go به‌خاطر سادگی و سهولت در یادگیری برای پروژه‌هایی که نیاز به توسعه سریع دارند، مناسب است. در مقابل، Rust به‌خاطر امنیت و عملکرد بالای خود برای توسعه بلاکچین‌های پیچیده و حساس به عملکرد ترجیح داده می‌شود. برای پروژه‌هایی که مقیاس‌پذیری و کارایی بالا نیاز دارند، Rust گزینه‌ای عالی است، در حالی که برای توسعه‌دهندگانی که به دنبال سادگی و سرعت در توسعه هستند، Go گزینه بهتری است.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. بررسی پروژه‌های موفق پیاده‌سازی‌شده با Cosmos و Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”پروژه‌های مطرح مبتنی بر Cosmos SDK (مانند Binance Chain، Terra، Osmosis)” subtitle=”توضیحات کامل”]Cosmos SDK یک فریمورک قدرتمند برای توسعه بلاکچین‌های سفارشی و مقیاس‌پذیر است که توسط بسیاری از پروژه‌های معتبر برای ساخت بلاکچین‌های مستقل استفاده شده است. در این بخش، به بررسی چند پروژه مهم ساخته‌شده بر اساس Cosmos SDK خواهیم پرداخت.

1. Binance Chain

Binance Chain بلاکچینی است که توسط صرافی Binance برای تسهیل تراکنش‌های سریع و مقیاس‌پذیر ایجاد شده است. این بلاکچین به‌ویژه برای انجام معاملات سریع و کارآمد در بازار ارزهای دیجیتال و ایجاد توکن‌های BEP-2 استفاده می‌شود.

  • هدف و ویژگی‌ها:
    • Binance Chain به‌منظور پشتیبانی از معاملات در اکوسیستم Binance طراحی شده و برای تبادل سریع و کارآمد ارزهای دیجیتال به کار می‌رود.
    • این بلاکچین از Tendermint Core به‌عنوان موتور اجماع استفاده می‌کند و می‌تواند تراکنش‌های زیادی را با سرعت بالا پردازش کند.
    • ویژگی مهم دیگر این بلاکچین امکان ساخت توکن‌های BEP-2 است که به‌راحتی می‌توانند در اکوسیستم Binance مورد استفاده قرار گیرند.
  • پیکربندی و تنظیمات: در Binance Chain، برای راه‌اندازی یک نود و تعامل با شبکه باید از Cosmos SDK و تنظیمات خاص آن استفاده کرد. برای مثال، اگر بخواهیم یک نود از Binance Chain را راه‌اندازی کنیم، تنظیمات اولیه آن به‌صورت زیر خواهد بود:
    1. نصب Go و Cosmos SDK:
      sudo apt-get install golang
      git clone https://github.com/cosmos/cosmos-sdk.git
      cd cosmos-sdk
      make
      
    2. تنظیم فایل کانفیگ نود: مسیر فایل کانفیگ:
      /home/user/.cosmos/config/config.toml
      

      در این فایل باید تنظیماتی مانند پورت‌ها و تنظیمات امنیتی را پیکربندی کنید.

2. Terra

Terra بلاکچینی است که تمرکز اصلی آن بر روی استیبل‌کوین‌ها و DeFi است. این پروژه با استفاده از Cosmos SDK بلاکچینی ایجاد کرده که از مقیاس‌پذیری بالایی برخوردار است و می‌تواند پرداخت‌های جهانی را تسهیل کند.

  • هدف و ویژگی‌ها:
    • Terra هدف دارد که استیبل‌کوین‌هایی با پشتوانه ارز دیجیتال را برای استفاده در پرداخت‌های جهانی عرضه کند.
    • این پروژه به‌طور ویژه به ایجاد استیبل‌کوین‌های مبتنی بر LUNA و UST پرداخته است که برای تسهیل تراکنش‌های جهانی و فعالیت‌های DeFi استفاده می‌شود.
  • پیکربندی و تنظیمات: برای راه‌اندازی نود در بلاکچین Terra، به‌طور مشابه با Binance Chain از Cosmos SDK استفاده می‌شود. تنظیمات مربوطه در فایل‌های کانفیگ به‌صورت زیر خواهد بود:
    1. نصب Go و Cosmos SDK:
      sudo apt-get install golang
      git clone https://github.com/terra-money/core.git
      cd core
      make install
      
    2. تنظیم فایل‌های کانفیگ: مسیر فایل کانفیگ برای Terra به‌طور معمول در مسیر زیر قرار دارد:
      /home/user/.terra/config/config.toml
      

3. Osmosis

Osmosis یک صرافی غیرمتمرکز است که در اکوسیستم Cosmos فعالیت می‌کند. این صرافی از مدل AMM (Automated Market Maker) برای تسهیل تبادل ارزهای دیجیتال استفاده می‌کند.

  • هدف و ویژگی‌ها:
    • Osmosis به‌عنوان یک صرافی غیرمتمرکز، امکان تبادل ارزهای دیجیتال مختلف را بدون نیاز به واسطه فراهم می‌آورد.
    • این پروژه از IBC (Inter-Blockchain Communication) برای تعامل بین زنجیره‌ای استفاده می‌کند که یکی از ویژگی‌های اصلی Cosmos SDK است.
  • پیکربندی و تنظیمات: برای راه‌اندازی نود Osmosis، تنظیمات خاصی لازم است. پس از نصب Go و Cosmos SDK، مراحل زیر باید انجام شود:
    1. نصب Osmosis:
      git clone https://github.com/osmosis-labs/osmosis.git
      cd osmosis
      make install
      
    2. تنظیمات مربوط به فایل کانفیگ نود: مسیر فایل کانفیگ در Osmosis معمولاً به‌صورت زیر خواهد بود:
      /home/user/.osmosis/config/config.toml
      

جمع بندی

پروژه‌های مبتنی بر Cosmos SDK همچون Binance Chain، Terra و Osmosis نمایانگر قدرت این فریمورک در ایجاد بلاکچین‌های مستقل و مقیاس‌پذیر هستند. این پروژه‌ها از ویژگی‌های اصلی Cosmos SDK نظیر Tendermint و IBC بهره می‌برند تا بلاکچین‌هایی سریع، امن و مقیاس‌پذیر ایجاد کنند. در حالی که Binance Chain به‌عنوان یک بلاکچین برای تبادل ارزهای دیجیتال در اکوسیستم Binance شناخته می‌شود، Terra بر روی استیبل‌کوین‌ها و پروژه‌های DeFi متمرکز است و Osmosis به‌عنوان یک صرافی غیرمتمرکز از ویژگی‌های IBC برای تعامل بین زنجیره‌ها استفاده می‌کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”پروژه‌های موفق ساخته‌شده با Substrate (مانند Moonbeam، Acala، Phala)” subtitle=”توضیحات کامل”]Substrate یکی از قدرتمندترین فریمورک‌ها برای ساخت بلاکچین‌های سفارشی است که توسط Parity Technologies توسعه یافته است. این فریمورک به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های خود را با استفاده از معماری FRAME و Pallets بسازند. در این بخش، به بررسی برخی از پروژه‌های موفق که با استفاده از Substrate ساخته شده‌اند، خواهیم پرداخت.

1. Moonbeam

Moonbeam یکی از بلاکچین‌های معروف ساخته‌شده با استفاده از Substrate است که به‌طور ویژه برای پشتیبانی از قراردادهای هوشمند در شبکه Polkadot طراحی شده است. Moonbeam با هدف ارائه یک محیط توسعه مشابه به Ethereum، این امکان را برای توسعه‌دهندگان فراهم می‌آورد که بدون نیاز به تغییر کدهای موجود خود، از قراردادهای هوشمند در شبکه Polkadot استفاده کنند.

  • هدف و ویژگی‌ها:
    • Moonbeam به‌طور خاص برای کسانی طراحی شده است که می‌خواهند از مزایای Polkadot استفاده کنند، اما به برنامه‌های موجود خود در Ethereum ادامه دهند.
    • از قابلیت‌های کلیدی آن می‌توان به EVM (Ethereum Virtual Machine) و Substrate اشاره کرد که به توسعه‌دهندگان امکان می‌دهد قراردادهای هوشمند Solidity را در این شبکه پیاده‌سازی کنند.
    • Moonbeam از ویژگی XCM (Cross-Chain Message Passing) برای تعامل با دیگر بلاکچین‌ها در اکوسیستم Polkadot استفاده می‌کند.
  • پیکربندی و تنظیمات: برای راه‌اندازی یک نود Moonbeam، ابتدا باید Substrate را نصب کرده و سپس تنظیمات خاص Moonbeam را اعمال کرد.
    1. نصب Moonbeam:
      git clone https://github.com/PureStake/moonbeam.git
      cd moonbeam
      make build
      
    2. تنظیم فایل کانفیگ نود: مسیر فایل کانفیگ معمولاً به‌صورت زیر است:
      /home/user/.moonbeam/config/config.toml
      

2. Acala

Acala یک پروژه بلاکچین مبتنی بر Substrate است که به‌منظور ایجاد یک پلتفرم مالی غیرمتمرکز و چنددارایی در اکوسیستم Polkadot طراحی شده است. این پلتفرم هدف دارد تا استیبل‌کوین‌ها، وام‌دهی، و محصولات مالی دیگر را به‌طور غیرمتمرکز در اختیار کاربران قرار دهد.

  • هدف و ویژگی‌ها:
    • Acala در پی ایجاد یک اکوسیستم مالی غیرمتمرکز با استیبل‌کوین‌های aUSD است که می‌تواند در معاملات و پروژه‌های DeFi استفاده شود.
    • این پروژه از Polkadot برای تعامل با دیگر بلاکچین‌ها و استفاده از ویژگی‌های آن بهره می‌برد.
    • Acala همچنین از فناوری Cross-Chain برای امکان تبادل و تعامل بین بلاکچین‌ها استفاده می‌کند.
  • پیکربندی و تنظیمات: برای راه‌اندازی نود Acala، از Substrate و تنظیمات خاص آن استفاده می‌شود.
    1. نصب Acala:
      git clone https://github.com/AcalaNetwork/acala.git
      cd acala
      make install
      
    2. تنظیمات مربوط به فایل کانفیگ: مسیر فایل کانفیگ برای Acala به‌طور معمول در مسیر زیر قرار دارد:
      /home/user/.acala/config/config.toml
      

3. Phala Network

Phala Network یک پروژه بلاکچین مبتنی بر Substrate است که به‌طور خاص برای محافظت از حریم خصوصی داده‌ها در اکوسیستم بلاکچین طراحی شده است. این پروژه از Trusted Execution Environments (TEE) برای پردازش داده‌ها به‌صورت محرمانه و غیرقابل دسترسی استفاده می‌کند.

  • هدف و ویژگی‌ها:
    • Phala با استفاده از TEE به کاربران این امکان را می‌دهد که داده‌ها و قراردادهای هوشمند خود را به‌صورت کاملاً خصوصی اجرا کنند.
    • این پروژه برای کاربردهایی همچون قراردادهای هوشمند مالی، تحلیل داده‌ها، و غیره طراحی شده است که نیاز به حفظ حریم خصوصی دارند.
    • Phala از Substrate و ویژگی‌های آن همچون Pallets و FRAME برای ساخت بلاکچین‌های خود استفاده کرده است.
  • پیکربندی و تنظیمات: راه‌اندازی نود در Phala نیازمند نصب Substrate و تنظیمات خاص است. برای راه‌اندازی این نود، مراحل زیر را دنبال کنید:
    1. نصب Phala:
      git clone https://github.com/Phala-Network/phala-blockchain.git
      cd phala-blockchain
      make install
      
    2. تنظیمات کانفیگ برای Phala: مسیر فایل کانفیگ به‌طور معمول به‌صورت زیر خواهد بود:
      /home/user/.phala/config/config.toml
      

جمع بندی

پروژه‌های مبتنی بر Substrate مانند Moonbeam، Acala و Phala Network نشان‌دهنده قابلیت‌های بالای این فریمورک در ساخت بلاکچین‌های سفارشی با ویژگی‌های خاص هستند. Moonbeam به‌طور خاص برای اتصال به شبکه Ethereum و ارائه قابلیت‌های مشابه با آن در اکوسیستم Polkadot طراحی شده است. Acala به‌عنوان یک پلتفرم مالی غیرمتمرکز، قابلیت‌های مالی پیشرفته‌ای را برای کاربران فراهم می‌آورد و از Polkadot برای تعامل بین بلاکچین‌ها استفاده می‌کند. Phala Network با تمرکز بر حریم خصوصی داده‌ها و استفاده از TEE، ابزاری را برای محافظت از داده‌ها در قراردادهای هوشمند ارائه می‌دهد. این پروژه‌ها تنها نمونه‌ای از کاربردهای Substrate هستند که قدرت این فریمورک در ایجاد بلاکچین‌های مقیاس‌پذیر و کاربردی را به نمایش می‌گذارند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی موارد استفاده (Use Cases) برای انتخاب Cosmos SDK یا Substrate” subtitle=”توضیحات کامل”]در دنیای بلاکچین، انتخاب فریمورک مناسب برای ساخت بلاکچین‌های سفارشی می‌تواند تأثیر زیادی بر موفقیت پروژه داشته باشد. دو فریمورک برجسته برای ساخت بلاکچین‌های سفارشی، Cosmos SDK و Substrate هستند. این فریمورک‌ها با ویژگی‌ها و معماری‌های منحصر به فرد خود، انتخاب مناسب‌ترین گزینه را به عوامل مختلفی بستگی دارد.

در این بخش، به بررسی موارد استفاده مختلف و شرایطی که در آن‌ها استفاده از Cosmos SDK یا Substrate توصیه می‌شود، خواهیم پرداخت.

1. اگر هدف شما ایجاد یک بلاکچین با قابلیت تعامل میان زنجیره‌ای است

  • Cosmos SDK:
    • مناسب برای: اگر هدف شما ایجاد یک بلاکچین با قابلیت تعامل میان زنجیره‌ای (Cross-Chain) است، Cosmos SDK به‌ویژه برای شما مناسب است. این فریمورک از پروتکل IBC (Inter-Blockchain Communication) پشتیبانی می‌کند که امکان تعامل میان بلاکچین‌های مختلف را به‌صورت ایمن و بدون واسطه فراهم می‌کند.
    • موارد استفاده: پروژه‌هایی که نیاز به ارتباط با سایر بلاکچین‌ها دارند، مانند سیستم‌های مالی غیرمتمرکز (DeFi)، شبکه‌های اجتماعی بلاکچین‌محور یا پلتفرم‌های اشتراک‌گذاری داده.

    مثال‌ها:

    • پروژه‌هایی مانند Osmosis که به‌طور خاص برای ایجاد یک صرافی غیرمتمرکز میان بلاکچین‌ها از Cosmos SDK و IBC استفاده می‌کنند.
    • Akash Network که از Cosmos SDK برای ایجاد یک پلتفرم رایانش ابری غیرمتمرکز با تعامل میان بلاکچین‌های مختلف استفاده کرده است.
  • Substrate:
    • مناسب برای: در صورتی که نیاز دارید تا بلاکچینی را بسازید که بتواند با اکوسیستم Polkadot و بلاکچین‌های مختلف در آن تعامل داشته باشد، Substrate می‌تواند انتخاب مناسبی باشد. از آنجا که Substrate به شما امکان می‌دهد بلاکچین‌های خاص خود را بسازید که می‌توانند به راحتی با شبکه Polkadot تعامل داشته باشند، این فریمورک برای ایجاد پروژه‌هایی با نیاز به تعاملات پیچیده میان بلاکچین‌ها کاربرد دارد.
    • موارد استفاده: بلاکچین‌های خاص و با قابلیت اتصال به Polkadot و شبکه‌های Parachain آن.

    مثال‌ها:

    • Moonbeam که از Substrate برای ارائه قراردادهای هوشمند بر اساس Ethereum در اکوسیستم Polkadot استفاده می‌کند.
    • Phala Network که با استفاده از Substrate برای ارائه راه‌حل‌های حریم خصوصی مبتنی بر TEE طراحی شده است.

2. اگر شما به دنبال ساخت یک بلاکچین کاملاً سفارشی هستید

  • Cosmos SDK:
    • مناسب برای: Cosmos SDK به‌ویژه برای ساخت بلاکچین‌های با نیازهای خاص، مانند پروژه‌های غیرمتمرکز که فقط نیاز به ویژگی‌های خاصی از یک بلاکچین دارند، مانند حکمرانی، انتقال دارایی‌ها یا توکن‌ها، طراحی شده است. این فریمورک امکانات خوبی برای توسعه و سفارشی‌سازی بلاکچین‌ها به‌ویژه با استفاده از Modules دارد.
    • موارد استفاده: پروژه‌های مختلف مانند شبکه‌های مالی، بازی‌های بلاکچینی، شبکه‌های داده و هر پروژه‌ای که نیاز به راه‌اندازی بلاکچین با مشخصات خاص داشته باشد.

    مثال‌ها:

    • Terra که از Cosmos SDK برای ایجاد بلاکچینی با استیبل‌کوین‌ها و قابلیت تعامل میان زنجیره‌ای استفاده می‌کند.
    • Binance Chain که از Cosmos SDK برای ایجاد یک بلاکچین بسیار سریع و کارآمد برای صرافی Binance ساخته شده است.
  • Substrate:
    • مناسب برای: اگر نیاز دارید تا یک بلاکچین با معماری پیچیده و ساختار گسسته بسازید که امکان تعامل با Polkadot را داشته باشد، Substrate مناسب‌ترین گزینه است. این فریمورک به شما امکان می‌دهد تا به راحتی Pallets و Runtime خود را تعریف کرده و به‌طور کامل بلاکچین خود را سفارشی‌سازی کنید.
    • موارد استفاده: پروژه‌هایی که به معماری پیچیده نیاز دارند، مانند بلاکچین‌های خصوصی، پروژه‌های DeFi، و پروتکل‌های خصوصی.

    مثال‌ها:

    • Acala که از Substrate برای ایجاد یک اکوسیستم مالی غیرمتمرکز و چنددارایی استفاده کرده است.
    • Polkadot و Kusama که از Substrate برای ایجاد اکوسیستم‌های بلاکچینی با قابلیت‌های خاص مانند Parachain استفاده می‌کنند.

3. اگر به دنبال ساخت بلاکچین با قابلیت حاکمیت و مقیاس‌پذیری بالا هستید

  • Cosmos SDK:
    • مناسب برای: Cosmos SDK به شما این امکان را می‌دهد که با استفاده از ماژول‌های آماده، بلاکچینی با مقیاس‌پذیری بالا و قابلیت حکمرانی قوی بسازید. این فریمورک برای ایجاد بلاکچین‌های با نیاز به حکمرانی و تصمیم‌گیری‌های غیرمتمرکز مناسب است.
    • موارد استفاده: پروژه‌هایی که به مقیاس‌پذیری بالا و قابلیت مدیریت پیچیده نیاز دارند، مانند بلاکچین‌های مالی و پلتفرم‌های حکمرانی.

    مثال‌ها:

    • Cosmos Hub که به‌عنوان هاب اصلی شبکه Cosmos برای تعامل بین زنجیره‌ای طراحی شده است.
    • Osmosis که از Cosmos SDK برای ایجاد صرافی غیرمتمرکز با قابلیت حکمرانی استفاده می‌کند.
  • Substrate:
    • مناسب برای: در صورتی که نیاز به ساخت بلاکچین‌هایی با مقیاس‌پذیری بالا و پروتکل‌های پیچیده داشته باشید، Substrate می‌تواند برای شما مناسب باشد. Substrate به شما این امکان را می‌دهد که Runtime و Pallets خود را به‌طور کامل سفارشی کرده و قابلیت‌های مورد نیاز برای مقیاس‌پذیری را اضافه کنید.
    • موارد استفاده: پروژه‌های با نیاز به حکمرانی و مقیاس‌پذیری بالا، به‌ویژه در اکوسیستم‌های Polkadot.

    مثال‌ها:

    • Polkadot که به‌طور ویژه برای مقیاس‌پذیری بالا و تعامل میان بلاکچین‌ها ساخته شده است.
    • Kusama که برای آزمایش پروژه‌های مختلف با مقیاس‌پذیری بالا و حکمرانی غیرمتمرکز استفاده می‌شود.

4. اگر به دنبال توسعه سریع و راحت هستید

  • Cosmos SDK:
    • مناسب برای: اگر به دنبال یک راه‌حل سریع و ساده برای ساخت بلاکچین هستید که امکان توسعه سریع و استفاده از ماژول‌های آماده را داشته باشد، Cosmos SDK می‌تواند گزینه مناسبی باشد. این فریمورک دارای مستندات جامع و ماژول‌های آماده است که به شما کمک می‌کند پروژه خود را سریع‌تر راه‌اندازی کنید.

    مثال‌ها:

    • Terra که به‌عنوان یک استیبل‌کوین غیرمتمرکز با استفاده از Cosmos SDK توسعه داده شده است.
  • Substrate:
    • مناسب برای: اگر به توسعه‌ای بیشتر و پیچیده‌تر نیاز دارید که به سفارشی‌سازی‌های پیشرفته و امکانات خاص نیاز دارد، Substrate گزینه بهتری است. این فریمورک به شما آزادی بیشتری برای ساخت بلاکچین خود می‌دهد.

    مثال‌ها:

    • Acala که از Substrate برای توسعه یک پلتفرم مالی پیچیده استفاده کرده است.

جمع بندی

انتخاب بین Cosmos SDK و Substrate بستگی به نیازهای خاص پروژه دارد. اگر هدف شما تعامل میان بلاکچین‌ها و استفاده از پروتکل‌های ارتباطی میان زنجیره‌ای است، Cosmos SDK به‌ویژه با قابلیت IBC می‌تواند بهترین گزینه باشد. از سوی دیگر، اگر نیاز به سفارشی‌سازی‌های پیچیده، مقیاس‌پذیری بالا و ارتباط با اکوسیستم Polkadot دارید، Substrate بهترین انتخاب است. هر دو فریمورک دارای ویژگی‌های منحصر به فردی هستند که می‌توانند پروژه‌های بلاکچینی را با نیازهای مختلف پشتیبانی کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”چالش‌ها و فرصت‌های استفاده از این فریمورک‌ها در توسعه بلاکچین‌های سفارشی” subtitle=”توضیحات کامل”]با توجه به اینکه Cosmos SDK و Substrate هر دو فریمورک‌های قدرتمندی برای توسعه بلاکچین‌های سفارشی هستند، انتخاب میان این دو فریمورک به عوامل مختلفی بستگی دارد. هر یک از این فریمورک‌ها مزایا و چالش‌های خاص خود را دارند که در این بخش به بررسی آن‌ها خواهیم پرداخت.

1. چالش‌های استفاده از Cosmos SDK

  • محدودیت‌های توسعه بلاکچین‌های بسیار سفارشی:
    • چالش: اگرچه Cosmos SDK امکان توسعه بلاکچین‌های سفارشی را فراهم می‌کند، اما ممکن است در برخی موارد که نیاز به ویژگی‌های خاص و پیچیده‌تر دارید، این فریمورک محدودیت‌هایی ایجاد کند. به‌خصوص اگر به توسعه ویژگی‌هایی که فراتر از ماژول‌های موجود باشد نیاز داشته باشید، ممکن است مجبور شوید تغییرات زیادی در کدها ایجاد کنید.
    • فرصت: با توجه به مستندات کامل و جامعه فعال، می‌توان مشکلات را شناسایی و سریع‌تر برطرف کرد.
  • وابستگی به IBC برای تعامل میان زنجیره‌ای:
    • چالش: اگرچه IBC (Inter-Blockchain Communication) برای ارتباط بین زنجیره‌ها مفید است، اما این پروتکل هنوز در حال توسعه و به‌روزرسانی است و ممکن است مشکلات مقیاس‌پذیری و پیچیدگی در برخی از ارتباطات بین زنجیره‌ای ایجاد شود.
    • فرصت: با تکامل IBC، فرصت‌هایی برای تعامل بین بلاکچین‌های مختلف به‌صورت ایمن و کارآمد ایجاد خواهد شد که می‌تواند زمینه‌ساز نوآوری‌های بیشتر در اکوسیستم بلاکچین شود.
  • مقیاس‌پذیری و عملکرد:
    • چالش: Cosmos SDK به‌طور کلی برای بلاکچین‌هایی با مقیاس‌پذیری متوسط طراحی شده است. در حالی که IBC امکان ارتباط میان بلاکچین‌ها را فراهم می‌آورد، برای بلاکچین‌هایی با بار زیاد و درخواست‌های مقیاس‌پذیری بالا ممکن است به چالش‌هایی از جمله تاخیر در ارسال داده‌ها و مصرف زیاد منابع برخورد کنید.
    • فرصت: با بهینه‌سازی‌های مستمر در پروتکل‌ها و افزودن قابلیت‌های جدید، مقیاس‌پذیری بهبود خواهد یافت.

2. چالش‌های استفاده از Substrate

  • پیچیدگی بیشتر در سفارشی‌سازی:
    • چالش: یکی از ویژگی‌های برجسته Substrate قابلیت سفارشی‌سازی بالای آن است. این قابلیت به شما این امکان را می‌دهد که تمامی جنبه‌های بلاکچین خود را سفارشی‌سازی کنید، اما همین ویژگی می‌تواند باعث پیچیدگی در طراحی و توسعه بلاکچین شود. اگر تیم توسعه‌دهنده شما تجربه کافی در برنامه‌نویسی Rust و معماری‌های بلاکچینی ندارد، ممکن است با مشکلاتی در این زمینه مواجه شوید.
    • فرصت: با استفاده از Pallets و ماژول‌های قابل سفارشی‌سازی، می‌توانید بلاکچین‌هایی دقیقاً مطابق با نیاز خود بسازید که انعطاف‌پذیری بالایی دارند.
  • وابستگی به اکوسیستم Polkadot:
    • چالش: اگرچه Substrate برای ساخت بلاکچین‌های سفارشی بسیار مناسب است، اما برای بهره‌مندی کامل از قابلیت‌های آن، ممکن است نیاز به ادغام با شبکه Polkadot داشته باشید. این وابستگی می‌تواند برای پروژه‌هایی که نمی‌خواهند وابسته به اکوسیستم خاصی باشند، مشکل‌ساز باشد.
    • فرصت: به دلیل پشتیبانی از Polkadot و قابلیت اتصال به Parachains، می‌توانید از مقیاس‌پذیری و تعاملات بین بلاکچین‌های مختلف بهره‌مند شوید.
  • پشتیبانی و جامعه کاربری:
    • چالش: در مقایسه با Cosmos SDK که جامعه فعال‌تری دارد، Substrate به دلیل پیچیدگی‌های خود و نسبتاً جدید بودن، ممکن است جامعه کوچکتری داشته باشد. این موضوع می‌تواند مشکلاتی در یافتن منابع و راه‌حل‌ها برای مشکلات مختلف ایجاد کند.
    • فرصت: Substrate به دلیل ارتباط نزدیک با Polkadot، با سرعت در حال رشد است و به‌ویژه در زمینه استفاده از Parachains و قابلیت‌های نوآورانه بلاکچین‌های چندگانه، فرصت‌های زیادی دارد.

3. فرصت‌های استفاده از Cosmos SDK

  • تعامل و ارتباط بین زنجیره‌ها (IBC):
    • فرصت: یکی از بزرگ‌ترین مزایای Cosmos SDK، امکان ارتباط مستقیم و ایمن میان بلاکچین‌های مختلف از طریق IBC است. این ویژگی می‌تواند فرصت‌های زیادی برای پروژه‌هایی فراهم کند که به دنبال ایجاد یک اکوسیستم پیچیده از بلاکچین‌های مستقل هستند.
  • ماژول‌های آماده و سفارشی‌سازی آسان:
    • فرصت: استفاده از ماژول‌های آماده در Cosmos SDK (مانند Bank، Staking، Governance) این امکان را فراهم می‌کند که توسعه‌دهندگان بلاکچین‌های خاص خود را به‌سرعت راه‌اندازی کنند. این ماژول‌ها به راحتی قابل سفارشی‌سازی و گسترش هستند.
  • جامعه بزرگ و مستندات قوی:
    • فرصت: با وجود مستندات جامع و جامعه فعال، توسعه‌دهندگان می‌توانند به راحتی مشکلات خود را حل کنند و از تجربیات دیگران بهره‌برداری کنند.

4. فرصت‌های استفاده از Substrate

  • انعطاف‌پذیری در ساخت بلاکچین‌های سفارشی:
    • فرصت: Substrate به شما این امکان را می‌دهد که تمام جنبه‌های بلاکچین خود را از جمله حکمرانی، اجماع و فرآیندهای اجرایی سفارشی‌سازی کنید. این امکان به توسعه‌دهندگان این فرصت را می‌دهد که بلاکچین‌هایی بسیار خاص و متناسب با نیازهای پروژه‌های خود بسازند.
  • ادغام با Polkadot و قابلیت مقیاس‌پذیری:
    • فرصت: استفاده از Polkadot به عنوان شبکه زیرساختی برای بلاکچین‌های ساخته‌شده با Substrate، می‌تواند مقیاس‌پذیری بالا و قابلیت‌های تعامل بین بلاکچین‌ها را فراهم آورد.
  • پشتیبانی از Parachains:
    • فرصت: اگر هدف شما ایجاد بلاکچینی است که می‌تواند به‌صورت مستقل از دیگر بلاکچین‌ها عمل کرده و در عین حال از مزایای شبکه‌های دیگر بهره‌برداری کند، Substrate با قابلیت پشتیبانی از Parachains این فرصت را فراهم می‌آورد.

جمع بندی

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

انتخاب فریمورک مناسب به نیازهای خاص پروژه، تیم توسعه‌دهنده و اهداف درازمدت پروژه بستگی دارد.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش ۲: شروع کار با Cosmos SDK”][cdb_course_lesson title=”فصل 1. نصب و راه‌اندازی محیط توسعه Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”پیش‌نیازهای نصب (Go، Node.js، Docker، Rust)” subtitle=”توضیحات کامل”]برای شروع کار با Cosmos SDK و Substrate، باید برخی از ابزارهای پیش‌نیاز را نصب کنید. در این بخش، به توضیح هرکدام از این ابزارها و نحوه نصب آن‌ها خواهیم پرداخت.

۱. نصب Go (برای Cosmos SDK)

Cosmos SDK از زبان Go برای توسعه استفاده می‌کند. در اینجا نحوه نصب Go روی سیستم‌عامل‌های مختلف توضیح داده شده است.

  1. ابتدا، برای نصب Go، به صفحه دانلود Go مراجعه کنید و نسخه مناسب سیستم‌عامل خود را انتخاب کنید.
  2. پس از دانلود، برای نصب Go، دستور زیر را در ترمینال وارد کنید:
    • برای سیستم‌عامل‌های لینوکس و macOS:
      sudo tar -C /usr/local -xzf go1.16.4.linux-amd64.tar.gz
      
    • برای ویندوز: فایل .msi را دانلود کرده و مراحل نصب را طی کنید.
  3. سپس، مسیر Go را به متغیر محیطی PATH اضافه کنید. برای این کار، فایل ~/.bash_profile یا ~/.bashrc را باز کرده و خط زیر را اضافه کنید:
    export PATH=$PATH:/usr/local/go/bin
    
  4. برای اطمینان از نصب صحیح Go، دستور زیر را وارد کنید:
    go version
    

مسیر فایل: /usr/local/go

۲. نصب Node.js (برای Polkadot Substrate)

Node.js برای توسعه و اجرای پروژه‌های مبتنی بر JavaScript و TypeScript مورد نیاز است. برای نصب آن:

  1. به سایت Node.js مراجعه کرده و نسخه LTS را دانلود کنید.
  2. در ترمینال، دستور زیر را برای نصب Node.js و npm وارد کنید:
    • برای لینوکس و macOS:
      sudo apt install nodejs
      sudo apt install npm
      
    • برای ویندوز: نصب‌کننده را دانلود کرده و نصب کنید.
  3. برای بررسی نسخه‌های نصب‌شده، دستور زیر را وارد کنید:
    node -v
    npm -v
    

مسیر فایل: /usr/local/bin/node

۳. نصب Docker (برای اجرای محیط‌های مجازی)

Docker ابزار حیاتی برای اجرای محفظه‌های (containers) مجازی است. برای نصب Docker:

  1. برای نصب Docker، به صفحه دانلود Docker مراجعه کنید و نسخه مناسب سیستم‌عامل خود را انتخاب کنید.
  2. برای نصب Docker در لینوکس، دستور زیر را وارد کنید:
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
  3. برای بررسی نصب Docker:
    docker --version
    

مسیر فایل: /usr/local/bin/docker

۴. نصب Rust (برای Substrate)

Rust برای توسعه بلاکچین‌های مبتنی بر Substrate به کار می‌رود. برای نصب آن:

  1. برای نصب Rust، دستور زیر را وارد کنید:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  2. پس از نصب، دستورات زیر را برای تنظیم محیط Rust اجرا کنید:
    source $HOME/.cargo/env
    
  3. برای بررسی نسخه Rust:
    rustc --version
    

مسیر فایل: $HOME/.cargo/bin/rustc

جمع‌بندی

در این بخش، پیش‌نیازهای نصب ابزارهای مورد نیاز برای کار با Cosmos SDK و Substrate (Go، Node.js، Docker، و Rust) را بررسی کردیم. با نصب و تنظیم صحیح این ابزارها، آماده خواهید بود تا توسعه بلاکچین‌های سفارشی را آغاز کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نصب Cosmos SDK از طریق GitHub” subtitle=”توضیحات کامل”]برای نصب Cosmos SDK، می‌توانید از طریق GitHub اقدام کنید. در این بخش، مراحل لازم برای نصب و راه‌اندازی Cosmos SDK از طریق GitHub به‌صورت گام به گام توضیح داده شده است.

۱. پیش‌نیازها

قبل از شروع نصب، باید پیش‌نیازهای زیر را نصب کرده باشید:

  • Go (نسخه 1.16 یا بالاتر)
  • Git
  • ابزارهای ساخت (Make)
۲. کلون کردن مخزن Cosmos SDK از GitHub

برای شروع، باید مخزن رسمی Cosmos SDK را از GitHub کلون کنید. برای این کار مراحل زیر را دنبال کنید:

  1. ابتدا، ترمینال را باز کنید و مسیر دلخواه برای پروژه خود را انتخاب کنید.
  2. دستور زیر را وارد کنید تا مخزن رسمی Cosmos SDK را کلون کنید:
    git clone https://github.com/cosmos/cosmos-sdk.git
    
  3. وارد دایرکتوری پروژه شوید:
    cd cosmos-sdk
    
۳. ساخت Cosmos SDK

برای ساخت Cosmos SDK از کدهای کلون‌شده، باید ابزار ساخت (Make) را نصب و استفاده کنید. دستور زیر را برای نصب Make در سیستم خود وارد کنید:

  • برای سیستم‌عامل‌های مبتنی بر Debian/Ubuntu:
    sudo apt-get install build-essential
    
  • برای سیستم‌عامل‌های macOS:اگر Homebrew را دارید، دستور زیر را وارد کنید:
    brew install make
    

پس از نصب Make، دستور زیر را وارد کنید تا Cosmos SDK ساخته شود:

make
۴. نصب Cosmos SDK به‌صورت جهانی

پس از ساخت Cosmos SDK، می‌توانید آن را به‌صورت جهانی روی سیستم خود نصب کنید. برای این کار از دستور زیر استفاده کنید:

make install

این دستور Cosmos SDK را به‌صورت جهانی در سیستم شما نصب می‌کند.

۵. بررسی نصب

برای بررسی اینکه Cosmos SDK به درستی نصب شده است، می‌توانید دستور زیر را وارد کنید:

gaiad version

اگر همه چیز به درستی نصب شده باشد، باید نسخه Cosmos SDK را مشاهده کنید.

مسیر فایل‌ها

در این فرآیند، Cosmos SDK در دایرکتوری که شما پروژه را کلون کرده‌اید، نصب می‌شود. مسیر پیش‌فرض این دایرکتوری به شکل زیر است:

~/cosmos-sdk/

جمع‌بندی

در این بخش، نحوه نصب Cosmos SDK از طریق GitHub توضیح داده شد. با کلون کردن مخزن رسمی، ساخت و نصب Cosmos SDK، شما آماده خواهید بود تا به توسعه بلاکچین‌های سفارشی با استفاده از این فریمورک قدرتمند بپردازید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”پیکربندی مسیرهای محیطی و متغیرهای موردنیاز” subtitle=”توضیحات کامل”]برای استفاده از Cosmos SDK، باید مسیرهای محیطی و متغیرهای خاصی را پیکربندی کنید تا ابزارها و دستورات به‌درستی اجرا شوند. این متغیرها به ابزارهایی مانند gaiad، gaiacli و سایر ابزارهای Cosmos SDK دسترسی می‌دهند. در این بخش، پیکربندی این متغیرها به‌طور گام به گام توضیح داده شده است.

۱. تنظیم متغیرهای محیطی برای Go

اولین قدم برای پیکربندی Cosmos SDK، تنظیم متغیرهای محیطی برای Go است. برای این کار، باید مسیر GOPATH و GOROOT را تنظیم کنید.

  1. ابتدا، مسیر نصب Go را مشخص کنید. اگر Go را طبق دستورالعمل‌های رسمی نصب کرده‌اید، به‌طور پیش‌فرض GOROOT در مسیر /usr/local/go قرار دارد.
  2. متغیر محیطی GOPATH باید به دایرکتوری که پروژه‌های Go شما در آن قرار دارند، تنظیم شود. معمولاً مسیر پیش‌فرض GOPATH در دایرکتوری ~/go است.
  3. برای تنظیم این متغیرها، فایل پیکربندی شل خود را (مثل ~/.bashrc یا ~/.zshrc بسته به شل شما) ویرایش کنید و خطوط زیر را به آن اضافه کنید:
    export GOROOT=/usr/local/go
    export GOPATH=$HOME/go
    export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
    
  4. پس از ویرایش فایل پیکربندی، تغییرات را بارگذاری کنید:
    source ~/.bashrc  # یا source ~/.zshrc
    
۲. تنظیم متغیرهای محیطی Cosmos SDK

بعد از تنظیم Go، باید متغیرهای خاص Cosmos SDK را برای کار با پروژه‌های خود پیکربندی کنید.

  1. مسیر Cosmos SDK را که در مرحله نصب تعیین کرده‌اید (مثل ~/cosmos-sdk)، به متغیر محیطی COSMOS_SDK_PATH اضافه کنید. برای این کار، به همان فایل پیکربندی شل (~/.bashrc یا ~/.zshrc) بروید و این خط را اضافه کنید:
    export COSMOS_SDK_PATH=$HOME/cosmos-sdk
    
  2. سپس فایل پیکربندی شل را دوباره بارگذاری کنید:
    source ~/.bashrc  # یا source ~/.zshrc
    
۳. پیکربندی Cosmos برای استفاده از gaiad و gaiacli

برای استفاده از دستورات gaiad و gaiacli در محیط خط فرمان، باید مسیر مربوط به این ابزارها در متغیر محیطی PATH قرار گیرد.

  1. اگر gaiad و gaiacli را به‌صورت محلی نصب کرده‌اید، این ابزارها در دایرکتوری $GOPATH/bin قرار دارند. بنابراین باید این مسیر را به PATH اضافه کنید:
    export PATH=$PATH:$GOPATH/bin
    
  2. تغییرات را دوباره بارگذاری کنید:
    source ~/.bashrc  # یا source ~/.zshrc
    
۴. بررسی تنظیمات

برای اطمینان از اینکه متغیرهای محیطی به‌درستی پیکربندی شده‌اند، دستورات زیر را اجرا کنید تا وضعیت متغیرها را بررسی کنید:

  • بررسی متغیر GOROOT:
    echo $GOROOT
    
  • بررسی متغیر GOPATH:
    echo $GOPATH
    
  • بررسی مسیر gaiad:
    which gaiad
    
۵. راه‌اندازی محیط برای توسعه

برای شروع توسعه و تعامل با Cosmos SDK، شما به یک محیط اجرایی نیاز دارید که شامل gaiad و gaiacli باشد. برای این منظور، می‌توانید از دستورات زیر استفاده کنید:

  1. برای شروع یک شبکه محلی Cosmos SDK:
    gaiad init mynode --chain-id mychain
    
  2. برای ایجاد حساب و تعامل با شبکه:
    gaiacli keys add mykey
    

مسیر فایل‌ها

  • فایل‌های پیکربندی شل معمولاً در مسیرهای زیر قرار دارند:
    • ~/.bashrc
    • ~/.zshrc
  • Cosmos SDK در مسیر پیش‌فرض ~/cosmos-sdk قرار دارد.

جمع‌بندی

در این بخش، نحوه پیکربندی متغیرهای محیطی و مسیرهای لازم برای استفاده از Cosmos SDK توضیح داده شد. با تنظیم این متغیرها و مسیرها، شما آماده خواهید بود که به‌طور مؤثر از ابزارها و دستورات Cosmos SDK استفاده کنید و توسعه بلاکچین‌های سفارشی را شروع کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی ابزار Starport و نصب آن برای توسعه سریع” subtitle=”توضیحات کامل”]Starport یک ابزار خط فرمان است که به‌طور خاص برای ساده‌سازی فرآیند ساخت و توسعه بلاکچین‌های سفارشی با استفاده از Cosmos SDK طراحی شده است. Starport به توسعه‌دهندگان کمک می‌کند تا به‌سرعت بلاکچین‌های سفارشی ایجاد کنند، ویژگی‌های جدید اضافه کنند و شبکه‌های بلاکچین را بدون نیاز به پیچیدگی‌های زیاد راه‌اندازی کنند. این ابزار با ارائه قالب‌ها، ماژول‌ها و فرمان‌های خودکار، روند توسعه را سرعت می‌بخشد.

ویژگی‌های کلیدی Starport:
  • توسعه سریع بلاکچین: با استفاده از Starport، می‌توانید به‌سرعت بلاکچین‌های سفارشی را بسازید، ویژگی‌های جدید را اضافه کنید و شبکه را برای آزمایش راه‌اندازی کنید.
  • ایجاد و مدیریت ماژول‌ها: Starport به شما اجازه می‌دهد که ماژول‌های جدید را به‌سادگی ایجاد کنید و به بلاکچین خود اضافه کنید.
  • تنظیمات پیش‌فرض و قالب‌ها: Starport یک سری تنظیمات پیش‌فرض را ارائه می‌دهد که به‌طور خودکار پیکربندی می‌شود و به شما این امکان را می‌دهد که تمرکز خود را روی منطق تجاری قرار دهید.
  • مدیریت شبکه: می‌توانید شبکه‌های خصوصی و عمومی را با ابزارهایی برای مدیریت تأسیس، ارتقا و آزمایش شبکه بسازید.
مراحل نصب Starport:

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

1. نصب پیش‌نیازها

برای استفاده از Starport، باید ابزارهایی مانند Go، Node.js و Git را نصب کنید. برای نصب این ابزارها، مراحل زیر را دنبال کنید:

نصب Go
  1. اگر Go را نصب نکرده‌اید، ابتدا نسخه مناسب آن را از وب‌سایت رسمی Go دانلود کنید:
  2. سپس دستور زیر را برای نصب Go در سیستم خود اجرا کنید:
    sudo apt update
    sudo apt install golang-go
    
  3. پس از نصب، بررسی کنید که Go به‌درستی نصب شده است:
    go version
    
نصب Git
  1. برای نصب Git، دستور زیر را در ترمینال وارد کنید:
    sudo apt update
    sudo apt install git
    
  2. پس از نصب، می‌توانید با دستور زیر بررسی کنید که Git به‌درستی نصب شده است:
    git --version
    
نصب Node.js

برای نصب Node.js، دستور زیر را در ترمینال وارد کنید:

sudo apt install nodejs
sudo apt install npm

2. نصب Starport

پس از نصب پیش‌نیازها، می‌توانید به‌راحتی Starport را نصب کنید. برای نصب Starport، از دستور go install استفاده خواهیم کرد.

  1. برای نصب Starport، دستور زیر را در ترمینال وارد کنید:
    go install github.com/tendermint/starport@latest
    
  2. پس از نصب موفق، بررسی کنید که Starport به‌درستی نصب شده است:
    starport version
    

3. استفاده از Starport برای ایجاد بلاکچین

پس از نصب Starport، می‌توانید به‌راحتی بلاکچین‌های سفارشی را ایجاد کنید. در اینجا نحوه ایجاد یک پروژه جدید با Starport توضیح داده شده است.

  1. برای ایجاد یک بلاکچین جدید با Starport، دستور زیر را وارد کنید:
    starport scaffold chain github.com/myusername/mychain
    
  2. این دستور به‌طور خودکار یک پروژه جدید با ساختار لازم برای توسعه بلاکچین با Cosmos SDK ایجاد می‌کند.

4. راه‌اندازی شبکه محلی

برای آزمایش بلاکچین خود در یک شبکه محلی، دستور زیر را وارد کنید:

starport chain serve

این دستور شبکه محلی را راه‌اندازی می‌کند و به شما این امکان را می‌دهد که بلاکچین خود را در یک محیط کنترل‌شده آزمایش کنید.

5. ایجاد ماژول‌ها و ویژگی‌های جدید

یکی از ویژگی‌های مهم Starport، امکان افزودن ماژول‌ها به بلاکچین است. به‌عنوان مثال، برای افزودن ماژولی به نام “bank”، دستور زیر را وارد کنید:

starport scaffold module bank --no-message

این دستور یک ماژول جدید به پروژه شما اضافه می‌کند. شما می‌توانید آن را ویرایش کرده و ویژگی‌های خاص خود را به آن اضافه کنید.

مسیر فایل‌ها

  • پس از نصب Starport و اجرای دستورات، فایل‌های پروژه جدید در دایرکتوری مشخص‌شده قرار می‌گیرند. به‌طور پیش‌فرض، این پروژه در مسیر github.com/myusername/mychain ایجاد می‌شود.
  • فایل‌های پیکربندی Cosmos SDK و Starport در دایرکتوری پروژه شما قرار خواهند گرفت.

جمع‌بندی

در این بخش، نحوه نصب و استفاده از ابزار Starport برای توسعه سریع بلاکچین‌های سفارشی بررسی شد. با استفاده از Starport، می‌توانید بلاکچین‌های سفارشی را به‌سرعت ایجاد و آزمایش کنید و ماژول‌های جدیدی به پروژه خود اضافه کنید. این ابزار به‌طور خاص برای تسهیل توسعه در Cosmos SDK طراحی شده است و با ارائه یک سری قالب‌ها و فرمان‌های از پیش پیکربندی‌شده، فرآیند توسعه بلاکچین را ساده‌تر می‌کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تست صحت نصب با اجرای یک بلاکچین نمونه” subtitle=”توضیحات کامل”]پس از نصب موفقیت‌آمیز Cosmos SDK و ابزارهای موردنیاز، مرحله بعدی تست صحت نصب با اجرای یک بلاکچین نمونه است. در این بخش، یک بلاکچین نمونه را راه‌اندازی خواهیم کرد و صحت نصب Cosmos SDK را بررسی می‌کنیم.

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

برای انجام این کار، از ابزار Starport استفاده خواهیم کرد که برای ایجاد بلاکچین‌های سفارشی در Cosmos SDK طراحی شده است. مراحل زیر شامل ایجاد یک پروژه جدید و راه‌اندازی شبکه محلی برای تست صحت نصب است.

1. ایجاد پروژه جدید با Starport

اولین گام برای اجرای یک بلاکچین نمونه، ایجاد یک پروژه جدید با استفاده از ابزار Starport است. در اینجا نحوه ایجاد پروژه جدید با Starport را توضیح می‌دهیم.

  1. دستور زیر را وارد کنید تا یک بلاکچین نمونه بسازید:
    starport scaffold chain github.com/myusername/mychain
    

    این دستور یک بلاکچین نمونه به نام mychain ایجاد می‌کند. شما می‌توانید نام پروژه خود را به دلخواه تغییر دهید.

  2. پس از اجرای این دستور، یک پروژه جدید در مسیر github.com/myusername/mychain ایجاد می‌شود. این پروژه شامل ساختار استاندارد Cosmos SDK و فایل‌های پیکربندی است.

2. پیکربندی شبکه محلی

برای آزمایش بلاکچین، نیاز داریم که یک شبکه محلی راه‌اندازی کنیم. با استفاده از دستور starport chain serve می‌توانیم این کار را انجام دهیم.

  1. وارد دایرکتوری پروژه‌ای که ایجاد کرده‌اید شوید:
    cd github.com/myusername/mychain
    
  2. سپس دستور زیر را برای راه‌اندازی شبکه محلی وارد کنید:
    starport chain serve
    

    این دستور شبکه محلی را راه‌اندازی کرده و یک گره (Node) بلاکچین را شروع می‌کند.

  3. در این مرحله، اگر همه چیز به‌درستی نصب و پیکربندی شده باشد، باید پیامی مشابه با این پیام مشاهده کنید:
    Starting node...
    Node started successfully
    

3. اتصال به شبکه محلی

پس از راه‌اندازی شبکه محلی، شما می‌توانید با استفاده از APIهای مختلف Cosmos SDK به شبکه خود متصل شوید و تراکنش‌ها را ارسال کنید.

  1. برای مشاهده وضعیت گره محلی، دستور زیر را وارد کنید:
    curl http://localhost:26657/status
    

    این دستور باید اطلاعات مربوط به گره محلی شما را به شما نمایش دهد.

4. ارسال تراکنش‌های نمونه

برای تست بیشتر بلاکچین و بررسی صحت نصب، می‌توانید تراکنش‌های نمونه ارسال کنید. این تراکنش‌ها به شما کمک می‌کنند تا از صحت عملکرد بلاکچین اطمینان حاصل کنید.

  1. ابتدا، یک آدرس جدید ایجاد کنید:
    starport keys add mykey
    

    این دستور یک کلید جدید به نام mykey ایجاد می‌کند.

  2. حالا می‌توانید تراکنشی ارسال کنید. برای این کار، دستور زیر را وارد کنید:
    starport tx bank send mykey cosmos1v... 100uatom --chain-id mychain
    

    این دستور یک تراکنش ارسال 100 واحد از توکن‌های uatom به آدرس مشخص‌شده (cosmos1v...) ارسال می‌کند.

مسیر فایل‌ها

  • پروژه‌ای که ایجاد کرده‌اید، در مسیر github.com/myusername/mychain قرار دارد.
  • فایل‌های پیکربندی و تنظیمات بلاکچین در این دایرکتوری ذخیره می‌شوند.
  • برای ارسال تراکنش‌ها و ارتباط با بلاکچین، از دستورات starport و curl استفاده می‌کنید.

جمع‌بندی

با اجرای دستور starport chain serve، بلاکچین نمونه شما در شبکه محلی راه‌اندازی می‌شود. این فرآیند به شما این امکان را می‌دهد که از صحت نصب Cosmos SDK و ابزارهای وابسته مطمئن شوید. همچنین، می‌توانید تراکنش‌های نمونه را ارسال کرده و عملکرد بلاکچین خود را آزمایش کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. معماری ماژولار در Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی مفهوم ماژولار در Cosmos SDK” subtitle=”توضیحات کامل”]در Cosmos SDK، مفهوم ماژولار به طراحی و معماری سیستم اشاره دارد که به شما این امکان را می‌دهد تا قابلیت‌ها و ویژگی‌های مختلف بلاکچین را به‌طور جداگانه و مستقل از هم مدیریت کنید. این رویکرد به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی را با انتخاب ماژول‌ها و ویژگی‌های خاص بسازند و آن‌ها را به‌صورت ساده و انعطاف‌پذیر پیاده‌سازی کنند.

ماژول‌ها در Cosmos SDK به‌عنوان واحدهای سازنده اصلی بلاکچین‌ها عمل می‌کنند و هر یک از آن‌ها مسئول یک جنبه خاص از عملکرد بلاکچین است، مانند احراز هویت (Auth)، تراکنش‌های بانکی (Bank)، استیکینگ (Staking) و دیگر قابلیت‌ها.

مزایای معماری ماژولار در Cosmos SDK

  1. انعطاف‌پذیری بالا
    یکی از مزایای اصلی معماری ماژولار، توانایی انتخاب و ترکیب ماژول‌های مختلف برای نیازهای خاص پروژه است. به‌جای اینکه یک بلاکچین پیش‌ساخته با ویژگی‌های ثابت داشته باشید، می‌توانید ماژول‌های موردنیاز خود را انتخاب کرده و آن‌ها را به‌صورت جداگانه توسعه دهید.
  2. قابلیت توسعه و بهبود آسان
    ماژول‌ها به‌صورت مستقل از یکدیگر طراحی شده‌اند، بنابراین می‌توانند به راحتی توسعه داده شوند یا به‌روزرسانی شوند بدون اینکه بر روی سایر قسمت‌ها تأثیر بگذارند. این ویژگی توسعه‌دهندگان را قادر می‌سازد که تغییرات جدید را با حداقل ریسک اعمال کنند.
  3. پشتیبانی از بلاکچین‌های سفارشی
    هر بلاکچین می‌تواند مجموعه‌ای از ماژول‌های مختلف را که به نیازهای خاص آن پروژه پاسخ می‌دهند، داشته باشد. به‌عنوان مثال، یک بلاکچین می‌تواند ماژول‌های بانکداری و استیکینگ را داشته باشد، در حالی که یک بلاکچین دیگر ممکن است ماژول‌های حاکمیتی و اوراکل را به آن اضافه کند.
  4. مدیریت بهتر امنیت
    به دلیل اینکه هر ماژول به‌صورت جداگانه مدیریت می‌شود، شما می‌توانید امنیت هر یک از ماژول‌ها را به‌طور مجزا ارزیابی و تقویت کنید. این امکان باعث می‌شود که اگر یک ماژول دچار آسیب‌پذیری شود، اثرات آن بر روی کل سیستم کاهش یابد.

اجزای ماژولار در Cosmos SDK

هر بلاکچین ساخته‌شده با استفاده از Cosmos SDK از ترکیب چندین ماژول مختلف تشکیل می‌شود. این ماژول‌ها می‌توانند به راحتی اضافه، حذف یا تغییر داده شوند. در ادامه، برخی از ماژول‌های استاندارد در Cosmos SDK معرفی شده‌اند:

  1. ماژول Auth
    ماژول Auth مسئول مدیریت حساب‌ها و تراکنش‌ها است. این ماژول شامل امکاناتی برای مدیریت احراز هویت و تایید اعتبار تراکنش‌ها می‌باشد.
  2. ماژول Bank
    ماژول Bank مسئول انجام تراکنش‌های انتقال ارز و ذخیره توکن‌ها است. این ماژول با استفاده از ماژول Auth برای تایید تراکنش‌ها و اعتبار حساب‌ها کار می‌کند.
  3. ماژول Staking
    ماژول Staking به کاربران اجازه می‌دهد تا توکن‌های خود را استیک کرده و در فرآیند اجماع مشارکت کنند. این ماژول امکاناتی برای ایجاد و مدیریت اعتبارسنج‌ها (validators) فراهم می‌آورد.
  4. ماژول Governance
    ماژول Governance مسئول پیاده‌سازی سیستم‌های حاکمیتی و تصمیم‌گیری در بلاکچین است. این ماژول به کاربران این امکان را می‌دهد که در تغییرات پروتکل‌ها و تصمیمات دیگر مشارکت کنند.
  5. ماژول IBC
    ماژول IBC (Inter-Blockchain Communication) به بلاکچین‌ها اجازه می‌دهد که با یکدیگر ارتباط برقرار کنند و اطلاعات یا دارایی‌ها را از یک زنجیره به زنجیره دیگر منتقل کنند. این ماژول نقش بسیار مهمی در اکوسیستم Cosmos دارد.

نحوه اضافه کردن ماژول‌ها به پروژه

در Cosmos SDK، اضافه کردن ماژول‌های جدید به‌راحتی از طریق دستورات و تنظیمات ساده انجام می‌شود. برای افزودن ماژول به پروژه Cosmos SDK خود، باید مراحل زیر را دنبال کنید:

  1. وارد کردن ماژول به پروژه
    ابتدا باید ماژول موردنظر خود را از GitHub یا منابع رسمی Cosmos SDK دریافت کنید. به‌عنوان مثال، برای افزودن ماژول bank به پروژه، باید فایل‌های مربوطه را به پروژه خود اضافه کنید.

    git clone https://github.com/cosmos/cosmos-sdk.git
    
  2. پیکربندی ماژول
    پس از دریافت ماژول، باید آن را در فایل پیکربندی بلاکچین خود، معمولاً در مسیر x/<module_name>/module.go، وارد کنید.
  3. ایجاد و اعمال تغییرات
    پس از وارد کردن ماژول‌ها و پیکربندی آن‌ها، تغییرات خود را کامپایل کرده و بلاکچین خود را بازسازی کنید.

    make install
    

جمع‌بندی

در Cosmos SDK، مفهوم ماژولار به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌هایی سفارشی و انعطاف‌پذیر بسازند. با استفاده از ماژول‌ها، می‌توان قابلیت‌های مختلف بلاکچین را به‌طور مستقل اضافه یا حذف کرد، بدون اینکه به بخش‌های دیگر سیستم آسیب برساند. این رویکرد از توسعه ساده‌تر، به‌روزرسانی‌های سریع‌تر و امنیت بهتری برخوردار است. Cosmos SDK با استفاده از این معماری، بلاکچین‌هایی قدرتمند و مقیاس‌پذیر ارائه می‌دهد که می‌توانند نیازهای مختلف پروژه‌ها را برآورده کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی ساختار کلی یک بلاکچین مبتنی بر Cosmos SDK” subtitle=”توضیحات کامل”]Cosmos SDK یک فریمورک ماژولار برای ساخت بلاکچین‌های سفارشی است که به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌هایی با ویژگی‌های خاص و مطابق با نیازهای پروژه بسازند. در این بخش، به بررسی ساختار کلی یک بلاکچین مبتنی بر Cosmos SDK پرداخته می‌شود و اجزای مختلف آن توضیح داده خواهد شد.

یک بلاکچین ساخته‌شده با Cosmos SDK از چندین بخش کلیدی تشکیل می‌شود که هرکدام مسئول یک وظیفه خاص هستند. این اجزا شامل ماژول‌ها، هسته Cosmos SDK، و اجزای زیرساختی مختلف می‌باشند. در ادامه، اجزای اصلی ساختار یک بلاکچین مبتنی بر Cosmos SDK را به تفصیل بررسی می‌کنیم.

1. هسته Cosmos SDK (Core SDK)

هسته اصلی Cosmos SDK وظیفه اصلی هماهنگ‌سازی و اجرای بلاکچین را بر عهده دارد. این هسته شامل مجموعه‌ای از ویژگی‌های اساسی است که بلاکچین‌های ساخته‌شده با Cosmos SDK را قادر می‌سازد که عملکرد اصلی خود را انجام دهند. اجزای اصلی هسته Cosmos SDK عبارتند از:

  • Tendermint Core: سیستم اجماع و لایه شبکه برای بلاکچین.
  • Consensus: الگوریتم اجماع که تصمیم می‌گیرد که کدام بلاک به زنجیره اضافه شود.
  • Networking: مدیریت ارتباطات شبکه‌ای بین نودها.
  • Mempool: مدیریت تراکنش‌های تایید نشده.

Tendermint Core به‌عنوان الگوریتم اجماع و لایه شبکه‌ای در Cosmos SDK عمل می‌کند که مسئول ایجاد بلوک‌ها و اطمینان از صحت تراکنش‌ها در بلاکچین است. در حالی که هسته SDK عملیات پایه‌ای بلاکچین را انجام می‌دهد، ماژول‌ها به‌عنوان واحدهای اضافی قابلیت‌های بیشتر را به بلاکچین اضافه می‌کنند.

2. ماژول‌ها (Modules)

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

  • Auth Module: این ماژول مسئول مدیریت حساب‌ها و تایید تراکنش‌ها است.
  • Bank Module: وظیفه مدیریت توکن‌ها و تراکنش‌های مالی را بر عهده دارد.
  • Staking Module: برای پیاده‌سازی فرآیند استیکینگ و مدیریت اعتبارسنج‌ها (Validators) استفاده می‌شود.
  • Governance Module: این ماژول مسئول مدیریت فرآیندهای حاکمیتی مانند رای‌گیری و پیشنهاد تغییرات پروتکل است.
  • IBC (Inter-Blockchain Communication) Module: برای ارتباط میان بلاکچین‌های مختلف و انتقال داده‌ها و دارایی‌ها از یک بلاکچین به دیگری طراحی شده است.

این ماژول‌ها از طریق هسته Cosmos SDK به یکدیگر متصل شده و در نهایت یک بلاکچین کامل و قابل استفاده را تشکیل می‌دهند.

3. پایگاه داده (Database)

برای ذخیره اطلاعات مختلف بلاکچین، Cosmos SDK از یک پایگاه داده استفاده می‌کند. پایگاه داده‌ای که در Cosmos SDK مورد استفاده قرار می‌گیرد معمولاً LevelDB یا RocksDB است. این پایگاه داده برای ذخیره‌سازی سریع و مقیاس‌پذیر داده‌ها مناسب است و تمام اطلاعات مربوط به بلاکچین، مانند بلوک‌ها، تراکنش‌ها، وضعیت حساب‌ها و وضعیت‌های مختلف سیستم در آن ذخیره می‌شود.

4. اجزای شبکه (Network Components)

یکی از اجزای اصلی هر بلاکچین، اجزای شبکه‌ای آن است. در Cosmos SDK، این اجزا شامل NODES (نودها) و پروتکل‌های ارتباطی هستند که برای تبادل داده‌ها بین نودها استفاده می‌شود. در Cosmos SDK، از Tendermint برای مدیریت ارتباطات بین نودها استفاده می‌شود. نودهای شبکه با استفاده از پروتکل‌های استاندارد (مانند TCP/IP) به یکدیگر متصل شده و اطلاعات را منتقل می‌کنند.

5. اجزای مدیریتی (Governance Components)

حاکمیت یکی از بخش‌های اساسی در اکثر بلاکچین‌هاست و در Cosmos SDK نیز با استفاده از ماژول Governance پیاده‌سازی می‌شود. این ماژول به کاربران این امکان را می‌دهد که تغییرات پیشنهادی در پروتکل بلاکچین را مطرح کنند و به رای‌گیری بگذارند. در نتیجه، تصمیمات اصلی در بلاکچین، مانند تغییرات در کد، از طریق فرآیند حاکمیتی انجام می‌شود.

6. اجزای اعتبارسنجی و استیکینگ (Validator and Staking Components)

در Cosmos SDK، اعتبارسنج‌ها (Validators) مسئول اعتبارسنجی تراکنش‌ها و ایجاد بلوک‌های جدید در زنجیره هستند. اعتبارسنج‌ها می‌توانند به‌صورت داوطلبانه در فرآیند Staking مشارکت کنند. این اجزا به‌شدت به امنیت بلاکچین بستگی دارند و به‌عنوان موتور اصلی فرآیند اجماع عمل می‌کنند.

جمع‌بندی

یک بلاکچین مبتنی بر Cosmos SDK از چندین جزء اصلی تشکیل می‌شود که هرکدام وظیفه خاصی را بر عهده دارند. هسته اصلی Cosmos SDK (که شامل Tendermint Core و اجزای شبکه است) عملیات پایه‌ای بلاکچین را انجام می‌دهد. ماژول‌ها به‌عنوان اجزای افزوده‌شده به بلاکچین، قابلیت‌های خاصی را پیاده‌سازی می‌کنند و به شما این امکان را می‌دهند که بلاکچین‌هایی سفارشی و قابل‌گسترش بسازید. اجزای مدیریتی و استیکینگ نیز به افزایش امنیت، حاکمیت و مشارکت کاربران در سیستم کمک می‌کنند. Cosmos SDK این امکان را فراهم می‌آورد تا بلاکچین‌هایی با ویژگی‌های خاص و نیازهای متفاوت بسازید و از قدرت شبکه‌های متصل به یکدیگر بهره‌برداری کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی بخش‌های اصلی (BaseApp، Store، Keeper، Handler)” subtitle=”توضیحات کامل”]Cosmos SDK یک فریمورک برای ساخت بلاکچین‌های سفارشی است که در آن تعدادی جزء اصلی و بنیادی وجود دارند که به‌طور مشترک برای پیاده‌سازی و مدیریت ساختار بلاکچین‌ها عمل می‌کنند. این اجزاء شامل BaseApp، Store، Keeper و Handler هستند. در این بخش، هرکدام از این اجزا را به تفصیل بررسی می‌کنیم و نقش آن‌ها در ساخت بلاکچین مبتنی بر Cosmos SDK را توضیح خواهیم داد.

1. BaseApp

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

از وظایف اصلی BaseApp می‌توان به موارد زیر اشاره کرد:

  • مدیریت درخواست‌ها (Requests): دریافت و پردازش درخواست‌های ورودی از نودهای مختلف در شبکه.
  • مدیریت تراکنش‌ها: بررسی، تایید و ذخیره تراکنش‌ها.
  • بررسی اعتبار: اطمینان از صحت و اعتبار تراکنش‌ها قبل از اعمال آن‌ها در بلاکچین.
  • نگهداری وضعیت: BaseApp مسئول ذخیره وضعیت فعلی بلاکچین در Store است.

BaseApp می‌تواند به‌صورت سفارشی با تغییراتی در منطق پردازش درخواست‌ها و تعاملات با ماژول‌ها توسعه یابد.

2. Store

Store یک ساختار ذخیره‌سازی برای مدیریت داده‌ها و وضعیت بلاکچین است. این جزء از Cosmos SDK مسئول ذخیره اطلاعات مختلف از جمله وضعیت حساب‌ها، تراکنش‌ها و بلاک‌ها می‌باشد. در واقع، Store وظیفه ذخیره‌سازی و دسترسی به داده‌ها را بر عهده دارد.

وظایف اصلی Store عبارتند از:

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

Cosmos SDK از LevelDB یا RocksDB به‌عنوان پایگاه داده برای ذخیره‌سازی استفاده می‌کند و داده‌ها به‌صورت کلید-مقدار ذخیره می‌شوند.

3. Keeper

Keeper یک لایه مدیریتی است که برای دسترسی به داده‌ها و انجام عملیات‌های مختلف در بلاکچین استفاده می‌شود. Keeper ارتباط بین ماژول‌ها و Store را مدیریت می‌کند و به‌طور مستقیم با BaseApp برای اجرای درخواست‌ها و تراکنش‌ها همکاری می‌کند.

نقش‌های اصلی Keeper عبارتند از:

  • مدیریت داده‌ها: Keeper مسئول ذخیره‌سازی، دسترسی و تغییر داده‌ها در Store است.
  • رابط ماژول‌ها: Keeper به‌عنوان رابطی بین ماژول‌ها و Store عمل می‌کند. به این معنی که ماژول‌ها از Keeper برای ذخیره‌سازی و دسترسی به داده‌های خاص استفاده می‌کنند.
  • پیاده‌سازی منطق تجاری: هر ماژول از Keeper برای انجام عملیات‌هایی مانند اعتبارسنجی، تغییر وضعیت یا انجام عملیات‌های خاص استفاده می‌کند.

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

4. Handler

Handler مسئول پردازش و مدیریت عملیات‌های مربوط به تراکنش‌ها است. در Cosmos SDK، هر ماژول دارای یک Handler است که به‌طور خاص برای پردازش تراکنش‌ها و درخواست‌های ورودی طراحی شده است.

وظایف Handler عبارتند از:

  • پردازش تراکنش‌ها: Handler مسئول اجرای منطق خاص هر تراکنش است. به‌عنوان مثال، در یک تراکنش انتقال دارایی، Handler وظیفه پردازش و به‌روزرسانی حساب‌ها را بر عهده دارد.
  • تایید صحت تراکنش: قبل از این‌که تراکنش در بلاکچین ذخیره شود، Handler مسئول تایید صحت آن است.
  • مدیریت وقایع: Handler می‌تواند وقایع خاصی را تولید کند که به‌صورت درون‌زا به‌طور خودکار در بلاکچین ثبت می‌شوند.

Handler به‌طور معمول به داده‌های ذخیره‌شده در Store دسترسی دارد و از Keeper برای انجام عملیات‌های مختلف استفاده می‌کند. این بخش به توسعه‌دهندگان اجازه می‌دهد تا به‌طور دقیق رفتار تراکنش‌ها و تغییرات وضعیت در بلاکچین را تعریف کنند.

جمع‌بندی

اجزای BaseApp، Store، Keeper و Handler بخش‌های اساسی ساختار یک بلاکچین مبتنی بر Cosmos SDK هستند. BaseApp به‌عنوان هسته اصلی، وظیفه مدیریت درخواست‌ها و تراکنش‌ها را دارد، در حالی که Store داده‌ها و وضعیت بلاکچین را ذخیره می‌کند. Keeper مسئول دسترسی به داده‌ها و انجام عملیات‌های مختلف است و Handler به‌عنوان پردازشگر تراکنش‌ها، منطق اجرایی بلاکچین را پیاده‌سازی می‌کند. این اجزا به‌طور مشترک با هم برای پیاده‌سازی و مدیریت بلاکچین‌های سفارشی در Cosmos SDK عمل می‌کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نحوه مدیریت ذخیره‌سازی و State در Cosmos SDK” subtitle=”توضیحات کامل”]در Cosmos SDK، ذخیره‌سازی داده‌ها و مدیریت وضعیت (State) از اهمیت بالایی برخوردار است. این مسئله به دلیل تأثیر آن بر عملکرد و امنیت بلاکچین‌های مبتنی بر Cosmos SDK بسیار حیاتی است. در این بخش، نحوه مدیریت ذخیره‌سازی و وضعیت بلاکچین در Cosmos SDK را بررسی خواهیم کرد و اجزای مختلف این فرآیند را تشریح می‌کنیم.

۱. Store: ساختار ذخیره‌سازی در Cosmos SDK

Store در Cosmos SDK مسئول ذخیره‌سازی و دسترسی به داده‌ها است. تمامی وضعیت بلاکچین از جمله وضعیت تراکنش‌ها، حساب‌ها، بلاک‌ها و داده‌های مرتبط با هر ماژول در Store ذخیره می‌شود. Store به‌عنوان یک کلید-مقدار (Key-Value) عمل می‌کند و داده‌ها به‌صورت جفت‌های کلید-مقدار در پایگاه داده ذخیره می‌شوند.

برای پیاده‌سازی Store در Cosmos SDK از LevelDB یا RocksDB به‌عنوان سیستم‌های پایگاه داده استفاده می‌شود که به‌طور بهینه برای ذخیره‌سازی داده‌ها طراحی شده‌اند.

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

۲. State: مدیریت وضعیت در Cosmos SDK

State به وضعیت فعلی بلاکچین اطلاق می‌شود که شامل تمامی داده‌ها و اطلاعاتی است که برای اجرای تراکنش‌ها و عملیات‌ها نیاز است. وضعیت بلاکچین به‌طور دائمی در Store ذخیره می‌شود و هر تغییر در وضعیت منجر به بروزرسانی داده‌ها در این پایگاه داده می‌شود.

مدیریت وضعیت به‌شکل زیر صورت می‌گیرد:

  • State Persistence: وضعیت در طول زمان ذخیره و به‌روزرسانی می‌شود. پس از اجرای هر تراکنش یا عملیات تغییر وضعیت، داده‌های جدید در Store ذخیره می‌شوند.
  • State Separation: در Cosmos SDK، وضعیت مربوط به هر ماژول از هم جدا می‌شود. هر ماژول برای ذخیره‌سازی داده‌های خاص خود از Keeper و Store استفاده می‌کند، و این باعث می‌شود که داده‌ها به‌صورت جداگانه برای هر ماژول مدیریت شوند.
  • State Caching: برای کاهش فشار روی پایگاه داده و افزایش سرعت، از کَشینگ برای ذخیره موقت وضعیت استفاده می‌شود. این عمل باعث می‌شود که تغییرات در وضعیت بلاکچین به‌صورت موقت ذخیره شده و قبل از نوشتن دائمی در Store، در حافظه موقت ذخیره شوند.

۳. Keeper: رابط ذخیره‌سازی و State

Keeper به‌عنوان رابطی بین ماژول‌ها و Store عمل می‌کند. Keeper به ماژول‌ها این امکان را می‌دهد که به‌طور امن و مؤثر به داده‌ها دسترسی پیدا کنند و تغییرات وضعیت را اعمال کنند.

وظایف Keeper عبارتند از:

  • دسترسی به داده‌ها: Keeper مسئول دسترسی به داده‌های ذخیره‌شده در Store و مدیریت این داده‌ها برای هر ماژول است.
  • تغییر وضعیت: Keeper عملیات‌های لازم برای تغییر وضعیت داده‌ها را انجام می‌دهد و این تغییرات را در Store ذخیره می‌کند.
  • حفظ امنیت: Keeper اطمینان حاصل می‌کند که داده‌ها و تغییرات وضعیت به‌صورت امن و معتبر ذخیره و پردازش می‌شوند.

هر ماژول می‌تواند Keeper مخصوص خود را داشته باشد که به‌طور خاص برای نیازهای آن ماژول طراحی شده است.

۴. مدیریت تراکنش‌ها و Atomicity

یکی از ویژگی‌های مهم Cosmos SDK در زمینه ذخیره‌سازی و وضعیت، پشتیبانی از Atomicity (اتمیک بودن تراکنش‌ها) است. این به‌این معنی است که هر تغییر در وضعیت باید به‌صورت کامل و صحیح انجام شود یا در صورت بروز هرگونه خطا، هیچ‌گونه تغییرات جزئی در وضعیت اعمال نخواهد شد.

برای این کار، Cosmos SDK از مفهومی به‌نام multi-store استفاده می‌کند. در multi-store، چندین store مختلف برای ذخیره‌سازی داده‌ها وجود دارد که همگی تحت یک تراکنش واحد مدیریت می‌شوند. در صورت بروز خطا در هر یک از بخش‌ها، تمامی تغییرات به‌طور خودکار لغو می‌شوند تا از ناسازگاری داده‌ها جلوگیری شود.

۵. Snapshots

در Cosmos SDK، برای حفظ و بازیابی وضعیت بلاکچین از مفهوم snapshots استفاده می‌شود. Snapshot به‌معنی گرفتن یک نسخه از وضعیت فعلی بلاکچین است که در زمان خاصی ذخیره می‌شود. این امکان به بلاکچین‌ها می‌دهد که در صورت نیاز به بازیابی یا انتقال به وضعیت قبلی، از snapshot‌ها استفاده کنند.

Snapshot برای موارد زیر کاربرد دارد:

  • بازیابی وضعیت در صورت خرابی: در صورت بروز خرابی یا کرش در سیستم، می‌توان از snapshot برای بازیابی وضعیت استفاده کرد.
  • مهاجرت و ارتقاء: برای انتقال یا ارتقاء بلاکچین، می‌توان از snapshot‌ها به‌عنوان ابزار برای کپی کردن وضعیت بلاکچین به محیط جدید استفاده کرد.

جمع‌بندی

مدیریت ذخیره‌سازی و وضعیت در Cosmos SDK شامل اجزای اصلی مانند Store، State، Keeper و Snapshot است که به‌طور هماهنگ برای ذخیره‌سازی داده‌ها، مدیریت وضعیت بلاکچین و پردازش تراکنش‌ها عمل می‌کنند. Store به‌عنوان ساختار ذخیره‌سازی اصلی داده‌ها عمل می‌کند، Keeper به‌عنوان رابط برای دسترسی به داده‌ها و تغییر وضعیت استفاده می‌شود، و snapshots به‌عنوان ابزاری برای بازیابی وضعیت در بلاکچین‌های مبتنی بر Cosmos SDK عمل می‌کند. همچنین، ویژگی Atomicity از اهمیت زیادی برخوردار است تا تراکنش‌ها به‌صورت کامل و صحیح پردازش شوند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”نقش Validatorها و نحوه تأیید تراکنش‌ها” subtitle=”توضیحات کامل”]در بلاکچین‌های مبتنی بر Cosmos SDK، Validatorها بخش حیاتی از پروتکل اجماع و تأیید تراکنش‌ها هستند. آنها نقش کلیدی در تأمین امنیت، پردازش تراکنش‌ها و تولید بلاک‌ها ایفا می‌کنند. در این بخش، به‌طور مفصل نقش و نحوه تأیید تراکنش‌ها توسط Validatorها در Cosmos SDK را بررسی می‌کنیم.

۱. Validatorها: تعریفی جامع

Validatorها در بلاکچین‌های مبتنی بر Cosmos SDK مسئول تأیید و اعتبارسنجی تراکنش‌ها و تولید بلاک‌ها هستند. هر Validator با استیک کردن کوین‌های خود در شبکه، به‌عنوان یک گره (node) تأییدکننده فعالیت می‌کند. در واقع، تأیید تراکنش‌ها و تولید بلاک‌ها وظایفی است که بر عهده Validatorها است و آنها از طریق سیستم اجماع Tendermint این عملیات را انجام می‌دهند.

ویژگی‌های اصلی Validator:
  • استیکینگ: برای اینکه یک گره به‌عنوان Validator عمل کند، باید مقدار مشخصی از توکن‌های بومی شبکه (که به آن‌ها staking tokens گفته می‌شود) را در شبکه استیک کند.
  • انتخاب Validator: به‌طور معمول، تنها یک گروه محدود از گره‌ها به‌عنوان Validator انتخاب می‌شوند. این انتخاب بستگی به تعداد توکن‌های استیک شده و سایر الگوریتم‌های انتخابی دارد.
  • گواهی‌نامه‌ها: هر Validator مسئول تأیید تراکنش‌ها و گواهی‌نامه بلاک‌های جدید است.
  • پاداش‌ها و جریمه‌ها: Validatorها پاداش می‌گیرند تا در شبکه مشارکت کنند، اما در صورت انجام تخلفات مانند رفتار نادرست یا غیرفعال بودن، ممکن است جریمه شوند.

۲. فرآیند تأیید تراکنش‌ها و اجماع

برای درک نحوه تأیید تراکنش‌ها توسط Validatorها، لازم است که مراحل فرآیند اجماع و تأیید را بررسی کنیم. در Cosmos SDK، از پروتکل اجماع Tendermint برای تأیید تراکنش‌ها استفاده می‌شود. این پروتکل یک سیستم اجماع Proof-of-Stake (PoS) است که در آن Validatorها برای تأیید تراکنش‌ها و اضافه کردن بلاک‌ها به زنجیره رقابت می‌کنند.

مراحل فرآیند تأیید تراکنش‌ها:
  1. ارسال تراکنش‌ها به شبکه:
    • کاربران تراکنش‌های خود را به شبکه ارسال می‌کنند. این تراکنش‌ها شامل اطلاعاتی مانند انتقال کوین‌ها، تغییر وضعیت حساب‌ها و اجرای قراردادهای هوشمند هستند.
  2. جمع‌آوری تراکنش‌ها:
    • بعد از دریافت تراکنش‌ها از کاربران، Validatorها این تراکنش‌ها را جمع‌آوری کرده و در یک بلاک جدید قرار می‌دهند.
  3. تولید بلاک پیشنهادی:
    • یکی از Validatorها (که به‌عنوان Proposer شناخته می‌شود) یک بلاک جدید را شامل تراکنش‌ها ایجاد می‌کند.
  4. رای‌گیری و گواهی‌نامه بلاک:
    • بلاک پیشنهادی برای گواهی‌نامه (نهایی شدن) توسط Validatorهای دیگر به رأی گذاشته می‌شود. هر Validator بررسی می‌کند که آیا بلاک پیشنهادی به‌درستی ساخته شده است یا خیر و سپس آن را امضا می‌کند.
    • در سیستم Tendermint، برای تأیید یک بلاک، حداقل دو سوم از Validatorها باید به بلاک پیشنهادی رأی مثبت دهند.
  5. تأسیس بلاک نهایی:
    • زمانی که تعداد کافی از Validatorها به بلاک پیشنهادی رأی مثبت دهند، بلاک به‌طور نهایی به زنجیره اضافه می‌شود و تراکنش‌ها تأیید شده و اجرایی می‌گردند.
  6. پرداخت پاداش‌ها و جریمه‌ها:
    • Validatorها پس از افزودن بلاک به زنجیره، پاداش‌هایی دریافت می‌کنند که معمولاً شامل توکن‌های بومی شبکه است. این پاداش‌ها به‌صورت مستقیم به Validatorهایی که در فرآیند تأیید تراکنش‌ها و تولید بلاک شرکت کرده‌اند تعلق می‌گیرد.
    • در صورت تخلف از استانداردهای شبکه (مانند غیرفعال بودن یا رأی منفی دادن به بلاک‌های درست)، Validator ممکن است جریمه شود یا از سیستم خارج گردد.

۳. فرآیند انتخاب Validatorها

در شبکه‌های مبتنی بر Cosmos SDK، تعداد Validatorهایی که قادر به تأیید تراکنش‌ها هستند محدود است. این انتخاب به‌طور معمول بر اساس حجم استیکینگ انجام می‌شود. Validatorهایی که بیشترین توکن‌ها را استیک کرده‌اند، شانس بیشتری برای انتخاب شدن دارند.

روش‌های انتخاب Validator:
  • حداقل استیکینگ: برای اینکه یک گره بتواند Validator شود، باید حداقل میزان مشخصی از توکن‌های شبکه را استیک کرده باشد.
  • رای‌دهی به Validatorها: در شبکه‌های مبتنی بر Cosmos SDK، کاربران می‌توانند توکن‌های خود را به Validatorهای مختلف رای بدهند. این رأی‌دهی به انتخاب Validatorها و تعیین جایگاه آنها کمک می‌کند.

۴. امنیت و تحمل خطا

پروتکل اجماع Tendermint که در Cosmos SDK استفاده می‌شود، به‌طور خاص برای تحمل خطا طراحی شده است. در این پروتکل، حتی اگر تعداد کمی از Validatorها رفتار نادرست داشته باشند یا غیرفعال شوند، شبکه همچنان قادر به ادامه عملیات و تأیید تراکنش‌ها خواهد بود.

  • توانایی تحمل خطای 1/3: پروتکل Tendermint قادر است تا 1/3 از Validatorها را خراب یا غیرفعال کند بدون اینکه امنیت یا کارایی شبکه مختل شود. این ویژگی موجب می‌شود که شبکه مقاومت بالایی در برابر حملات و خرابی‌ها داشته باشد.

۵. پاداش و جریمه برای Validatorها

Validatorها برای مشارکت در تأیید تراکنش‌ها و تولید بلاک‌ها پاداش دریافت می‌کنند، اما این پاداش مشروط به رفتار صحیح آنها است. در صورتی که Validatorها عملکرد صحیحی نداشته باشند، ممکن است جریمه شوند.

انواع جریمه‌ها:
  • Slashing: اگر یک Validator رفتار نادرستی مانند سوءاستفاده از سیستم یا غیرفعال بودن نشان دهد، ممکن است بخشی از استیک‌های خود را از دست بدهد. این عمل به‌عنوان slashing شناخته می‌شود.
  • هیچ‌گونه پاداشی در صورت غیرفعالی: در صورتی که Validatorها غیرفعال باشند یا نتوانند در فرآیند اجماع مشارکت کنند، از پاداش‌ها محروم خواهند شد.

جمع‌بندی

در Cosmos SDK، Validatorها نقش مهمی در تأیید تراکنش‌ها و تولید بلاک‌ها ایفا می‌کنند. آنها با استیک کردن توکن‌ها در شبکه، به‌عنوان گره‌های تأییدکننده در فرآیند اجماع مشارکت می‌کنند. از پروتکل اجماع Tendermint برای انتخاب و تأیید بلاک‌ها استفاده می‌شود که در آن، بلاک‌ها باید به‌وسیله دو سوم از Validatorها تأیید شوند تا نهایی شوند. همچنین، پاداش‌ها و جریمه‌ها بر اساس رفتار Validatorها تعیین می‌شود که این خود انگیزه‌ای برای تأمین امنیت و عملکرد صحیح شبکه ایجاد می‌کند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. معرفی ابزارهای کلیدی در Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی Tendermint و نحوه عملکرد آن به‌عنوان مکانیزم اجماع” subtitle=”توضیحات کامل”]Tendermint یک مکانیزم اجماع است که برای حل مشکلات مقیاس‌پذیری و امنیت در بلاکچین‌ها طراحی شده است. این سیستم به‌طور خاص برای پروژه‌های بلاکچین مبتنی بر Proof-of-Stake (PoS) ساخته شده و در پروژه‌های بسیاری مانند Cosmos SDK برای تأمین اجماع و تأیید تراکنش‌ها به کار می‌رود.

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

۱. مفهوم و ساختار Tendermint

Tendermint یک مکانیزم اجماع BFT (Byzantine Fault Tolerant) است که به بلاکچین‌ها این امکان را می‌دهد تا به توافق برسند و بلاک‌ها را به صورت معتبر به زنجیره اضافه کنند. Tendermint دو بخش اصلی دارد:

  1. Tendermint Core: که شامل الگوریتم اجماع و مدل شبکه برای ارسال پیام‌ها است.
  2. Application Blockchain Interface (ABCI): که واسط ارتباطی بین الگوریتم اجماع و لایه‌های مختلف اپلیکیشن بلاکچین است.
اجزای اصلی Tendermint:
  • Proposer: گره‌ای که مسئول پیشنهاد بلاک جدید است.
  • Validator: گره‌هایی که مسئول تأیید بلاک‌های پیشنهادی هستند.
  • Tendermint Consensus Engine: پروتکل اجماع که تصمیم می‌گیرد کدام بلاک به زنجیره اضافه شود.
  • ABCI: رابطی که اجازه می‌دهد تا بلاکچین‌های مختلف بدون نیاز به تغییر در لایه اجماع، از یکدیگر جدا شوند.

۲. نحوه عملکرد Tendermint

Tendermint از الگوریتم اجماع Proof-of-Stake (PoS) استفاده می‌کند و برای تأیید تراکنش‌ها و تولید بلاک‌ها از یک فرآیند سه‌مرحله‌ای استفاده می‌کند:

  1. Pre-vote: در این مرحله، گره‌ها نظر خود را در مورد بلاک پیشنهادی اعلام می‌کنند.
  2. Pre-commit: گره‌ها پیش از تکمیل بلاک، باید بررسی کنند که همه شرایط مورد نیاز برای بلاک تایید شده رعایت شده است.
  3. Commit: زمانی که یک بلاک توسط اکثریت گره‌ها تایید شد، به زنجیره بلاکچین اضافه می‌شود.
مراحل فرآیند اجماع Tendermint:
  1. Proposer انتخاب می‌شود: یکی از Validatorها به‌طور تصادفی انتخاب می‌شود تا بلاک جدید را پیشنهاد دهد.
  2. ارسال بلاک پیشنهادی: پروپوزر یک بلاک جدید ایجاد کرده و آن را برای سایر Validatorها ارسال می‌کند.
  3. رای‌گیری در مورد بلاک پیشنهادی: سایر Validatorها بررسی کرده و رأی خود را اعلام می‌کنند. اگر تعداد لازم رأی‌ها از Validatorها تأمین شود، بلاک تایید می‌شود.
  4. اضافه کردن بلاک به زنجیره: در صورتی که اکثریت گره‌ها بلاک را تأیید کنند، بلاک به‌طور رسمی به زنجیره اضافه می‌شود.

۳. مزایای Tendermint

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

۴. نحوه نصب و پیکربندی Tendermint

برای استفاده از Tendermint در بلاکچین‌های مبتنی بر Cosmos SDK، ابتدا باید Tendermint را نصب کرده و تنظیمات مورد نیاز را انجام دهید.

مراحل نصب Tendermint:
  1. نصب Go: قبل از نصب Tendermint، نیاز به نصب زبان برنامه‌نویسی Go است. برای نصب Go می‌توانید دستورات زیر را اجرا کنید:
    sudo apt update
    sudo apt install golang-go
    
  2. نصب Tendermint: پس از نصب Go، می‌توانید Tendermint را از GitHub نصب کنید. دستور زیر را برای نصب از گیت‌هاب وارد کنید:
    git clone https://github.com/tendermint/tendermint.git
    cd tendermint
    make install
    

    پس از نصب، می‌توانید دستور tendermint version را برای بررسی نسخه نصب‌شده اجرا کنید:

    tendermint version
    
  3. پیکربندی Tendermint: برای پیکربندی Tendermint، ابتدا نیاز است تا یک دایرکتوری برای پیکربندی‌ها ایجاد کنید. سپس از دستور tendermint init برای راه‌اندازی نود جدید استفاده کنید:
    tendermint init
    

    این دستور فایل‌های پیکربندی مورد نیاز را در مسیر پیش‌فرض خود (~/.tendermint/config/) ایجاد خواهد کرد. شما می‌توانید فایل‌های پیکربندی مانند config.toml و genesis.json را در این مسیر ویرایش کنید.

  4. راه‌اندازی گره Tendermint: برای راه‌اندازی گره Tendermint، می‌توانید دستور زیر را اجرا کنید:
    tendermint node
    

    با اجرای این دستور، نود شما به شبکه متصل می‌شود و شروع به اعتبارسنجی بلاک‌ها می‌کند.

۵. نحوه عملکرد Tendermint در بلاکچین‌های مبتنی بر Cosmos SDK

در Cosmos SDK، از Tendermint برای ایجاد شبکه‌های بلاکچینی مقیاس‌پذیر و ایمن استفاده می‌شود. زمانی که یک گره در شبکه قرار می‌گیرد، از Tendermint برای انتخاب پروپوزر، تأیید تراکنش‌ها و اضافه کردن بلاک‌ها به زنجیره استفاده می‌کند.

تنظیمات مربوط به Tendermint در Cosmos SDK:
  • config.toml: فایل پیکربندی اصلی برای تنظیمات شبکه Tendermint مانند تعداد Validatorها، پارامترهای پروتکل اجماع و پیکربندی‌های امنیتی است.
  • genesis.json: این فایل شامل اطلاعات اولیه شبکه، از جمله آدرس‌های Validatorها، میزان استیکینگ و پارامترهای دیگر است.

جمع‌بندی

Tendermint به‌عنوان یک مکانیزم اجماع BFT، نقش بسیار مهمی در بلاکچین‌های مبتنی بر Cosmos SDK دارد. این سیستم با استفاده از پروتکل اجماع سریع و مقاوم در برابر خطا، امکان تأسیس شبکه‌هایی مقیاس‌پذیر و ایمن را فراهم می‌آورد. نصب و پیکربندی Tendermint در Cosmos SDK از طریق ابزارهای مختلفی مانند tendermint init و tendermint node امکان‌پذیر است و برای اجرای بلاکچین‌های سفارشی به‌طور گسترده‌ای استفاده می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی Starport و نحوه ایجاد سریع یک بلاکچین” subtitle=”توضیحات کامل”]Starport یک ابزار توسعه برای ساخت و توسعه بلاکچین‌های مبتنی بر Cosmos SDK است که به توسعه‌دهندگان کمک می‌کند تا به‌طور سریع و ساده بلاکچین‌های سفارشی خود را ایجاد کنند. Starport تمام فرآیندهای پیچیده‌ای که برای راه‌اندازی یک بلاکچین Cosmos SDK لازم است، خودکار می‌کند و به توسعه‌دهندگان اجازه می‌دهد تا بیشتر روی منطق کسب‌وکار و ویژگی‌های اپلیکیشن بلاکچینی خود تمرکز کنند.

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

۱. ویژگی‌های Starport

Starport شامل ابزارهایی است که به توسعه‌دهندگان امکان ایجاد بلاکچین‌های سفارشی، ماژول‌های جدید، و APIهای مربوط به آن‌ها را به‌سادگی فراهم می‌کند. ویژگی‌های اصلی Starport عبارتند از:

  • ایجاد سریع بلاکچین‌ها: Starport به‌طور خودکار تمام ساختارهای مورد نیاز برای بلاکچین، از جمله کدهای اولیه و فایل‌های پیکربندی را تولید می‌کند.
  • مدیریت ماژول‌ها: می‌توانید ماژول‌های جدید ایجاد کرده و آن‌ها را به بلاکچین اضافه کنید.
  • مراحل توسعه بدون نیاز به پیچیدگی‌های دستی: تمام فرآیندهای پیچیده از جمله ایجاد اپلیکیشن‌های بلاکچین، اتصال به شبکه و اجرای دستورات با استفاده از ابزارهای گرافیکی و کامندی ساده‌تر می‌شود.
  • حمایت از قابلیت‌های Cosmos SDK: Starport به‌طور کامل از ویژگی‌های Cosmos SDK پشتیبانی می‌کند و به شما این امکان را می‌دهد که از قابلیت‌های اجماع، ذخیره‌سازی و شبکه استفاده کنید.
  • پشتیبانی از پروتکل‌های مختلف: Starport این امکان را فراهم می‌کند که بلاکچین‌های مختلف با پروتکل‌های متفاوت ایجاد کنید.

۲. نصب Starport

برای استفاده از Starport، باید آن را نصب کنید. Starport به‌راحتی از طریق دستور CLI نصب می‌شود. ابتدا باید Go را نصب کرده باشید، سپس می‌توانید دستور زیر را برای نصب Starport اجرا کنید:

# نصب Starport
curl https://get.starport.network/starport! | bash

پس از نصب Starport، می‌توانید آن را با دستور زیر بررسی کنید:

starport version

۳. ایجاد یک بلاکچین جدید با Starport

یکی از قابلیت‌های اصلی Starport، ایجاد بلاکچین‌های جدید به‌طور سریع است. با استفاده از دستور starport scaffold chain می‌توانید به‌راحتی یک بلاکچین جدید ایجاد کنید.

گام‌های ایجاد بلاکچین:
  1. ایجاد پروژه بلاکچین: برای ایجاد یک پروژه بلاکچین جدید، دستور زیر را اجرا کنید:
    starport scaffold chain github.com/username/mychain
    

    این دستور یک دایرکتوری جدید به نام mychain ایجاد می‌کند که شامل کدهای اولیه برای بلاکچین، فایل‌های پیکربندی و ماژول‌های ابتدایی است.

  2. پیکربندی بلاکچین: Starport به‌طور خودکار فایل‌هایی مانند app.toml و config.toml را در دایرکتوری پروژه ایجاد می‌کند. این فایل‌ها برای پیکربندی ویژگی‌های مختلف بلاکچین استفاده می‌شوند.
  3. راه‌اندازی بلاکچین: پس از ایجاد پروژه، می‌توانید بلاکچین را راه‌اندازی کنید. برای این کار دستور زیر را وارد کنید:
    cd mychain
    starport chain serve
    

    این دستور بلاکچین جدید را در حالت تست راه‌اندازی می‌کند و به شما این امکان را می‌دهد که از طریق APIهای آن تعامل کنید.

۴. ایجاد ماژول‌های جدید با Starport

یکی دیگر از ویژگی‌های کلیدی Starport این است که به شما این امکان را می‌دهد که ماژول‌های سفارشی برای بلاکچین خود ایجاد کنید.

ایجاد ماژول جدید:

برای ایجاد یک ماژول جدید در بلاکچین خود، می‌توانید از دستور starport scaffold module استفاده کنید:

starport scaffold module mymodule

این دستور ماژول جدیدی به نام mymodule ایجاد می‌کند و فایل‌های ضروری برای آن را در پروژه بلاکچین شما قرار می‌دهد.

۵. ایجاد و مدیریت تراکنش‌ها

با Starport، می‌توانید به‌سادگی تراکنش‌های جدید را ایجاد کرده و آن‌ها را برای بلاکچین خود تنظیم کنید.

ایجاد تراکنش جدید:

برای ایجاد یک تراکنش جدید، می‌توانید از دستور starport scaffold tx استفاده کنید:

starport scaffold tx send coins --module=mymodule

این دستور یک تراکنش جدید برای ارسال کوین‌ها در ماژول mymodule ایجاد می‌کند.

۶. تست و دیباگ بلاکچین

Starport به شما امکان می‌دهد تا بلاکچین خود را به‌طور محلی تست و دیباگ کنید.

اجرای بلاکچین در حالت تست:

برای تست بلاکچین خود، کافیست از دستور زیر استفاده کنید:

starport chain serve

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

۷. استفاده از Starport برای مدیریت شبکه‌های تولیدی

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

جمع‌بندی

Starport یک ابزار قدرتمند و ساده برای توسعه سریع بلاکچین‌های مبتنی بر Cosmos SDK است که با خودکار کردن بسیاری از مراحل پیچیده، فرآیند ساخت بلاکچین‌های سفارشی را تسهیل می‌کند. از طریق Starport، می‌توانید بلاکچین‌های جدید، ماژول‌های سفارشی و تراکنش‌های مختلف را به‌سرعت ایجاد کرده و به‌راحتی آن‌ها را در شبکه‌های تست و تولید راه‌اندازی کنید. این ابزار به‌ویژه برای توسعه‌دهندگانی که نیاز به ساخت بلاکچین‌های سفارشی با حداقل پیچیدگی دارند، یک گزینه ایده‌آل است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”معرفی IBC (Inter-Blockchain Communication) برای ارتباط بین زنجیره‌ای” subtitle=”توضیحات کامل”]IBC (Inter-Blockchain Communication) یک پروتکل است که به بلاکچین‌های مختلف این امکان را می‌دهد تا به‌طور ایمن و قابل اعتماد با یکدیگر ارتباط برقرار کنند. این پروتکل از Cosmos SDK و اکوسیستم Cosmos سرچشمه می‌گیرد و طراحی شده است تا از تبادل داده‌ها و دارایی‌ها میان بلاکچین‌ها پشتیبانی کند. IBC می‌تواند ارتباطات میان بلاکچین‌های مستقل را برقرار کرده و به آن‌ها این امکان را بدهد که بدون نیاز به اعتماد متقابل یا نیاز به یک بلاکچین واحد مرکزی، اطلاعات و دارایی‌ها را انتقال دهند.

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

۱. چگونه IBC کار می‌کند؟

در پروتکل IBC، بلاکچین‌ها از طریق کانال‌های ایمن و قابل اعتماد برای انتقال داده‌ها و تراکنش‌ها به یکدیگر متصل می‌شوند. هر بلاکچین در شبکه IBC به‌طور مستقل عمل می‌کند، ولی از طریق پروتکل IBC می‌تواند با دیگر بلاکچین‌ها تعامل داشته باشد.

مراحل کلی عملکرد IBC به‌شرح زیر است:

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

۲. مزایای IBC

پروتکل IBC مزایای زیادی برای اکوسیستم‌های بلاکچینی فراهم می‌کند. از مهم‌ترین مزایای IBC می‌توان به موارد زیر اشاره کرد:

  • ارتباط بلاکچین‌های مستقل: بلاکچین‌ها می‌توانند به‌طور مستقل عمل کنند ولی از طریق IBC با یکدیگر ارتباط برقرار کنند. این امر به توسعه‌دهندگان و کاربران این امکان را می‌دهد که از مزایای بلاکچین‌های مختلف بهره‌مند شوند.
  • انتقال دارایی‌ها بین بلاکچین‌ها: IBC به کاربران این امکان را می‌دهد که دارایی‌ها (مثل توکن‌ها) را به‌راحتی بین بلاکچین‌ها منتقل کنند.
  • عدم نیاز به اعتماد متقابل: بلاکچین‌ها برای انتقال داده‌ها به یکدیگر نیازی به اعتماد متقابل ندارند. هر بلاکچین از پروتکل IBC استفاده می‌کند تا اطمینان حاصل کند که داده‌ها به‌طور امن منتقل می‌شوند.
  • بهبود مقیاس‌پذیری و کارایی: IBC می‌تواند به مقیاس‌پذیری بلاکچین‌ها کمک کند و امکان ارتباط و انتقال سریع داده‌ها را فراهم آورد.
  • رشد اکوسیستم بلاکچین‌ها: IBC می‌تواند کمک کند تا اکوسیستم بلاکچین‌ها به‌طور کلی گسترش یابد و بلاکچین‌های مختلف با نیازهای متفاوت به هم متصل شوند.

۳. نحوه استفاده از IBC در بلاکچین‌ها

برای استفاده از IBC در بلاکچین‌های مبتنی بر Cosmos SDK، ابتدا باید پیکربندی‌های خاصی انجام شود. این پیکربندی‌ها شامل تنظیمات مربوط به کانال‌ها و اتصال به دیگر بلاکچین‌ها است. در ادامه یک فرایند ساده برای استفاده از IBC توضیح داده می‌شود.

گام اول: نصب و پیکربندی Cosmos SDK

برای استفاده از IBC، ابتدا باید Cosmos SDK را نصب کنید. پس از نصب، نیاز است که تنظیمات مربوط به IBC را در بلاکچین خود انجام دهید. این تنظیمات در فایل‌های پیکربندی مربوطه قرار می‌گیرند.

# نصب Cosmos SDK
git clone https://github.com/cosmos/cosmos-sdk.git
cd cosmos-sdk
make
گام دوم: ایجاد کانال ارتباطی IBC

برای ایجاد کانال ارتباطی بین دو بلاکچین، باید از دستور starport برای پیکربندی استفاده کنید. این کانال‌ها برای ارسال و دریافت داده‌ها بین بلاکچین‌ها ضروری هستند.

# ایجاد کانال IBC
starport scaffold ibc channel [source-chain] [destination-chain]
گام سوم: راه‌اندازی بلاکچین

پس از پیکربندی کانال‌ها، می‌توانید بلاکچین خود را در حالت آزمایشی یا تولید راه‌اندازی کنید. این کار از طریق دستور starport serve انجام می‌شود.

# راه‌اندازی بلاکچین
starport serve
گام چهارم: ارسال تراکنش بین بلاکچین‌ها

برای ارسال تراکنش بین بلاکچین‌ها از پروتکل IBC، باید تراکنش‌های مربوطه را از طریق API‌های بلاکچین ارسال کنید. این تراکنش‌ها در کانال‌های IBC منتقل می‌شوند و در بلاکچین گیرنده تایید می‌شوند.

# ارسال تراکنش از بلاکچین A به بلاکچین B
starport tx send [amount] --from [source-chain] --to [destination-chain]

۴. نمونه‌های استفاده از IBC

IBC در پروژه‌های مختلف بلاکچینی استفاده می‌شود که از آن برای انتقال دارایی‌ها، داده‌ها، و یا هماهنگی میان بلاکچین‌های مختلف بهره می‌برند. یکی از نمونه‌های برجسته استفاده از IBC، Cosmos Hub و Osmois هستند که از IBC برای انتقال دارایی‌ها و انجام تراکنش‌ها بین زنجیره‌های مختلف استفاده می‌کنند.

جمع‌بندی

پروتکل IBC یک ابزار قدرتمند برای ارتباط بین بلاکچین‌های مستقل است که به‌طور عمده در اکوسیستم Cosmos استفاده می‌شود. این پروتکل به بلاکچین‌ها این امکان را می‌دهد که بدون نیاز به اعتماد متقابل، داده‌ها و دارایی‌ها را به‌طور ایمن و قابل اعتماد منتقل کنند. IBC به‌ویژه در زمانی که نیاز به تعامل بین بلاکچین‌ها وجود داشته باشد، اهمیت زیادی پیدا می‌کند و می‌تواند به مقیاس‌پذیری و توسعه بیشتر اکوسیستم بلاکچین کمک کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”کار با Cosmovisor برای مدیریت به‌روزرسانی‌های بلاکچین” subtitle=”توضیحات کامل”]Cosmovisor یک ابزار قدرتمند در اکوسیستم Cosmos SDK است که برای مدیریت به‌روزرسانی‌ها و ارتقاء نسخه‌های بلاکچین‌ها طراحی شده است. این ابزار به‌ویژه برای بلاکچین‌هایی که نیاز به به‌روزرسانی‌های منظم دارند و می‌خواهند بدون توقف و اختلال در عملیات، نسخه‌های جدید را پیاده‌سازی کنند، بسیار مفید است. در این بخش، نحوه نصب، پیکربندی و استفاده از Cosmovisor برای به‌روزرسانی‌های بلاکچین بررسی خواهد شد.

۱. مفهوم Cosmovisor

Cosmovisor یک پروسه مدیریت به‌روزرسانی است که به‌طور خودکار و بدون نیاز به دخالت دستی از سوی اپراتور شبکه، به‌روزرسانی‌ها و ارتقاء نسخه‌ها را انجام می‌دهد. این ابزار به‌ویژه برای بلاکچین‌های مبتنی بر Cosmos SDK طراحی شده و به‌طور عمده برای مدیریت ارتقاء‌های نرم‌افزاری در شبکه‌های بلاکچینی کاربرد دارد.

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

۲. نصب و پیکربندی Cosmovisor

برای استفاده از Cosmovisor، باید ابتدا آن را نصب کرده و سپس بلاکچین خود را برای استفاده از این ابزار پیکربندی کنید. در اینجا مراحل نصب و پیکربندی Cosmovisor را به‌طور کامل توضیح می‌دهیم.

گام اول: نصب Cosmovisor

برای نصب Cosmovisor، ابتدا باید از GitHub نسخه رسمی این ابزار را دانلود کنید.

# دانلود و نصب Cosmovisor از GitHub
git clone https://github.com/cosmos/cosmovisor.git
cd cosmovisor
make install

پس از نصب Cosmovisor، باید مطمئن شوید که پیکربندی صحیح انجام شده است.

گام دوم: پیکربندی متغیرهای محیطی

برای اینکه Cosmovisor بتواند به‌درستی کار کند، باید چندین متغیر محیطی را تنظیم کنید. این متغیرها به ابزار کمک می‌کنند تا مسیرهای مختلف فایل‌ها و بلاکچین‌ها را شناسایی کند.

# تنظیم مسیر به بلاکچین خود و Cosmovisor
export DAEMON_HOME=$HOME/.cosmosd
export DAEMON_NAME=cosmosd
export COSMOVISOR_HOME=$HOME/.cosmovisor
گام سوم: تنظیم Cosmovisor برای مدیریت ارتقاء‌ها

برای مدیریت ارتقاء‌ها با Cosmovisor، باید بلاکچین خود را به‌گونه‌ای تنظیم کنید که به‌طور خودکار از نسخه‌های جدید پشتیبانی کند. این کار با تغییر پیکربندی‌های بلاکچین و استفاده از فایل‌های خاص برای نسخه‌های جدید انجام می‌شود.

در مسیر $DAEMON_HOME/config/app.toml، باید مقادیر مربوط به به‌روزرسانی‌ها و ارتقاء‌ها را تنظیم کنید.

# ویرایش پیکربندی بلاکچین برای پشتیبانی از به‌روزرسانی‌ها
nano $DAEMON_HOME/config/app.toml

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

۳. نحوه استفاده از Cosmovisor برای مدیریت به‌روزرسانی‌ها

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

گام اول: راه‌اندازی Cosmovisor

برای راه‌اندازی Cosmovisor، باید آن را به‌عنوان یک سرویس در پس‌زمینه اجرا کنید. این کار به Cosmovisor این امکان را می‌دهد که به‌طور خودکار به‌روزرسانی‌ها را مدیریت کند.

# راه‌اندازی Cosmovisor به‌صورت پس‌زمینه
cosmovisor start
گام دوم: بررسی وضعیت به‌روزرسانی‌ها

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

# بررسی وضعیت به‌روزرسانی‌ها
cosmovisor status

این دستور به شما اطلاعاتی از وضعیت فعلی به‌روزرسانی‌ها، آخرین نسخه‌های بلاکچین و هرگونه مشکلات مربوط به ارتقاء‌ها را نشان می‌دهد.

گام سوم: اجرای ارتقاء‌ها

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

# تایید ارتقاء بلاکچین
cosmovisor upgrade

۴. مزایای استفاده از Cosmovisor

استفاده از Cosmovisor در شبکه‌های بلاکچینی مزایای زیادی دارد که به شرح زیر است:

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

جمع‌بندی

Cosmovisor یک ابزار بسیار مفید برای مدیریت به‌روزرسانی‌ها و ارتقاء نسخه‌های بلاکچین است که در اکوسیستم Cosmos SDK به‌طور گسترده‌ای استفاده می‌شود. این ابزار به شما کمک می‌کند تا بدون نیاز به توقف و اختلال در عملیات شبکه، نسخه‌های جدید را پیاده‌سازی کرده و از پشتیبانی از به‌روزرسانی‌ها اطمینان حاصل کنید. با نصب و پیکربندی صحیح Cosmovisor، می‌توانید به‌راحتی فرآیند به‌روزرسانی‌ها را مدیریت کرده و از مزایای آن بهره‌مند شوید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”استفاده از gRPC و REST API برای تعامل با بلاکچین” subtitle=”توضیحات کامل”]در اکوسیستم Cosmos SDK، برای ارتباط و تعامل با بلاکچین از دو پروتکل gRPC و REST API به‌طور گسترده استفاده می‌شود. این دو پروتکل ابزارهای قدرتمندی برای توسعه‌دهندگان فراهم می‌کنند تا به‌راحتی با بلاکچین‌های مبتنی بر Cosmos SDK تعامل داشته باشند و عملیات مختلفی را مانند ارسال تراکنش‌ها، دریافت داده‌ها و مدیریت وضعیت‌ها انجام دهند.

در این بخش، نحوه استفاده از gRPC و REST API برای تعامل با بلاکچین مبتنی بر Cosmos SDK بررسی خواهد شد. این موضوع شامل نصب و پیکربندی ابزارهای موردنیاز، استفاده از گراف API برای ارسال درخواست‌ها، و نحوه اتصال به سرویس‌های بلاکچین خواهد بود.

۱. مقدمه‌ای بر gRPC و REST API

gRPC (Google Remote Procedure Call) یک فریمورک برای ساخت APIهای سریع، قابل‌مقیاس و قدرتمند است. gRPC مبتنی بر پروتکل HTTP/2 است که سرعت بالایی در انتقال داده‌ها و قابلیت‌های فراوانی مانند استریمینگ و متصل بودن به‌صورت همزمان را فراهم می‌آورد.

REST API به‌عنوان یک استاندارد برای تعامل با سرویس‌ها و سرورها، از پروتکل HTTP برای ارسال درخواست‌ها و دریافت پاسخ‌ها استفاده می‌کند. REST API در بسیاری از پروژه‌ها برای تعامل با بلاکچین‌ها و سرویس‌های مختلف استفاده می‌شود و به‌ویژه در Cosmos SDK برای عملیات مختلف مانند دریافت وضعیت بلاک‌ها و تراکنش‌ها کاربرد دارد.

۲. نصب و پیکربندی gRPC و REST API در بلاکچین‌های Cosmos SDK

قبل از استفاده از gRPC و REST API در بلاکچین‌های مبتنی بر Cosmos SDK، لازم است برخی پیکربندی‌ها انجام شود. در این بخش، ابتدا نحوه پیکربندی و نصب موردنیازهای gRPC و REST API توضیح داده می‌شود.

گام اول: نصب ابزارهای لازم

برای استفاده از gRPC و REST API در بلاکچین مبتنی بر Cosmos SDK، ابتدا باید ابزارهای موردنیاز مانند Protobuf و gRPC tools را نصب کنید. در ادامه، نحوه نصب این ابزارها به‌طور گام‌به‌گام آمده است.

  1. نصب Protobuf

Protobuf به‌عنوان یک فرمت فایل برای تعریف پیام‌ها و سرویس‌ها استفاده می‌شود. برای نصب Protobuf، از دستورات زیر استفاده کنید:

# نصب Protobuf
sudo apt install -y protobuf-compiler
  1. نصب gRPC tools

برای نصب ابزارهای گرافی از دستورات زیر استفاده کنید:

# نصب gRPC tools
go get -u google.golang.org/grpc
گام دوم: پیکربندی gRPC و REST API در Cosmos SDK

برای فعال‌سازی gRPC و REST API در بلاکچین خود، باید پیکربندی‌های مربوطه را در فایل app.toml که در دایرکتوری config بلاکچین قرار دارد، انجام دهید.

# ویرایش فایل پیکربندی app.toml
nano $DAEMON_HOME/config/app.toml

در این فایل، باید تنظیمات مربوط به gRPC و REST API را به‌صورت زیر اعمال کنید:

# فعال‌سازی gRPC
grpc = true

# فعال‌سازی REST API
rest = true

پس از انجام این تغییرات، بلاکچین شما آماده استفاده از gRPC و REST API خواهد بود.

۳. استفاده از gRPC برای تعامل با بلاکچین

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

گام اول: تنظیم gRPC Server در بلاکچین

برای راه‌اندازی gRPC، ابتدا باید یک سرور gRPC در بلاکچین خود تنظیم کنید. به‌طور پیش‌فرض، Cosmos SDK از gRPC پشتیبانی می‌کند و شما فقط باید آن را در پیکربندی فعال کنید.

پس از پیکربندی، برای راه‌اندازی سرور gRPC از دستور زیر استفاده کنید:

# راه‌اندازی gRPC server
cosmosd start --rpc.laddr tcp://0.0.0.0:26657 --grpc.laddr tcp://0.0.0.0:9090

این دستور gRPC server را در پورت 9090 راه‌اندازی خواهد کرد.

گام دوم: ارسال درخواست gRPC

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

# ارسال درخواست gRPC برای دریافت وضعیت بلاکچین
grpcurl -d '{"height": "100"}' -plaintext localhost:9090 cosmos.stake.v1beta1.Query/Validator

در این مثال، از grpcurl برای ارسال درخواست gRPC به بلاکچین استفاده می‌شود. این دستور اطلاعات مربوط به یک Validator خاص را بر اساس شماره بلاک (height) مورد نظر دریافت می‌کند.

۴. استفاده از REST API برای تعامل با بلاکچین

REST API به‌طور گسترده‌ای در بلاکچین‌های مبتنی بر Cosmos SDK برای انجام درخواست‌های مختلف از جمله ارسال تراکنش‌ها، دریافت وضعیت بلاک‌ها و اطلاعات شبکه استفاده می‌شود.

گام اول: ارسال درخواست‌های REST API

برای ارسال درخواست‌های REST API به بلاکچین، باید از ابزارهایی مانند curl یا Postman استفاده کنید.

برای مثال، برای ارسال یک درخواست GET به بلاکچین و دریافت اطلاعات وضعیت بلاک، از دستور زیر استفاده کنید:

# ارسال درخواست REST API برای دریافت وضعیت بلاکچین
curl http://localhost:1317/status

این درخواست اطلاعات مربوط به وضعیت بلاکچین را بر اساس پورت 1317 که به‌طور پیش‌فرض برای REST API در بلاکچین‌های Cosmos SDK تنظیم شده است، دریافت می‌کند.

گام دوم: ارسال تراکنش‌ها از طریق REST API

برای ارسال یک تراکنش به بلاکچین از طریق REST API، از دستور POST استفاده می‌شود. برای مثال، برای ارسال تراکنش جدید، می‌توانید از دستور زیر استفاده کنید:

# ارسال تراکنش از طریق REST API
curl -X POST http://localhost:1317/txs -d '{"tx": {...}}' -H "Content-Type: application/json"

در این درخواست، شما باید ساختار تراکنش را در داخل بخش tx قرار دهید و آن را به بلاکچین ارسال کنید.

۵. جمع‌بندی

استفاده از gRPC و REST API برای تعامل با بلاکچین‌های مبتنی بر Cosmos SDK امکانات قدرتمندی را در اختیار توسعه‌دهندگان قرار می‌دهد. gRPC برای انجام درخواست‌های سریع و کارآمد و REST API برای تعامل‌های مبتنی بر HTTP بسیار مفید است. با پیکربندی صحیح و استفاده از این ابزارها، می‌توانید بلاکچین خود را به‌طور مؤثر مدیریت کرده و تعاملات مختلف را انجام دهید.

با استفاده از این دو پروتکل، شما قادر خواهید بود که بلاکچین خود را به‌راحتی گسترش دهید و ارتباطات بی‌وقفه و کارآمدی را بین اپلیکیشن‌ها و بلاکچین برقرار کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. ایجاد اولین بلاکچین با Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ایجاد یک پروژه جدید با Starport” subtitle=”توضیحات کامل”]Starport ابزاری است که به توسعه‌دهندگان امکان می‌دهد به‌سرعت یک بلاکچین جدید مبتنی بر Cosmos SDK بسازند. این ابزار با فراهم کردن مجموعه‌ای از دستورات ساده، فرآیند ساخت بلاکچین‌های اختصاصی را سریع و ساده می‌کند. در این بخش، ما گام‌های لازم برای ایجاد یک پروژه جدید با استفاده از Starport را بررسی خواهیم کرد و نحوه پیکربندی و تنظیمات مختلف آن را به‌طور دقیق توضیح خواهیم داد.

۱. نصب Starport

قبل از ایجاد پروژه با Starport، ابتدا باید این ابزار را بر روی سیستم خود نصب کنید. برای نصب، از دستور زیر استفاده می‌شود:

# نصب Starport با استفاده از دستور Go
GO111MODULE=on go get github.com/tendermint/starport/starport@latest

این دستور آخرین نسخه Starport را از GitHub دانلود و نصب می‌کند.

پس از نصب Starport، با استفاده از دستور زیر می‌توانید بررسی کنید که نصب با موفقیت انجام شده است:

# بررسی نصب Starport
starport version

این دستور باید نسخه نصب‌شده Starport را نمایش دهد.

۲. ایجاد یک پروژه جدید با Starport

برای ایجاد یک پروژه جدید با استفاده از Starport، ابتدا باید به دایرکتوری مورد نظر خود بروید و دستور زیر را اجرا کنید:

# ایجاد یک پروژه جدید
starport scaffold chain github.com/<username>/<project_name>

در این دستور:

  • <username>: نام کاربری شما در GitHub یا نام دلخواه برای پروژه.
  • <project_name>: نام پروژه شما (بلاکچین جدید).

این دستور به طور خودکار یک پروژه جدید با ساختار استاندارد ایجاد می‌کند و فایل‌های موردنیاز برای یک بلاکچین مبتنی بر Cosmos SDK را در دایرکتوری پروژه قرار می‌دهد.

۳. ساختار پروژه ایجاد شده

پس از اجرای دستور فوق، یک دایرکتوری با نام <project_name> در مسیر جاری ایجاد می‌شود. ساختار این پروژه به شکل زیر است:

<project_name>/
├── app/
├── block/
├── cmd/
├── config/
├── docs/
├── go.mod
├── go.sum
├── main.go
├── proto/
└── starport.yaml

این دایرکتوری‌ها شامل تمامی فایل‌های اصلی و پیکربندی‌های پروژه هستند.

توضیح هر دایرکتوری:

  • app/: این دایرکتوری شامل کدهای اصلی بلاکچین شما است.
  • block/: شامل فایل‌های مربوط به ساختار بلاک‌ها و پردازش آن‌ها می‌باشد.
  • cmd/: این دایرکتوری شامل دستورات CLI برای تعامل با بلاکچین است.
  • config/: فایل‌های پیکربندی بلاکچین، شامل پیکربندی‌های مربوط به شبکه و اجماع.
  • docs/: مستندات پروژه شما.
  • proto/: شامل فایل‌های تعریف پیام‌ها و سرویس‌ها با استفاده از Protocol Buffers است.
  • main.go: فایل ورودی برای شروع اجرای بلاکچین.
  • starport.yaml: فایل پیکربندی پروژه که شامل تنظیمات و ویژگی‌های اصلی بلاکچین است.

۴. پیکربندی فایل‌های پروژه

پس از ایجاد پروژه، ممکن است بخواهید تنظیمات و پیکربندی‌هایی برای بلاکچین خود انجام دهید. برای این کار می‌توانید فایل‌های مختلف پروژه را ویرایش کنید.

ویرایش فایل starport.yaml

فایل starport.yaml شامل تنظیمات پروژه است که می‌توانید آن را ویرایش کنید تا ویژگی‌های پروژه خود را تغییر دهید. برای مثال، می‌توانید نام بلاکچین یا پیکربندی‌های مختلف را در این فایل تنظیم کنید.

برای ویرایش این فایل از دستور زیر استفاده کنید:

# ویرایش فایل starport.yaml
nano <project_name>/starport.yaml

در این فایل می‌توانید پارامترهایی مانند نام پروژه، نسخه بلاکچین و سایر تنظیمات را تغییر دهید.

ویرایش فایل main.go

در فایل main.go که در دایرکتوری اصلی پروژه قرار دارد، فرآیند راه‌اندازی بلاکچین مدیریت می‌شود. برای افزودن تنظیمات یا کدهای دلخواه، می‌توانید این فایل را ویرایش کنید.

برای ویرایش فایل main.go از دستور زیر استفاده کنید:

# ویرایش فایل main.go
nano <project_name>/main.go

۵. اجرای بلاکچین

پس از ایجاد و پیکربندی پروژه خود، برای راه‌اندازی بلاکچین از دستور زیر استفاده کنید:

# راه‌اندازی بلاکچین
starport chain serve

این دستور بلاکچین شما را راه‌اندازی می‌کند و به شما امکان می‌دهد تا به‌طور محلی از آن استفاده کنید. این فرایند شامل راه‌اندازی Tendermint، gRPC و REST API برای تعامل با بلاکچین است.

پس از اجرای این دستور، باید خروجی مشابه زیر را مشاهده کنید:

Starting the chain
Tendermint is running
gRPC server is listening on port 9090
REST API server is listening on port 1317

حالا بلاکچین شما آماده برای تعامل از طریق گراف API، REST API و دستورات CLI است.

۶. تعامل با بلاکچین

برای ارسال تراکنش‌ها یا انجام عملیات‌های مختلف با بلاکچین از CLI استفاده کنید. به‌عنوان مثال، برای ارسال یک تراکنش ساده، از دستور زیر استفاده کنید:

# ارسال تراکنش از طریق CLI
starport tx bank send <from_address> <to_address> <amount> --chain-id=<chain_id>

در این دستور:

  • <from_address>: آدرس فرستنده.
  • <to_address>: آدرس گیرنده.
  • <amount>: مقدار پول (مثلاً 10atom).
  • <chain_id>: شناسه زنجیره بلاکچین شما.

جمع‌بندی

در این بخش، نحوه ایجاد یک پروژه جدید با استفاده از Starport برای ساخت بلاکچین‌های مبتنی بر Cosmos SDK به‌طور کامل بررسی شد. با استفاده از Starport، فرآیند ایجاد بلاکچین بسیار ساده‌تر می‌شود و شما می‌توانید به سرعت پروژه‌های خود را راه‌اندازی کنید.

مراحل کار شامل نصب Starport، ایجاد پروژه جدید، پیکربندی فایل‌ها، و اجرای بلاکچین با استفاده از دستورات ساده بود. همچنین، نحوه تعامل با بلاکچین از طریق CLI نیز توضیح داده شد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی ساختار دایرکتوری پروژه” subtitle=”توضیحات کامل”]در توسعه بلاک‌چین با استفاده از Cosmos SDK، ساختار دایرکتوری پروژه یکی از بخش‌های حیاتی است که می‌تواند بر کارایی و مقیاس‌پذیری پروژه تاثیر زیادی بگذارد. پروژه‌های بلاک‌چین مبتنی بر Cosmos SDK از ساختار مشخصی پیروی می‌کنند تا قابلیت توسعه، مدیریت، و سازمان‌دهی بهتر کدها را فراهم آورند. در این بخش، به بررسی ساختار دایرکتوری پروژه Cosmos SDK و اجزای آن می‌پردازیم و تنظیمات و پیکربندی‌های مختلف را به‌صورت کامندی و گرافیکی توضیح می‌دهیم.


ساختار دایرکتوری پروژه

در پروژه‌های بلاک‌چین مبتنی بر Cosmos SDK، ساختار دایرکتوری به‌طور معمول شامل بخش‌های زیر است:

my-blockchain/
│
├── app/
│   └── app.go
│   └── genesis.go
│   └── module_manager.go
│
├── cmd/
│   └── myblockchaind/
│       └── main.go
│
├── x/
│   └── mymodule/
│       └── handler.go
│       └── keeper.go
│       └── types.go
│       └── module.go
│
├── scripts/
│   └── init.sh
│   └── start.sh
│
├── config/
│   └── config.yaml
│
├── go.mod
└── go.sum

این ساختار استاندارد Cosmos SDK است که در آن چندین دایرکتوری و فایل اصلی وجود دارد:

  1. app/: این دایرکتوری حاوی فایل‌های اصلی برای پیکربندی برنامه و مدیریت وضعیت برنامه است. از جمله فایل‌هایی مانند app.go که معمولا برای راه‌اندازی و پیکربندی بلاک‌چین استفاده می‌شود.
  2. cmd/: دایرکتوری اصلی برای اجرای سرور است و معمولا شامل فایل‌های main.go برای راه‌اندازی و مدیریت سرور Cosmos SDK است.
  3. x/: دایرکتوری که حاوی ماژول‌های مختلف بلاک‌چین است. هر ماژول مانند myblockchain یا mymodule به‌طور جداگانه در این دایرکتوری قرار می‌گیرد.
  4. scripts/: اسکریپت‌ها برای انجام اقدامات خودکار مانند راه‌اندازی سرور یا پیکربندی بلاک‌چین.
  5. config/: فایل‌های پیکربندی برای بلاک‌چین. در اینجا، می‌توانید فایل‌های YAML یا TOML را برای تنظیمات شبکه، امنیت و پیکربندی‌های دیگر پیدا کنید.

توضیح هر بخش از ساختار دایرکتوری

  1. app/:
    • app.go: این فایل اصلی‌ترین بخش پیکربندی بلاک‌چین شما را در بر می‌گیرد. شما می‌توانید ماژول‌ها را در این فایل بارگذاری کرده و شبکه بلاک‌چین خود را تنظیم کنید.
    • genesis.go: این فایل برای مدیریت داده‌های اولیه بلاک‌چین است.
    • module_manager.go: در این فایل، ماژول‌های مختلف بلاک‌چین بارگذاری می‌شوند و مدیریت می‌شوند.
  2. cmd/:
    • main.go: این فایل نقطه شروع اجرای بلاک‌چین است. از اینجا سرور بلاک‌چین اجرا شده و ماژول‌ها و سایر تنظیمات راه‌اندازی می‌شوند.
  3. x/:
    • این دایرکتوری به‌طور کلی شامل ماژول‌های بلاک‌چین است که می‌تواند شامل عملکردهایی مانند تراکنش‌ها، کنتراکت‌های هوشمند و دیگر ویژگی‌های خاص باشد.
    • handler.go: کدی برای پردازش تراکنش‌ها و عملکردهای خاص ماژول.
    • keeper.go: منطق مربوط به ذخیره‌سازی داده‌ها و تعامل با پایگاه‌داده.
    • module.go: نقطه آغاز ماژول که مسئول بارگذاری و مدیریت عملکردهای مختلف ماژول است.
  4. scripts/:
    • این دایرکتوری شامل اسکریپت‌های مختلف برای راه‌اندازی و مدیریت بلاک‌چین است.
    • اسکریپت‌های init.sh و start.sh می‌توانند برای پیکربندی بلاک‌چین و شروع شبکه استفاده شوند.
  5. config/:
    • در این دایرکتوری، می‌توانید فایل‌های پیکربندی مانند config.yaml یا config.toml را پیدا کنید که برای تنظیمات شبکه بلاک‌چین مورد استفاده قرار می‌گیرند.

دستورات و پیکربندی‌های کامندی

  1. ایجاد پروژه جدید با Cosmos SDK: برای ایجاد یک پروژه جدید با استفاده از Cosmos SDK از دستور زیر استفاده کنید:
    starport app github.com/my-blockchain
    

    این دستور یک پروژه جدید در دایرکتوری فعلی شما ایجاد می‌کند و ساختار اولیه پروژه را در همان دایرکتوری قرار می‌دهد.

  2. پیکربندی فایل app.go: برای اضافه کردن ماژول‌ها به پروژه خود، فایل app.go را ویرایش کرده و ماژول‌ها را در آن بارگذاری کنید. اینکار را می‌توانید با دستور زیر انجام دهید:
    nano app/app.go
    

    سپس ماژول‌های دلخواه خود را به آن اضافه کنید:

    moduleManager.RegisterModule(module.NewAppModule())
    
  3. ساخت ماژول جدید: برای ایجاد یک ماژول جدید با استفاده از دستور زیر در دایرکتوری x/ می‌توانید یک ماژول جدید بسازید:
    starport module create mymodule --no-module
    

    این دستور یک ماژول جدید به نام mymodule در دایرکتوری x/ ایجاد می‌کند.

  4. تنظیمات پیکربندی در فایل config.yaml: برای پیکربندی تنظیمات شبکه بلاک‌چین، فایل config/config.yaml را باز کرده و تغییرات لازم را اعمال کنید:
    nano config/config.yaml
    

    در این فایل می‌توانید مواردی مانند پیکربندی نود، تنظیمات امنیتی و موارد دیگر را تنظیم کنید.


جمع‌بندی

در این بخش، به بررسی ساختار دایرکتوری پروژه در Cosmos SDK پرداختیم و نحوه پیکربندی هر یک از اجزای آن را بررسی کردیم. همچنین، دستورات و پیکربندی‌های لازم برای تنظیم پروژه و توسعه ماژول‌ها به‌صورت کامندی و گرافیکی توضیح داده شد. این اطلاعات به شما کمک می‌کند تا بتوانید پروژه بلاک‌چین خود را به‌خوبی مدیریت و پیکربندی کنید و مراحل توسعه را به‌طور مؤثر پیش ببرید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تعریف اولین ماژول سفارشی در Cosmos SDK” subtitle=”توضیحات کامل”]در Cosmos SDK، ماژول‌ها بخش‌های مهم و قابل گسترش بلاک‌چین هستند که مسئولیت پیاده‌سازی ویژگی‌های خاص مانند تراکنش‌ها، کوین‌ها، و غیره را بر عهده دارند. برای ایجاد اولین ماژول سفارشی در Cosmos SDK، شما باید چندین مرحله را طی کنید که شامل تعریف منطق ماژول، ایجاد فایل‌های لازم، و سپس ثبت ماژول در اپلیکیشن بلاک‌چین است. در این بخش، نحوه ساخت اولین ماژول سفارشی در Cosmos SDK به‌طور گام‌به‌گام توضیح داده می‌شود.


مراحل ایجاد اولین ماژول سفارشی در Cosmos SDK

  1. ایجاد پروژه جدید: ابتدا باید پروژه‌ای جدید با استفاده از دستور starport ایجاد کنید تا ساختار اولیه پروژه Cosmos SDK آماده شود.دستور زیر پروژه جدید را با نام my-blockchain ایجاد می‌کند:
    starport app github.com/my-blockchain
    

    پس از اجرای این دستور، ساختار دایرکتوری پروژه شما ایجاد می‌شود.

  2. ایجاد ماژول جدید: برای ایجاد یک ماژول جدید در پروژه، می‌توانید از دستور starport module create استفاده کنید. این دستور به‌طور خودکار فایل‌های لازم برای ماژول را ایجاد می‌کند.برای ایجاد اولین ماژول سفارشی با نام mymodule، از دستور زیر استفاده کنید:
    starport module create mymodule
    

    این دستور یک ماژول جدید به نام mymodule در دایرکتوری x/ ایجاد می‌کند. این ماژول شامل چندین فایل پایه مانند handler.go, keeper.go, و types.go خواهد بود.

  3. ویرایش فایل‌های ماژول: پس از ایجاد ماژول، باید فایل‌های مختلف ماژول را ویرایش کنید تا منطق دلخواه خود را پیاده‌سازی کنید.
    1. ایجاد فایل types.go: در این فایل، شما نوع داده‌های ماژول خود را تعریف می‌کنید. به‌عنوان مثال، می‌توانید یک ساختار برای داده‌های تراکنش‌ها یا وضعیت ماژول تعریف کنید.فایل x/mymodule/types.go را ویرایش کرده و ساختارهای خود را اضافه کنید:
      package mymodule
      
      import (
          sdk "github.com/cosmos/cosmos-sdk/types"
      )
      
      // MsgMyTransaction represents a transaction in the mymodule.
      type MsgMyTransaction struct {
          Sender   sdk.AccAddress `json:"sender" yaml:"sender"`
          Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
          Amount   sdk.Coins      `json:"amount" yaml:"amount"`
      }
      
    2. ویرایش فایل keeper.go: در این فایل، شما منطق ذخیره‌سازی و مدیریت وضعیت ماژول را پیاده‌سازی می‌کنید. به‌عنوان مثال، شما می‌توانید این فایل را برای ذخیره تراکنش‌ها و اطلاعات مربوط به آن‌ها ویرایش کنید.فایل x/mymodule/keeper.go را ویرایش کنید:
      package mymodule
      
      import (
          sdk "github.com/cosmos/cosmos-sdk/types"
          "github.com/cosmos/cosmos-sdk/x/staking/types"
      )
      
      type Keeper struct {
          storeKey sdk.StoreKey
      }
      
      func NewKeeper(storeKey sdk.StoreKey) Keeper {
          return Keeper{
              storeKey: storeKey,
          }
      }
      
      // SetTransaction stores a transaction in the keeper.
      func (k Keeper) SetTransaction(ctx sdk.Context, tx MsgMyTransaction) {
          store := ctx.KVStore(k.storeKey)
          store.Set([]byte(tx.Sender.String()), []byte(tx.Amount.String()))
      }
      
    3. ویرایش فایل handler.go: در این فایل، شما منطق پردازش تراکنش‌ها و دیگر عملیات را پیاده‌سازی می‌کنید. برای این‌که تراکنش‌ها را پردازش کنید، باید آن‌ها را در این فایل مدیریت کنید.فایل x/mymodule/handler.go را ویرایش کرده و کد زیر را اضافه کنید:
      package mymodule
      
      import (
          sdk "github.com/cosmos/cosmos-sdk/types"
      )
      
      func NewHandler(k Keeper) sdk.Handler {
          return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
              switch msg := msg.(type) {
              case MsgMyTransaction:
                  k.SetTransaction(ctx, msg)
                  return &sdk.Result{}, nil
              default:
                  return nil, sdk.ErrUnknownRequest("unrecognized mymodule message type")
              }
          }
      }
      
  4. ثبت ماژول در اپلیکیشن بلاک‌چین: پس از ایجاد و ویرایش ماژول، باید ماژول را در اپلیکیشن بلاک‌چین خود ثبت کنید تا بلاک‌چین از آن استفاده کند.برای این کار، فایل app.go را ویرایش کرده و ماژول را ثبت کنید. این کار را به‌صورت زیر انجام دهید:
    package app
    
    import (
        "github.com/my-blockchain/x/mymodule"
        "github.com/cosmos/cosmos-sdk/types/module"
    )
    
    func (app *MyBlockchainApp) ModuleBasics() []module.AppModuleBasic {
        return []module.AppModuleBasic{
            mymodule.AppModuleBasic{},
        }
    }
    
    func (app *MyBlockchainApp) Modules() []module.AppModule {
        return []module.AppModule{
            mymodule.NewAppModule(app.mymoduleKeeper),
        }
    }
    
  5. ساخت و اجرای پروژه: پس از ثبت ماژول، شما باید پروژه خود را کامپایل و اجرا کنید. برای این کار از دستورات زیر استفاده کنید:
    go build
    

    سپس، بلاک‌چین خود را با استفاده از دستور starport یا دستورات اجرایی دیگر راه‌اندازی کنید:

    starport serve
    

جمع‌بندی

در این بخش، نحوه تعریف اولین ماژول سفارشی در Cosmos SDK را بررسی کردیم. شما یاد گرفتید که چگونه یک ماژول جدید ایجاد کنید، فایل‌های مربوط به آن را ویرایش کرده و در نهایت آن را در اپلیکیشن بلاک‌چین ثبت کنید. همچنین، دستورات کامندی مورد نیاز برای ایجاد و پیکربندی ماژول نیز ارائه شد. این مراحل به شما کمک می‌کنند تا اولین ماژول سفارشی خود را به‌راحتی توسعه دهید و آن را در بلاک‌چین Cosmos SDK خود پیاده‌سازی کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”کامپایل و اجرای بلاکچین محلی” subtitle=”توضیحات کامل”]برای اجرای بلاک‌چین محلی در Cosmos SDK، باید چندین مرحله را دنبال کنید. در این بخش، فرآیند کامپایل و راه‌اندازی بلاک‌چین محلی را به‌طور گام‌به‌گام بررسی خواهیم کرد. این کار شامل ساخت پروژه، تنظیمات لازم برای بلاک‌چین محلی، و اجرای آن به‌صورت سرور محلی است.


مراحل کامپایل و اجرای بلاکچین محلی

  1. نصب وابستگی‌ها: ابتدا باید مطمئن شوید که تمامی وابستگی‌های لازم برای Cosmos SDK در سیستم شما نصب شده است. این شامل Go، Cosmos SDK، و ابزارهای دیگر مانند starport است.
    1. نصب Go: برای نصب Go، به وب‌سایت رسمی Go مراجعه کنید و آخرین نسخه آن را دانلود و نصب کنید:
      https://golang.org/dl/سپس، محیط Go را به‌صورت زیر تنظیم کنید:

      export GOPATH=$HOME/go
      export GOROOT=/usr/local/go
      export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
      
    2. نصب Cosmos SDK: برای نصب Cosmos SDK، از دستور زیر استفاده کنید:
      git clone https://github.com/cosmos/cosmos-sdk.git
      cd cosmos-sdk
      make install
      
    3. نصب Starport: برای نصب Starport، از دستور زیر استفاده کنید:
      curl https://get.starport.network/starport! | bash
      
  2. ایجاد پروژه و ماژول: حالا که ابزارهای لازم را نصب کرده‌اید، می‌توانید پروژه بلاک‌چین خود را ایجاد کنید. ابتدا پروژه‌ای جدید با استفاده از Starport ایجاد کنید:
    starport app github.com/my-blockchain
    

    سپس، ماژول دلخواه خود را ایجاد کنید:

    starport module create mymodule
    

    این دستورات یک پروژه بلاک‌چین جدید به نام my-blockchain و ماژول mymodule ایجاد می‌کنند.

  3. ویرایش و پیکربندی پروژه: پس از ایجاد پروژه و ماژول، باید آن‌ها را ویرایش کرده و منطق مورد نظر خود را برای بلاک‌چین تنظیم کنید. این شامل اضافه کردن نوع داده‌ها، تراکنش‌ها، و نگهداری اطلاعات است که قبلاً در مراحل پیشین توضیح داده شد.پس از ویرایش پروژه، باید ماژول خود را در فایل app.go ثبت کنید:
    package app
    
    import (
        "github.com/my-blockchain/x/mymodule"
        "github.com/cosmos/cosmos-sdk/types/module"
    )
    
    func (app *MyBlockchainApp) ModuleBasics() []module.AppModuleBasic {
        return []module.AppModuleBasic{
            mymodule.AppModuleBasic{},
        }
    }
    
    func (app *MyBlockchainApp) Modules() []module.AppModule {
        return []module.AppModule{
            mymodule.NewAppModule(app.mymoduleKeeper),
        }
    }
    
  4. ساخت بلاکچین: پس از تنظیم و پیکربندی پروژه، می‌توانید بلاک‌چین خود را کامپایل کنید. برای این کار از دستور go build استفاده کنید:
    go build
    

    این دستور فایل باینری بلاک‌چین شما را ایجاد می‌کند.

  5. ایجاد و تنظیم شبکه محلی: برای راه‌اندازی بلاک‌چین محلی، شما باید یک شبکه محلی (local network) بسازید. Starport این امکان را فراهم می‌کند تا با یک دستور ساده شبکه محلی را راه‌اندازی کنید.ابتدا، یک مسیر جدید برای شبکه محلی ایجاد کنید:
    starport chain init mychain
    

    سپس، بلاک‌چین محلی را پیکربندی کنید. فایل پیکربندی config.toml را ویرایش کرده و تنظیمات مورد نیاز خود را اعمال کنید.

  6. اجرای بلاک‌چین محلی: برای اجرای بلاک‌چین محلی، از دستور starport serve استفاده کنید:
    starport serve
    

    این دستور بلاک‌چین محلی شما را راه‌اندازی می‌کند و آن را برای استفاده و آزمایش آماده می‌سازد.

    با اجرای این دستور، شبکه محلی بلاک‌چین شما راه‌اندازی می‌شود و می‌توانید به آن متصل شوید.

  7. اتصال به بلاک‌چین محلی: پس از راه‌اندازی بلاک‌چین محلی، شما می‌توانید از ابزارهای مختلف مانند gaiad یا starport برای ارسال تراکنش‌ها و تعامل با بلاک‌چین استفاده کنید.برای ایجاد حساب و ارسال تراکنش، می‌توانید دستورات زیر را وارد کنید:
    1. ایجاد حساب جدید:
      starport cli keys add mykey
      
    2. انتقال کوین‌ها: برای ارسال کوین به یک حساب دیگر، از دستور زیر استفاده کنید:
      starport cli tx send mykey <to_address> 100stake --fees 500nsm
      

جمع‌بندی

در این بخش، مراحل کامپایل و اجرای بلاک‌چین محلی در Cosmos SDK به‌طور کامل توضیح داده شد. شما یاد گرفتید که چگونه پروژه و ماژول خود را ایجاد و پیکربندی کنید، سپس بلاک‌چین محلی خود را بسازید و اجرا کنید. همچنین، دستورات لازم برای ساخت و پیکربندی بلاک‌چین محلی، ایجاد حساب‌های جدید و ارسال تراکنش‌ها نیز در این بخش آورده شد. این مراحل به شما کمک می‌کنند تا بلاک‌چین خود را به‌راحتی در محیط محلی توسعه دهید و آن را آزمایش کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ثبت اولین تراکنش و بررسی لاگ‌های سیستم” subtitle=”توضیحات کامل”]در این بخش، به نحوه ثبت اولین تراکنش در بلاک‌چین ساخته‌شده با Cosmos SDK و بررسی لاگ‌های سیستم برای تحلیل عملکرد تراکنش‌ها پرداخته می‌شود. ثبت تراکنش‌ها و بررسی لاگ‌ها از اهمیت زیادی برخوردار هستند زیرا این فرآیندها به شما امکان می‌دهند تا مشکلات را شناسایی کرده و عملکرد بلاک‌چین را تحلیل کنید.


1. ثبت اولین تراکنش

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

1.1 ایجاد حساب جدید

برای ایجاد حساب جدید در بلاک‌چین محلی خود، از دستور starport cli استفاده کنید. این دستور یک کلید خصوصی و عمومی برای شما ایجاد می‌کند:

starport cli keys add mykey

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

1.2 ارسال تراکنش

پس از ایجاد حساب، می‌توانید برای ارسال کوین‌ها به حساب دیگر از دستور starport cli tx send استفاده کنید. به‌عنوان مثال، برای ارسال 100 واحد از کوین‌ها به یک حساب دیگر از دستور زیر استفاده می‌شود:

starport cli tx send mykey <to_address> 100stake --fees 500nsm

در این دستور:

  • mykey نام حساب مبدا است.
  • <to_address> آدرس مقصد است که باید به‌جای آن آدرس واقعی مقصد قرار گیرد.
  • 100stake مقدار کوین‌هایی است که باید ارسال شوند.
  • 500nsm کارمزد تراکنش است.

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

1.3 تایید تراکنش

برای بررسی وضعیت تراکنش، از دستور starport cli query tx استفاده کنید:

starport cli query tx <tx_hash>

جایگزین کنید <tx_hash> با شناسه تراکنش که در نتیجه ارسال تراکنش به شما نمایش داده شده است. این دستور وضعیت تراکنش و جزئیات آن را نمایش می‌دهد.


2. بررسی لاگ‌های سیستم

لاگ‌های سیستم یکی از مهم‌ترین منابع برای بررسی عملکرد بلاک‌چین و شناسایی مشکلات هستند. Cosmos SDK از ابزارهای مختلفی برای مدیریت لاگ‌ها استفاده می‌کند. این لاگ‌ها اطلاعاتی در مورد وضعیت تراکنش‌ها، بلاک‌ها و وضعیت سیستم به‌طور کلی ارائه می‌دهند.

2.1 فعال‌سازی لاگ‌ها

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

مسیر فایل پیکربندی به‌صورت پیش‌فرض به این شکل است:

~/.myblockchain/config/config.toml

در این فایل، قسمت log_level را به‌صورت زیر تنظیم کنید تا تمام جزئیات و اطلاعات لاگ در کنسول نمایش داده شود:

log_level = "debug"

این تنظیم باعث می‌شود که تمامی اطلاعات مربوط به تراکنش‌ها و عملیات‌های دیگر با جزئیات زیاد در لاگ‌ها نمایش داده شوند.

2.2 مشاهده لاگ‌ها

برای مشاهده لاگ‌های بلاک‌چین، از دستور tail استفاده می‌شود تا جدیدترین لاگ‌ها را مشاهده کنید:

tail -f ~/.myblockchain/data/logs/gaia.log

این دستور تمامی خط‌های جدید لاگ را در زمان واقعی نمایش می‌دهد. از این طریق می‌توانید وضعیت تراکنش‌ها، اضافه‌شدن بلاک‌ها به زنجیره، و خطاها را بررسی کنید.

2.3 تجزیه‌وتحلیل لاگ‌ها

در لاگ‌های سیستم اطلاعات مختلفی مانند موفقیت یا شکست تراکنش‌ها، اضافه‌شدن بلاک‌های جدید، و خطاهای احتمالی وجود دارد. برای تجزیه‌وتحلیل این لاگ‌ها می‌توانید به موارد زیر توجه کنید:

  • خطاهای شبکه: اگر بلاک‌چین شما به‌درستی کار نمی‌کند، ممکن است خطاهایی مانند “connection refused” یا “timeout” مشاهده کنید.
  • تراکنش‌های موفق: وقتی تراکنش با موفقیت ثبت می‌شود، پیامی مشابه این مشاهده خواهید کرد:
    INFO [2025-03-05|14:32:14.192] tx sent successfully
    
  • خطاهای تراکنش: اگر تراکنش با خطا مواجه شود، پیامی مشابه این مشاهده خواهید کرد:
    ERROR [2025-03-05|14:32:15.404] failed to send tx
    

این لاگ‌ها به شما کمک می‌کنند تا مشکلات موجود در بلاک‌چین و تراکنش‌ها را شناسایی کرده و اقدام به رفع آن‌ها کنید.


جمع‌بندی

در این بخش، فرآیند ثبت اولین تراکنش در بلاک‌چین ساخته‌شده با Cosmos SDK بررسی شد. شما یاد گرفتید که چگونه حساب جدیدی ایجاد کنید، تراکنش ارسال کنید، و وضعیت آن را بررسی کنید. همچنین، نحوه فعال‌سازی و مشاهده لاگ‌های سیستم نیز توضیح داده شد. این اطلاعات به شما کمک می‌کند تا تراکنش‌ها را مدیریت کرده و به تحلیل عملکرد بلاک‌چین بپردازید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. مدیریت کیف پول و کلیدهای رمزنگاری در Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ایجاد کیف پول و مدیریت کلیدها با cosmosd keys” subtitle=”توضیحات کامل”]در این بخش، نحوه ایجاد کیف پول و مدیریت کلیدها با استفاده از ابزار cosmosd keys که در بلاک‌چین Cosmos SDK قرار دارد، مورد بررسی قرار می‌گیرد. این ابزار به شما این امکان را می‌دهد که کلیدهای خصوصی و عمومی مربوط به حساب‌های بلاک‌چین خود را مدیریت کرده و به‌راحتی تراکنش‌ها را انجام دهید.


1. نصب و راه‌اندازی cosmosd

ابتدا باید مطمئن شوید که ابزار cosmosd به‌درستی روی سیستم شما نصب شده است. برای نصب Cosmos SDK و ابزار cosmosd، می‌توانید از دستور زیر استفاده کنید:

git clone https://github.com/cosmos/cosmos-sdk.git
cd cosmos-sdk
make install

این دستور Cosmos SDK را روی سیستم شما نصب می‌کند. پس از نصب، می‌توانید از دستور cosmosd برای انجام عملیات‌های مختلف بلاک‌چین استفاده کنید.


2. ایجاد کیف پول (کیف پول جدید)

برای ایجاد یک کیف پول جدید با استفاده از cosmosd keys, ابتدا باید به دایرکتوری مربوط به بلاک‌چین خود بروید. فرض کنید که بلاک‌چین شما نامی مانند myblockchain دارد.

مسیر فایل‌های پیکربندی معمولاً به این صورت است:

~/.myblockchain/config/

برای ایجاد کیف پول جدید، از دستور زیر استفاده کنید:

cosmosd keys add mykey

در این دستور:

  • mykey نام کیف پول جدید شماست. شما می‌توانید این نام را به هر نام دلخواه تغییر دهید.

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

- name: mykey
  type: local
  address: cosmos1xyzabc...
  pubkey: cosmospub1xyzabc...
  mnemonic: "... (mnemonic phrase)"
  local_key: cosmos1xyzabc...

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


3. مشاهده کیف پول‌ها و کلیدها

برای مشاهده کیف پول‌ها و کلیدهای موجود در بلاک‌چین خود، از دستور زیر استفاده کنید:

cosmosd keys list

این دستور فهرستی از کیف پول‌های موجود را نمایش می‌دهد، به همراه آدرس‌های عمومی و عمومی‌های آن‌ها.


4. ارسال تراکنش از کیف پول

پس از ایجاد کیف پول و بررسی جزئیات آن، می‌توانید از این کیف پول برای ارسال تراکنش به آدرس‌های دیگر استفاده کنید. برای ارسال کوین‌ها از یک کیف پول به کیف پول دیگر، از دستور زیر استفاده کنید:

cosmosd tx send mykey <to_address> 100stake --fees 500nsm --chain-id=myblockchain

در این دستور:

  • mykey نام کیف پول مبدا است.
  • <to_address> آدرس مقصد است که باید آن را جایگزین کنید.
  • 100stake مقدار کوین‌هایی است که باید ارسال شوند.
  • 500nsm کارمزد تراکنش است.
  • --chain-id=myblockchain برای تعیین شناسه زنجیره بلاک‌چین شما است.

پس از ارسال تراکنش، تراکنش در بلاک‌چین ثبت خواهد شد و می‌توانید وضعیت آن را بررسی کنید.


5. بازیابی کیف پول با استفاده از عبارت Mnemonic

اگر بخواهید کیف پول خود را بازیابی کنید، می‌توانید از عبارت Mnemonic که هنگام ایجاد کیف پول دریافت کرده‌اید استفاده کنید. برای اینکار از دستور زیر استفاده کنید:

cosmosd keys add mykey --recover

سپس باید عبارت Mnemonic خود را وارد کنید تا کیف پول بازیابی شود. این فرایند برای جلوگیری از از دست رفتن کیف پول‌های شما بسیار مهم است.


6. حذف کیف پول

اگر بخواهید یک کیف پول را از سیستم حذف کنید، می‌توانید از دستور زیر استفاده کنید:

cosmosd keys delete mykey

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


جمع‌بندی

در این بخش، نحوه ایجاد کیف پول و مدیریت کلیدها با استفاده از ابزار cosmosd keys را یاد گرفتیم. این ابزار به شما این امکان را می‌دهد که کیف پول‌های مختلف ایجاد کرده، تراکنش‌ها را ارسال کنید و در صورت لزوم کیف پول‌ها را بازیابی یا حذف کنید. همچنین، مشاهده کیف پول‌های موجود و مدیریت کلیدهای خصوصی به‌راحتی با استفاده از این ابزار امکان‌پذیر است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”تولید و بازیابی کلیدهای خصوصی و عمومی” subtitle=”توضیحات کامل”]در این بخش، نحوه تولید و بازیابی کلیدهای خصوصی و عمومی در بلاک‌چین Cosmos SDK با استفاده از ابزار cosmosd بررسی خواهد شد. این فرآیند برای مدیریت کلیدهای خصوصی و عمومی ضروری است، زیرا از این کلیدها برای امضای تراکنش‌ها و تعامل با بلاک‌چین استفاده می‌شود.


1. تولید کلیدهای خصوصی و عمومی

برای تولید کلیدهای خصوصی و عمومی، از دستور cosmosd keys add استفاده می‌شود. این دستور به شما امکان می‌دهد که یک کیف پول جدید بسازید و به‌طور خودکار کلیدهای خصوصی و عمومی تولید کنید.

برای تولید یک کلید جدید، از دستور زیر استفاده کنید:

cosmosd keys add mykey

در این دستور:

  • mykey نام کلیدی است که می‌خواهید تولید کنید. این نام را می‌توانید به دلخواه تغییر دهید.

پس از اجرای این دستور، اطلاعات زیر به شما نمایش داده می‌شود:

- name: mykey
  type: local
  address: cosmos1xyzabc...
  pubkey: cosmospub1xyzabc...
  mnemonic: "... (mnemonic phrase)"
  local_key: cosmos1xyzabc...

در اینجا:

  • address: آدرس عمومی کیف پول شما است که می‌توانید برای دریافت کوین از آن استفاده کنید.
  • pubkey: کلید عمومی شما است که برای تایید تراکنش‌ها استفاده می‌شود.
  • mnemonic: عبارت بازیابی کیف پول است که باید به‌دقت ذخیره شود.
  • local_key: کلید خصوصی شما است که برای امضای تراکنش‌ها و مدیریت کیف پول استفاده می‌شود.

2. مشاهده کلیدهای موجود

برای مشاهده کلیدهای خصوصی و عمومی که در سیستم شما ذخیره شده‌اند، از دستور زیر استفاده کنید:

cosmosd keys list

این دستور فهرستی از کیف پول‌ها و کلیدهای موجود در سیستم شما نمایش می‌دهد.


3. بازیابی کیف پول با استفاده از عبارت Mnemonic

اگر عبارت Mnemonic کیف پول خود را ذخیره کرده‌اید و بخواهید کیف پول را بازیابی کنید، می‌توانید از دستور زیر استفاده کنید:

cosmosd keys add mykey --recover

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


4. بازیابی کیف پول با استفاده از کلید خصوصی

در صورتی که کلید خصوصی خود را دارید و بخواهید کیف پول را بازیابی کنید، می‌توانید از دستور زیر استفاده کنید:

cosmosd keys import mykey /path/to/private.key

در این دستور:

  • mykey نام کیف پول است.
  • /path/to/private.key مسیری است که کلید خصوصی شما در آن قرار دارد.

با این دستور، کیف پول شما با استفاده از کلید خصوصی بازیابی خواهد شد.


5. حذف کیف پول

برای حذف یک کیف پول از سیستم، از دستور زیر استفاده کنید:

cosmosd keys delete mykey

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


جمع‌بندی

در این بخش، نحوه تولید و بازیابی کلیدهای خصوصی و عمومی با استفاده از ابزار cosmosd keys در بلاک‌چین Cosmos SDK بررسی شد. این ابزار به شما این امکان را می‌دهد که کلیدهای خصوصی و عمومی را به‌راحتی تولید، بازیابی و حذف کنید. همچنین، برای حفظ امنیت، ذخیره‌سازی عبارت Mnemonic و کلید خصوصی بسیار مهم است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”ارسال توکن‌های آزمایشی و بررسی وضعیت حساب‌ها” subtitle=”توضیحات کامل”]در این بخش، نحوه ارسال توکن‌های آزمایشی در بلاک‌چین Cosmos SDK و همچنین بررسی وضعیت حساب‌ها با استفاده از دستورات مختلف بررسی می‌شود. این مراحل برای آزمایش تراکنش‌ها و مدیریت حساب‌ها در محیط بلاک‌چین ضروری هستند.


1. ارسال توکن‌های آزمایشی

برای ارسال توکن‌های آزمایشی از یک کیف پول به کیف پول دیگر، از دستور cosmosd tx send استفاده می‌شود. این دستور به شما این امکان را می‌دهد که تراکنش‌هایی با استفاده از کوین‌های موجود در حساب خود ایجاد کنید.

دستور ارسال توکن:
cosmosd tx send mykey cosmos1destinationaddress 1000uatom --chain-id=testnet --fees=500uatom --yes

در این دستور:

  • mykey: نام کیف پول فرستنده که توکن‌ها از آن ارسال می‌شوند.
  • cosmos1destinationaddress: آدرس کیف پول مقصد که توکن‌ها به آن ارسال می‌شود.
  • 1000uatom: مقدار توکن‌هایی که ارسال می‌شود. uatom واحد توکن در شبکه Cosmos است.
  • --chain-id=testnet: شناسه زنجیره‌ای که تراکنش در آن اجرا می‌شود. در اینجا از تست‌نت استفاده شده است.
  • --fees=500uatom: هزینه‌ای که برای اجرای تراکنش باید پرداخت شود.
  • --yes: تایید خودکار تراکنش بدون نیاز به تایید دستی.

پس از اجرای این دستور، تراکنش شما به شبکه ارسال شده و به‌صورت غیرمتمرکز پردازش می‌شود.


2. بررسی وضعیت تراکنش‌ها

برای بررسی وضعیت تراکنش ارسال‌شده، از دستور cosmosd query tx استفاده می‌شود. این دستور به شما اطلاعاتی از جمله موفقیت یا شکست تراکنش را نشان می‌دهد.

دستور بررسی وضعیت تراکنش:
cosmosd query tx <transaction_hash>

در این دستور:

  • <transaction_hash> باید به جای شناسه تراکنش واقعی که پس از ارسال به شما داده می‌شود، قرار گیرد. این شناسه را می‌توانید از نتیجه دستور ارسال توکن بدست آورید.

این دستور جزئیات تراکنش شامل وضعیت، زمان، و نتایج آن را نمایش خواهد داد.


3. بررسی وضعیت حساب‌ها

برای بررسی موجودی حساب‌ها و مشاهده توکن‌های موجود در یک کیف پول، از دستور cosmosd query bank balances استفاده می‌شود.

دستور بررسی موجودی حساب:
cosmosd query bank balances cosmos1address

در این دستور:

  • cosmos1address: آدرس کیف پول که می‌خواهید موجودی آن را بررسی کنید.

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

balances:
  - denom: uatom
    amount: "5000"

4. بررسی وضعیت کیف پول‌ها

برای بررسی وضعیت کلی کیف پول‌های ایجادشده، از دستور cosmosd keys list استفاده می‌شود. این دستور فهرستی از کیف پول‌ها و آدرس‌های مرتبط با آنها را به شما نمایش می‌دهد.

دستور بررسی وضعیت کیف پول‌ها:
cosmosd keys list

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


جمع‌بندی

در این بخش، نحوه ارسال توکن‌های آزمایشی در بلاک‌چین Cosmos SDK و بررسی وضعیت تراکنش‌ها و حساب‌ها با استفاده از دستورات مختلف توضیح داده شد. با استفاده از دستور cosmosd tx send می‌توانید توکن‌ها را ارسال کنید و از دستور cosmosd query tx وضعیت تراکنش‌ها را بررسی کنید. همچنین، با دستور cosmosd query bank balances می‌توانید موجودی حساب‌ها را مشاهده کنید و با cosmosd keys list وضعیت کلی کیف پول‌ها را بررسی نمایید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی نحوه امضای تراکنش‌ها و امنیت کلیدهای خصوصی” subtitle=”توضیحات کامل”]امضای تراکنش‌ها و حفظ امنیت کلیدهای خصوصی دو جنبه مهم در بلاک‌چین‌ها هستند. امضای دیجیتال برای تایید اصالت تراکنش‌ها و جلوگیری از دستکاری داده‌ها استفاده می‌شود. کلید خصوصی نیز به عنوان ابزاری برای امضای تراکنش‌ها و دسترسی به دارایی‌های دیجیتال به حساب می‌آید. در این بخش، نحوه امضای تراکنش‌ها در بلاک‌چین Cosmos SDK و اهمیت امنیت کلیدهای خصوصی بررسی خواهد شد.


1. امضای تراکنش‌ها

در بلاک‌چین Cosmos SDK، امضای تراکنش‌ها به این معناست که یک کیف پول از کلید خصوصی خود برای امضای تراکنش و تأیید هویت استفاده می‌کند. این فرآیند به شکلی است که فقط دارنده کلید خصوصی قادر به ارسال و امضای تراکنش‌ها است.

برای امضای تراکنش‌ها در Cosmos SDK، ابتدا باید تراکنش را با استفاده از کیف پول خود ایجاد کرده و سپس با استفاده از دستور cosmosd tx sign آن را امضا کنید.

مراحل امضای تراکنش:
  1. ایجاد تراکنش: ابتدا یک تراکنش جدید ایجاد کنید. برای این کار می‌توانید از دستور cosmosd tx send استفاده کنید که در بخش قبلی توضیح داده شد.
  2. امضای تراکنش:برای امضای تراکنش باید از دستور cosmosd tx sign استفاده کنید. این دستور برای امضای تراکنش و ایجاد فایل امضا شده کاربرد دارد.
    cosmosd tx sign <path_to_transaction_file> --from=mykey --chain-id=testnet --fees=500uatom --yes --output-document=<path_to_signed_transaction_file>
    

    در این دستور:

    • <path_to_transaction_file>: مسیر فایل تراکنش که قصد دارید آن را امضا کنید.
    • mykey: نام کیف پول فرستنده که تراکنش با آن امضا خواهد شد.
    • --chain-id=testnet: شناسه زنجیره‌ای که تراکنش در آن انجام می‌شود.
    • --fees=500uatom: هزینه تراکنش.
    • --yes: تایید خودکار تراکنش.
    • --output-document=<path_to_signed_transaction_file>: مسیر ذخیره‌سازی تراکنش امضا شده.

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

  1. ارسال تراکنش:پس از امضای تراکنش، می‌توانید آن را با استفاده از دستور cosmosd tx broadcast به شبکه ارسال کنید.
    cosmosd tx broadcast <path_to_signed_transaction_file>
    

    در این دستور:

    • <path_to_signed_transaction_file>: مسیر فایل تراکنش امضا شده.

2. امنیت کلیدهای خصوصی

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

روش‌های حفظ امنیت کلیدهای خصوصی:
  1. استفاده از کیف پول سخت‌افزاری:کیف پول‌های سخت‌افزاری مانند Ledger یا Trezor می‌توانند کلیدهای خصوصی شما را به‌صورت آفلاین نگهداری کنند و از دسترسی آنلاین آن جلوگیری کنند. این کیف پول‌ها تراکنش‌ها را به‌صورت آفلاین امضا کرده و پس از امضای تراکنش، آن را به دستگاه شما ارسال می‌کنند.
  2. استفاده از کلمه عبور برای محافظت از کیف پول‌ها:زمانی که از کیف پول نرم‌افزاری استفاده می‌کنید، مطمئن شوید که کیف پول خود را با یک کلمه عبور قوی محافظت کرده‌اید. همچنین، این کلمه عبور باید منحصر به فرد باشد و هیچ‌گاه آن را به اشتراک نگذارید.
  3. استفاده از روش‌های امنیتی چندعاملی (MFA):برای افزایش امنیت کلیدهای خصوصی، می‌توانید از روش‌های امنیتی چندعاملی (Multi-Factor Authentication) برای دسترسی به کیف پول خود استفاده کنید. این روش‌ها معمولا شامل تأیید هویت از طریق یک دستگاه جداگانه (مانند تلفن همراه) یا روش‌های دیگری مانند ایمیل و پیامک هستند.
  4. مراقبت از دستگاه‌های خود:هرگز کیف پول‌های دیجیتال خود را بر روی دستگاه‌های عمومی یا غیرامن ذخیره نکنید. از دستگاه‌های خود برای امضای تراکنش‌ها استفاده کنید که به‌طور منظم به‌روزرسانی می‌شوند و از آنتی‌ویروس و فایروال‌های مناسب برخوردارند.

3. بررسی و مدیریت کلیدهای خصوصی

در Cosmos SDK، شما می‌توانید کلیدهای خصوصی خود را با استفاده از دستورات cosmosd keys مدیریت کنید. برای بررسی کلیدهای خصوصی یا ایجاد یک کلید جدید از دستور cosmosd keys add استفاده می‌شود.

دستور ایجاد کلید جدید:
cosmosd keys add mykey --keyring-backend=test

این دستور یک کلید جدید با نام mykey ایجاد می‌کند و آن را در کلیدنگاری ذخیره می‌کند.

دستور نمایش کلیدها:
cosmosd keys list

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


جمع‌بندی

در این بخش نحوه امضای تراکنش‌ها و اهمیت امنیت کلیدهای خصوصی در بلاک‌چین Cosmos SDK مورد بررسی قرار گرفت. برای امضای تراکنش‌ها از دستور cosmosd tx sign استفاده می‌شود و پس از امضا تراکنش می‌توان آن را با دستور cosmosd tx broadcast ارسال کرد. همچنین، برای حفظ امنیت کلیدهای خصوصی، روش‌هایی مانند استفاده از کیف پول‌های سخت‌افزاری، کلمه عبور قوی و روش‌های امنیتی چندعاملی توصیه می‌شود. از طریق دستور cosmosd keys می‌توانید کلیدهای خصوصی خود را مدیریت کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. مدیریت نودها و اجرای شبکه آزمایشی (Testnet)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”راه‌اندازی یک Full Node و همگام‌سازی با شبکه” subtitle=”توضیحات کامل”]راه‌اندازی یک Full Node در بلاک‌چین Cosmos SDK به شما این امکان را می‌دهد که به‌طور کامل و مستقل از شبکه بلاک‌چین استفاده کرده و تمامی بلاک‌ها و تراکنش‌ها را به‌صورت محلی ذخیره و پردازش کنید. در این بخش، نحوه راه‌اندازی یک Full Node و همگام‌سازی آن با شبکه بلاک‌چین را بررسی خواهیم کرد.


1. نصب Cosmos SDK و پیش‌نیازهای آن

قبل از اینکه یک Full Node را راه‌اندازی کنیم، باید Cosmos SDK و پیش‌نیازهای آن را روی سیستم خود نصب کنیم. این پیش‌نیازها شامل نصب ابزارهای مربوط به Go، git و وابستگی‌های دیگر هستند.

مراحل نصب Cosmos SDK:
  1. نصب Go:Cosmos SDK به زبان Go نوشته شده است، بنابراین برای اجرای آن نیاز به نصب Go دارید. نسخه مناسب Go را از وب‌سایت رسمی آن دانلود و نصب کنید.برای نصب Go در سیستم‌های لینوکسی از دستورات زیر استفاده کنید:
    sudo apt update
    sudo apt install golang-go
    
  2. نصب Git:Git برای کلون کردن مخازن Cosmos SDK و همگام‌سازی با آن ضروری است.
    sudo apt install git
    
  3. نصب ابزار Cosmos SDK:پس از نصب Go و Git، ابزارهای Cosmos SDK را به‌صورت زیر نصب کنید:
    git clone https://github.com/cosmos/gaia.git
    cd gaia
    make install
    

    این دستور Cosmos SDK را روی سیستم شما نصب می‌کند.


2. راه‌اندازی Full Node

برای راه‌اندازی یک Full Node ابتدا باید یک گره جدید با استفاده از دستور cosmosd init ایجاد کنید. این گره باید به شبکه متصل شده و اطلاعات مربوط به بلاک‌ها و تراکنش‌ها را همگام‌سازی کند.

مراحل راه‌اندازی Full Node:
  1. ایجاد یک گره جدید:پس از نصب Cosmos SDK و ابزارهای مربوطه، می‌توانید گره خود را با دستور زیر راه‌اندازی کنید. این دستور مسیر گره را تنظیم می‌کند و داده‌های اولیه را برای همگام‌سازی با شبکه آماده می‌کند.
    cosmosd init <node_name> --chain-id=testnet
    

    در این دستور:

    • <node_name>: نام دلخواه برای گره شما.
    • --chain-id=testnet: شناسه شبکه‌ای که قصد دارید به آن متصل شوید (در اینجا شبکه آزمایشی testnet است).
  2. تنظیمات پیکربندی گره:پس از راه‌اندازی گره، باید فایل پیکربندی آن را ویرایش کنید. این فایل معمولاً در مسیر ~/.cosmosd/config/config.toml قرار دارد.برای ویرایش فایل پیکربندی، از ویرایشگر متنی مورد نظر خود استفاده کنید:
    nano ~/.cosmosd/config/config.toml
    

    در این فایل می‌توانید تنظیمات مختلف گره خود مانند پورت‌ها، آدرس‌های API، و تنظیمات همگام‌سازی را تنظیم کنید. به‌طور مثال، برای تنظیم همگام‌سازی با گره‌های دیگر شبکه، می‌توانید پارامترهای مربوط به seeds و persistent_peers را ویرایش کنید.

    seeds = "node1.cosmos.network:26656,node2.cosmos.network:26656"
    persistent_peers = "peer1,peer2,peer3"
    
  3. شروع همگام‌سازی:پس از پیکربندی گره، می‌توانید گره را با دستور زیر شروع کنید:
    cosmosd start
    

    این دستور باعث می‌شود که گره شما شروع به همگام‌سازی با شبکه کند و بلاک‌ها و تراکنش‌ها را از گره‌های دیگر دریافت کند.


3. بررسی وضعیت گره و همگام‌سازی

برای بررسی وضعیت گره و اطمینان از همگام‌سازی صحیح آن، می‌توانید از دستورات زیر استفاده کنید.

  1. بررسی وضعیت گره:با استفاده از دستور cosmosd status می‌توانید وضعیت گره خود را مشاهده کنید. این دستور اطلاعاتی از قبیل ارتفاع بلاک، تعداد همتایان متصل، و وضعیت همگام‌سازی را نمایش می‌دهد.
    cosmosd status
    
  2. بررسی لاگ‌ها:برای بررسی لاگ‌ها و اشکال‌زدایی از گره، می‌توانید فایل لاگ را در مسیر ~/.cosmosd/logs مشاهده کنید.
    tail -f ~/.cosmosd/logs/cosmosd.log
    

    این دستور خطایابی و مشاهده جزئیات فعالیت‌های گره را ساده‌تر می‌کند.


4. همگام‌سازی بلاک‌ها

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

بررسی وضعیت همگام‌سازی:

برای مشاهده وضعیت همگام‌سازی می‌توانید از دستور cosmosd status و مشاهده ارتفاع بلاک استفاده کنید.

اگر ارتفاع بلاک گره شما با بلاک‌های شبکه متفاوت باشد، نشان‌دهنده آن است که گره هنوز در حال همگام‌سازی است.


5. به‌روزرسانی گره

برای به‌روزرسانی گره و همگام‌سازی نسخه‌های جدید Cosmos SDK، می‌توانید دستورات زیر را اجرا کنید:

  1. کلون کردن نسخه جدید:
    cd ~/gaia
    git pull origin master
    
  2. ساخت مجدد و نصب نسخه جدید:
    make install
    
  3. راه‌اندازی مجدد گره:پس از نصب نسخه جدید، گره خود را مجدداً راه‌اندازی کنید:
    cosmosd start
    

جمع‌بندی

در این بخش نحوه راه‌اندازی یک Full Node و همگام‌سازی آن با شبکه بلاک‌چین Cosmos SDK مورد بررسی قرار گرفت. ابتدا با نصب پیش‌نیازها و ابزارهای مورد نیاز، یک گره جدید ایجاد کردیم. سپس با استفاده از دستور cosmosd start گره را راه‌اندازی کرده و به شبکه متصل شدیم. برای همگام‌سازی بلاک‌ها و بررسی وضعیت گره از دستورات مختلف مانند cosmosd status و مشاهده لاگ‌ها استفاده کردیم. در نهایت به روش‌های به‌روزرسانی گره پرداختیم تا بتوانیم به‌طور مداوم با آخرین نسخه Cosmos SDK همگام باشیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”اجرای Validator Node و ثبت در شبکه” subtitle=”توضیحات کامل”]در بلاک‌چین‌های مبتنی بر Cosmos SDK، Validatorها نقش بسیار مهمی ایفا می‌کنند. Validatorها مسئول تأیید تراکنش‌ها، ایجاد بلاک‌های جدید، و حفظ امنیت شبکه هستند. در این بخش، مراحل راه‌اندازی یک Validator Node و ثبت آن در شبکه بلاک‌چین را بررسی خواهیم کرد.


1. نصب Cosmos SDK و ابزارهای مورد نیاز

برای اجرای یک Validator Node، ابتدا باید Cosmos SDK را نصب کنید. این فرآیند همانند نصب Full Node است، اما در اینجا ما باید تنظیمات خاصی برای تبدیل نود به یک Validator اعمال کنیم.

مراحل نصب:
  1. نصب Go و Git:ابتدا باید Go و Git را بر روی سیستم خود نصب کنید، همانطور که پیش از این در بخش‌های قبل توضیح داده شد.
  2. نصب Cosmos SDK:سپس Cosmos SDK را با استفاده از دستور زیر کلون و نصب کنید:
    git clone https://github.com/cosmos/gaia.git
    cd gaia
    make install
    

    این ابزار به شما امکان می‌دهد یک نود جدید راه‌اندازی کنید.


2. راه‌اندازی Validator Node

برای راه‌اندازی یک Validator Node باید مراحل زیر را طی کنید:

  1. ایجاد یک گره جدید:پس از نصب Cosmos SDK، باید یک گره جدید با استفاده از دستور cosmosd init راه‌اندازی کنید. این دستور تنظیمات اولیه گره شما را ایجاد کرده و آن را برای ثبت به‌عنوان یک Validator آماده می‌کند.
    cosmosd init <validator_name> --chain-id=testnet
    

    در این دستور:

    • <validator_name>: نام دلخواه برای گره شما.
    • --chain-id=testnet: شناسه شبکه‌ای که قصد دارید به آن متصل شوید (در اینجا شبکه آزمایشی testnet است).
  2. تنظیمات پیکربندی:پس از راه‌اندازی گره، باید فایل‌های پیکربندی مربوط به نود خود را تنظیم کنید. این فایل‌ها در مسیر ~/.cosmosd/config/config.toml قرار دارند. برای ویرایش این فایل از ویرایشگر متن استفاده کنید:
    nano ~/.cosmosd/config/config.toml
    

    در این فایل می‌توانید تنظیمات مختلف گره مانند seeds و persistent_peers را برای اتصال به سایر گره‌ها تنظیم کنید.

    در اینجا می‌توانید شناسه شبکه (Chain ID) و تنظیمات اتصال گره‌ها به یکدیگر را تغییر دهید.


3. ایجاد کلید Validator و ثبت آن

برای تبدیل نود خود به یک Validator، شما نیاز به ایجاد کلیدهای عمومی و خصوصی برای نود خود دارید و سپس باید آن را به‌عنوان یک Validator ثبت کنید.

  1. ایجاد کلید Validator:برای ایجاد کلید عمومی و خصوصی برای نود خود، از دستور cosmosd keys add استفاده کنید. این دستور یک کلید جدید برای نود شما ایجاد می‌کند.
    cosmosd keys add <validator_key_name>
    

    این دستور یک کلید جدید ایجاد کرده و اطلاعات مربوط به آن را نمایش می‌دهد. اطلاعاتی مانند کلید خصوصی و عمومی را در جایی امن ذخیره کنید.

  2. ثبت نود به‌عنوان یک Validator:پس از ایجاد کلید، باید نود خود را به‌عنوان Validator ثبت کنید. برای این کار باید یک تراکنش ثبت Validator ارسال کنید.برای ثبت Validator از دستور زیر استفاده کنید:
    cosmosd tx staking create-validator \
      --amount=1000000uatom \
      --pubkey=$(cosmosd tendermint show-validator) \
      --moniker="<validator_name>" \
      --chain-id=testnet \
      --commission-rate="0.10" \
      --commission-max-rate="0.20" \
      --commission-max-change-rate="0.01" \
      --min-self-delegation="1" \
      --gas=auto \
      --from=<validator_key_name> \
      --fees=5000uatom
    

    در این دستور:

    • --amount=1000000uatom: مقدار توکن‌هایی که برای تأسیس Validator ارسال می‌کنید (در اینجا ۱ میلیون uatom).
    • --pubkey=$(cosmosd tendermint show-validator): کلید عمومی مربوط به نود شما.
    • --moniker="<validator_name>": نام دلخواه برای Validator شما.
    • --chain-id=testnet: شناسه شبکه.
    • --commission-rate="0.10": درصد کمیسیون برای Validator.
    • --fees=5000uatom: هزینه تراکنش.

    این دستور نود شما را به‌عنوان یک Validator در شبکه ثبت می‌کند.


4. راه‌اندازی و شروع به‌کار Validator Node

بعد از ثبت Validator، نود شما آماده است تا بلاک‌ها را تولید کرده و در فرآیند تأیید تراکنش‌ها مشارکت کند.

  1. راه‌اندازی نود:برای شروع به کار نود به‌عنوان Validator، دستور زیر را اجرا کنید:
    cosmosd start
    

    این دستور نود شما را به‌طور خودکار به شبکه متصل کرده و آن را به‌عنوان Validator فعال می‌کند.

  2. بررسی وضعیت Validator:برای بررسی وضعیت گره و تأیید اینکه نود شما به‌درستی به‌عنوان Validator فعال است، از دستور زیر استفاده کنید:
    cosmosd status
    

    همچنین، برای بررسی اطلاعات بیشتری در مورد عملکرد Validator، می‌توانید به وب‌سایت‌هایی مانند Cosmos Explorer مراجعه کرده و اطلاعات مربوط به نود خود را مشاهده کنید.


5. نظارت و مدیریت Validator Node

برای نظارت بر وضعیت Validator خود و مدیریت آن به‌طور مداوم، دستورات مختلفی برای مدیریت عملکرد نود وجود دارد. از جمله این دستورات می‌توان به موارد زیر اشاره کرد:

  1. بررسی لاگ‌ها:برای بررسی لاگ‌ها و مشاهده وضعیت عملکرد Validator، می‌توانید از دستور زیر استفاده کنید:
    tail -f ~/.cosmosd/logs/cosmosd.log
    
  2. چک کردن اعتبار نود:برای بررسی اعتبار نود خود می‌توانید از APIها و ابزارهای مختلفی برای نظارت بر عملکرد شبکه استفاده کنید.

جمع‌بندی

در این بخش، نحوه راه‌اندازی یک Validator Node در شبکه بلاک‌چین Cosmos SDK بررسی شد. ابتدا ابزارهای مورد نیاز نصب و سپس یک گره جدید ایجاد شد. پس از آن، کلیدهای مربوط به Validator تولید و نود به‌عنوان Validator در شبکه ثبت شد. در نهایت، نود به‌عنوان Validator راه‌اندازی شده و دستوراتی برای نظارت بر وضعیت آن ارائه گردید. این فرآیند به شما این امکان را می‌دهد که به‌عنوان یک Validator در شبکه مشارکت کرده و نقش مهمی در امنیت و اعتبار شبکه ایفا کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”مدیریت فایل genesis.json و تنظیمات اولیه شبکه” subtitle=”توضیحات کامل”]فایل genesis.json در شبکه‌های مبتنی بر Cosmos SDK، فایل پیکربندی اولیه شبکه است که تنظیمات اساسی شبکه، تنظیمات Validatorها، توکن‌ها، بلاک‌ها و سایر پارامترهای شبکه را شامل می‌شود. در این بخش، به بررسی نحوه مدیریت این فایل و تنظیمات اولیه شبکه خواهیم پرداخت.


1. آشنایی با ساختار فایل genesis.json

فایل genesis.json معمولاً شامل بخش‌های مختلفی است که هریک تنظیمات خاصی را در مورد شبکه و رفتار بلاک‌چین تعیین می‌کنند. این فایل به‌طور پیش‌فرض هنگام راه‌اندازی شبکه ایجاد می‌شود و معمولاً در مسیر ~/.cosmosd/config/genesis.json قرار دارد.

ساختار اصلی این فایل شامل موارد زیر است:

  1. Chain ID: شناسه منحصر به فرد شبکه که برای تشخیص شبکه از سایر شبکه‌ها استفاده می‌شود.
  2. Initial Validators: لیست اولیه Validatorهایی که در شبکه ثبت شده‌اند.
  3. Genesis Time: زمان شروع شبکه.
  4. Accounts: لیست حساب‌هایی که توکن‌های اولیه را دریافت می‌کنند.
  5. Governance Parameters: تنظیمات مربوط به حکمرانی و تأسیس بلاک‌ها.
  6. Token Definitions: اطلاعات توکن‌های شبکه مانند نام، نماد و تعداد توکن‌ها.
  7. Consensus Parameters: تنظیمات مربوط به الگوریتم اجماع.

2. ایجاد و ویرایش فایل genesis.json

برای ویرایش فایل genesis.json و تنظیمات اولیه شبکه، می‌توانیم به‌صورت دستی این فایل را ویرایش کرده یا از ابزارهای Cosmos SDK برای تولید آن استفاده کنیم.

2.1. ویرایش دستی فایل genesis.json

برای ویرایش فایل genesis.json به‌صورت دستی، کافی است که مسیر فایل را باز کرده و تنظیمات مورد نظر خود را تغییر دهید:

nano ~/.cosmosd/config/genesis.json

در این فایل، تنظیمات مختلفی برای شبکه و Validatorها وجود دارد. به‌طور مثال، شما می‌توانید تعداد توکن‌ها، تنظیمات اجماع یا اطلاعات Validatorها را تغییر دهید.

نمونه‌ای از بخش‌های مهم این فایل به شرح زیر است:

{
  "genesis_time": "2025-03-05T00:00:00Z",
  "chain_id": "testnet",
  "validators": [
    {
      "address": "cosmosvaloper1xxxxxx",
      "power": "1000000",
      "name": "Validator-1"
    }
  ],
  "accounts": [
    {
      "address": "cosmos1xxxxxx",
      "coins": [
        {
          "denom": "uatom",
          "amount": "1000000000"
        }
      ]
    }
  ]
}
  • genesis_time: زمان شروع شبکه.
  • chain_id: شناسه شبکه.
  • validators: لیست Validatorها.
  • accounts: حساب‌هایی که در ابتدا توکن دریافت می‌کنند.
2.2. استفاده از ابزار Cosmos SDK برای تولید فایل genesis.json

همچنین می‌توانید فایل genesis.json را با استفاده از دستور Cosmos SDK و از طریق ایجاد یک شبکه جدید تولید کنید. برای این کار، ابتدا باید یک شبکه جدید ایجاد کنید:

cosmosd init <network_name> --chain-id=testnet

این دستور به‌طور خودکار یک فایل genesis.json تولید می‌کند که شامل تنظیمات اولیه شبکه است. می‌توانید پس از تولید این فایل، آن را مطابق نیاز خود ویرایش کنید.


3. تنظیمات اولیه شبکه در فایل genesis.json

بعد از ایجاد یا ویرایش فایل genesis.json، ممکن است بخواهید تنظیمات مختلف شبکه را مطابق نیاز خود تنظیم کنید. در این بخش، برخی از تنظیمات اصلی را توضیح خواهیم داد:

3.1. تنظیمات Validatorها

در بخش validators، شما می‌توانید اطلاعات مربوط به Validatorهای شبکه را قرار دهید. هر Validator شامل آدرس، قدرت (Power) و نام خود است.

نمونه:

"validators": [
  {
    "address": "cosmosvaloper1xxxxxx",
    "power": "1000000",
    "name": "Validator-1"
  },
  {
    "address": "cosmosvaloper2xxxxxx",
    "power": "2000000",
    "name": "Validator-2"
  }
]

در اینجا، power نشان‌دهنده قدرت تأیید Validator است که معمولاً مرتبط با تعداد توکن‌هایی است که به آن اختصاص داده شده است.

3.2. تنظیمات بلاک‌ها و اجماع

در بخش consensus_params می‌توانید تنظیمات مربوط به الگوریتم اجماع و پارامترهای بلاک‌ها را مشخص کنید:

"consensus_params": {
  "block": {
    "max_bytes": "200000",
    "max_gas": "200000"
  },
  "evidence": {
    "max_age_duration": "86400s",
    "max_age_num_blocks": "100000"
  }
}

این تنظیمات حداکثر اندازه بلاک و تعداد گاز مجاز را برای هر بلاک مشخص می‌کنند.

3.3. تنظیمات توکن‌ها و حساب‌ها

در بخش accounts می‌توانید حساب‌هایی که قرار است توکن‌های اولیه دریافت کنند را مشخص کنید:

"accounts": [
  {
    "address": "cosmos1xxxxxx",
    "coins": [
      {
        "denom": "uatom",
        "amount": "1000000000"
      }
    ]
  }
]

این تنظیمات به حساب‌های مختلف توکن‌های اولیه اختصاص می‌دهند.


4. همگام‌سازی فایل genesis.json با شبکه

پس از ویرایش فایل genesis.json، باید نود خود را مجدداً راه‌اندازی کنید تا تنظیمات جدید اعمال شوند. برای انجام این کار:

  1. کپی فایل جدید genesis.json به مسیر صحیح:فایل ویرایش‌شده genesis.json را به مسیر زیر کپی کنید:
    cp genesis.json ~/.cosmosd/config/genesis.json
    
  2. راه‌اندازی دوباره نود:پس از اعمال تغییرات، نود خود را با دستور زیر دوباره راه‌اندازی کنید:
    cosmosd start
    
  3. بررسی صحت تنظیمات:برای بررسی اینکه تنظیمات به‌درستی اعمال شده‌اند، می‌توانید از دستور زیر برای مشاهده وضعیت نود خود استفاده کنید:
    cosmosd status
    

5. نظارت بر عملکرد شبکه و اصلاحات آینده

پس از راه‌اندازی نود با فایل genesis.json و اعمال تنظیمات، شما می‌توانید به‌طور پیوسته وضعیت شبکه و Validatorهای خود را نظارت کنید. همچنین، در صورت نیاز به تغییرات بیشتر، می‌توانید فایل genesis.json را به‌روزرسانی کرده و نود خود را مجدداً راه‌اندازی کنید.

برای نظارت و مدیریت بهتر شبکه و Validatorها، می‌توانید از ابزارهایی مانند Cosmos Explorer استفاده کنید که اطلاعاتی مانند تعداد بلاک‌ها، وضعیت تراکنش‌ها و عملکرد Validatorها را به شما نشان می‌دهد.


جمع‌بندی

در این بخش، به بررسی نحوه مدیریت فایل genesis.json و تنظیمات اولیه شبکه پرداختیم. ابتدا ساختار فایل genesis.json و نحوه ویرایش آن را توضیح دادیم. سپس تنظیمات مربوط به Validatorها، بلاک‌ها، اجماع و توکن‌ها را مورد بررسی قرار دادیم. در نهایت، نحوه همگام‌سازی این فایل با شبکه و نظارت بر عملکرد نودها و شبکه را شرح دادیم. این مراحل به شما این امکان را می‌دهند که تنظیمات شبکه بلاک‌چین خود را به‌دقت پیکربندی کرده و شبکه‌ای امن و پایدار ایجاد کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” title=”بررسی لاگ‌های شبکه و دیباگ تراکنش‌ها” subtitle=”توضیحات کامل”]برای نظارت بر عملکرد شبکه و دیباگ تراکنش‌ها در بلاک‌چین‌های مبتنی بر Cosmos SDK، بررسی لاگ‌ها و استفاده از ابزارهای دیباگ برای شناسایی مشکلات حیاتی است. در این بخش، نحوه دسترسی به لاگ‌های سیستم، بررسی اطلاعات مربوط به تراکنش‌ها و دیباگ آن‌ها را توضیح خواهیم داد.


1. دسترسی به لاگ‌های شبکه

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

1.1. مشاهده لاگ‌های نود در کنسول

اگر نود خود را به‌طور مستقیم از طریق خط فرمان (CLI) اجرا کرده‌اید، تمامی لاگ‌های مرتبط با نود به‌طور پیش‌فرض در کنسول نمایش داده می‌شود. برای مشاهده این لاگ‌ها، کافی است که نود را راه‌اندازی کرده و پیام‌های سیستم را در کنسول مشاهده کنید:

cosmosd start

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

1.2. ذخیره و مشاهده لاگ‌ها در فایل

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

~/.cosmosd/data/cosmovisor/logs/

برای مشاهده لاگ‌های ذخیره شده در این مسیر، می‌توانید از دستورات مانند cat یا tail استفاده کنید:

tail -f ~/.cosmosd/data/cosmovisor/logs/cosmosd.log

این دستور به شما این امکان را می‌دهد که به‌طور زنده لاگ‌های نود را مشاهده کنید.

1.3. استفاده از فیلترها برای بررسی خطاها

اگر به دنبال خطاهای خاص یا اطلاعات مربوط به تراکنش‌ها هستید، می‌توانید از ابزارهایی مانند grep برای فیلتر کردن لاگ‌ها استفاده کنید:

grep "error" ~/.cosmosd/data/cosmovisor/logs/cosmosd.log

این دستور فقط خطاهایی که در لاگ‌ها ثبت شده‌اند را به نمایش می‌گذارد.


2. بررسی تراکنش‌ها و دیباگ آن‌ها

یکی از مهم‌ترین بخش‌ها در بلاک‌چین‌های مبتنی بر Cosmos SDK، بررسی وضعیت تراکنش‌ها و دیباگ آن‌ها برای شناسایی هرگونه مشکل یا خطا است. در این بخش، نحوه بررسی تراکنش‌ها و دیباگ آن‌ها را بررسی می‌کنیم.

2.1. مشاهده وضعیت تراکنش‌ها

برای بررسی وضعیت تراکنش‌ها، می‌توانید از دستور cosmosd query tx استفاده کنید. این دستور وضعیت تراکنش‌های مختلف را از بلاک‌چین به شما نمایش می‌دهد.

به‌طور مثال، برای بررسی وضعیت یک تراکنش خاص با شناسه (TX hash) معین، می‌توانید از دستور زیر استفاده کنید:

cosmosd query tx <tx_hash>

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

2.2. استفاده از Debug Mode برای تحلیل بیشتر

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

cosmosd start --log_level=debug

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

2.3. بررسی خطاهای مربوط به تراکنش‌ها

در صورت بروز خطا در تراکنش‌ها، Cosmos SDK به‌طور دقیق دلایل آن را در لاگ‌ها ثبت می‌کند. این اطلاعات می‌تواند شامل مواردی مانند موارد زیر باشد:

  • Insufficient funds: نبود موجودی کافی در حساب برای انجام تراکنش.
  • Invalid signature: امضای نامعتبر در تراکنش.
  • Failed validation: رد شدن تراکنش به دلایل مختلف مانند خطای در پیکربندی شبکه یا اجماع.

برای مشاهده خطاهای مربوط به تراکنش‌ها در لاگ‌ها، می‌توانید از دستور grep برای جستجوی خطاها استفاده کنید:

grep "failed" ~/.cosmosd/data/cosmovisor/logs/cosmosd.log

این دستور تمامی خطاهایی که حاوی واژه “failed” هستند را نمایش می‌دهد.


3. ابزارهای دیگر برای دیباگ و مانیتورینگ

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

3.1. استفاده از cosmos-explorer

برای مشاهده اطلاعات تراکنش‌ها و وضعیت شبکه به‌طور بصری و آسان، می‌توانید از سایت‌های مبتنی بر Cosmos SDK مانند Cosmos Explorer استفاده کنید. این ابزار اطلاعات دقیق‌تری از بلاک‌ها، تراکنش‌ها، وضعیت نودها و Validatorها به شما نمایش می‌دهد.

3.2. استفاده از Prometheus و Grafana

برای مانیتورینگ دقیق‌تر و جمع‌آوری اطلاعات آماری، می‌توانید از ابزارهای مانند Prometheus و Grafana استفاده کنید. این ابزارها به شما امکان می‌دهند که اطلاعاتی در مورد عملکرد شبکه، مصرف گاز، وضعیت نودها و تراکنش‌ها به‌طور لحظه‌ای جمع‌آوری کنید.

برای نصب و راه‌اندازی Prometheus و Grafana، می‌توانید از دستورالعمل‌های رسمی این ابزارها استفاده کنید.


جمع‌بندی

در این بخش، به بررسی نحوه دسترسی به لاگ‌های شبکه و دیباگ تراکنش‌ها پرداختیم. ابتدا به روش‌های مشاهده لاگ‌های نود در کنسول و فایل‌های لاگ پرداختیم. سپس نحوه بررسی وضعیت تراکنش‌ها و استفاده از حالت دیباگ را برای تحلیل دقیق‌تر توضیح دادیم. در نهایت، ابزارهای جانبی مانند Cosmos Explorer و Prometheus برای مانیتورینگ و دیباگ بهتر شبکه را معرفی کردیم. این ابزارها و روش‌ها به شما کمک می‌کنند تا مشکلات موجود در شبکه و تراکنش‌ها را شناسایی کرده و آن‌ها را برطرف کنید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش ۳: طراحی و پیاده‌سازی ماژول‌های سفارشی در Cosmos SDK”][cdb_course_lesson title=”فصل 1. مقدمه‌ای بر ماژول‌های سفارشی در Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مفهوم ماژول در معماری ماژولار Cosmos SDK” subtitle=”توضیحات کامل”]در معماری Cosmos SDK، ماژول‌ها واحدهای ساختاری هستند که امکان افزودن ویژگی‌های جدید به بلاکچین را فراهم می‌آورند. Cosmos SDK یک فریم‌ورک متن‌باز است که برای ساخت بلاکچین‌های مستقل و مقیاس‌پذیر استفاده می‌شود. این فریم‌ورک به صورت ماژولار طراحی شده است، به این معنا که شما می‌توانید ماژول‌های مختلف را برای افزودن قابلیت‌های خاص به بلاکچین خود اضافه کنید، بدون اینکه نیاز به تغییر ساختار کلی سیستم داشته باشید.

ماژول‌ها در Cosmos SDK به‌طور مستقل از یکدیگر توسعه داده می‌شوند و می‌توانند به راحتی در کنار یکدیگر عمل کنند. این ماژول‌ها مسئول انجام وظایف خاص مانند مدیریت حساب‌ها، انجام تراکنش‌ها، رای‌گیری، و نظارت بر وضعیت بلاکچین هستند. همچنین، این ماژول‌ها به‌گونه‌ای طراحی شده‌اند که می‌توانند به راحتی با یکدیگر تعامل کنند و عملکرد کلی شبکه را بهبود بخشند.

اجزای اصلی یک ماژول در Cosmos SDK

هر ماژول در Cosmos SDK از چندین بخش اصلی تشکیل شده است:

  1. State: ماژول‌ها می‌توانند وضعیت (State) خود را مدیریت کنند. این وضعیت ممکن است شامل اطلاعات مربوط به تراکنش‌ها، حساب‌ها یا هر داده دیگر باشد که باید در طول زمان نگهداری شود.
  2. Handlers: ماژول‌ها به وسیله‌ی handlerها تراکنش‌ها را پردازش می‌کنند. هر handler مسئول انجام یک وظیفه خاص مانند پردازش تراکنش، تغییر وضعیت، یا ارسال اطلاعات به سایر ماژول‌ها است.
  3. Keeper: Keeperها رابط‌هایی هستند که اجازه می‌دهند داده‌ها به‌طور مؤثر و ایمن در وضعیت (State) ذخیره شوند. Keeper‌ها در Cosmos SDK مانند یک “دستیار” برای ماژول‌ها عمل می‌کنند که به آنها کمک می‌کنند داده‌ها را در پایگاه داده ذخیره و بازیابی کنند.
  4. Messages: پیام‌ها (Messages) در Cosmos SDK ارتباط میان کاربران و ماژول‌ها را ممکن می‌سازند. این پیام‌ها معمولاً داده‌هایی هستند که توسط کاربران برای تغییر وضعیت یا درخواست‌های خاص ارسال می‌شوند.
  5. Types: در هر ماژول، انواع داده‌ای (Types) خاصی تعریف می‌شوند که برای توصیف داده‌های مختلف مورد استفاده قرار می‌گیرند.

ساختار کلی یک ماژول در Cosmos SDK

برای ایجاد یک ماژول جدید در Cosmos SDK، ابتدا باید ساختار پروژه خود را تنظیم کنید و سپس ماژول جدید را اضافه کنید. در اینجا، یک مثال از نحوه ایجاد یک ماژول جدید در Cosmos SDK را بررسی می‌کنیم.

  1. ایجاد پروژه و نصب Cosmos SDKابتدا باید Cosmos SDK را روی سیستم خود نصب کنید. در اینجا، دستورات لازم برای نصب SDK آمده است:
    git clone https://github.com/cosmos/cosmos-sdk.git
    cd cosmos-sdk
    make install
    
  2. ایجاد ماژول جدیدپس از نصب SDK، برای ایجاد ماژول جدید، باید از دستور scaffold استفاده کنید که به طور خودکار ساختار فایل‌ها را برای ماژول جدید ایجاد می‌کند. این دستور به شما این امکان را می‌دهد که به سرعت یک ماژول اولیه بسازید.دستور زیر ماژول جدیدی به نام example ایجاد می‌کند:
    starport scaffold module example
    

    این دستور ساختار فایل‌های مورد نیاز را در مسیر زیر ایجاد می‌کند:

    ./x/example/
    ├── handler.go
    ├── keeper.go
    ├── types.go
    ├── msg.go
    └── genesis.go
    

    در این ساختار، فایل‌ها به ترتیب وظایف مختلف ماژول را انجام می‌دهند. به عنوان مثال:

    • handler.go: مسئول پردازش پیام‌های ورودی و اجرای منطق کسب‌وکار ماژول است.
    • keeper.go: این فایل وظیفه ذخیره‌سازی و بازیابی داده‌ها را بر عهده دارد.
    • types.go: شامل انواع داده‌ای مختلفی است که توسط ماژول استفاده می‌شوند.
  3. پیکربندی و تنظیمات ماژولبعد از ایجاد ماژول، باید آن را در فایل app.go به پروژه اضافه کنید تا بتوانید آن را در بلاکچین خود استفاده کنید. برای این کار، ابتدا فایل app.go را باز کرده و ماژول خود را به لیست ماژول‌های موجود اضافه کنید:مسیر فایل: ./app.goدر اینجا، کد برای اضافه کردن ماژول جدید به پروژه به صورت زیر است:
    import (
        "github.com/cosmos/cosmos-sdk/types"
        "github.com/cosmos/cosmos-sdk/x/example"
    )
    
    func NewApp(
        logger log.Logger,
        db dbm.DB,
        traceStore io.Writer,
        loadLatest bool,
        homePath string,
    ) *App {
        app := &App{}
        
        // اضافه کردن ماژول example
        app.MountModules(
            example.NewAppModule(appCodec, app.exampleKeeper),
        )
    
        return app
    }
    

ارسال پیام به ماژول

پس از ایجاد ماژول و انجام تنظیمات اولیه، شما می‌توانید پیام‌هایی را به ماژول ارسال کنید. برای این کار، ابتدا باید یک پیام (message) تعریف کنید و سپس آن را از طریق handler پردازش کنید.

در اینجا، مثالی از تعریف یک پیام جدید در ماژول آمده است. مسیر فایل: ./x/example/msg.go

package example

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type MsgExample struct {
   From   sdk.AccAddress `json:"from" yaml:"from"`
   Amount sdk.Coins      `json:"amount" yaml:"amount"`
}

func (msg MsgExample) Route() string { return RouterKey }
func (msg MsgExample) Type() string  { return "Example" }
func (msg MsgExample) GetSigners() []sdk.AccAddress {
   return []sdk.AccAddress{msg.From}
}

func (msg MsgExample) ValidateBasic() error {
   if msg.Amount.IsAnyNegative() {
       return sdk.ErrInvalidCoins("amount cannot be negative").Result()
   }
   return nil
}

جمع‌بندی

در این بخش، ما به طور کامل به معرفی و مفهوم ماژول‌ها در معماری ماژولار Cosmos SDK پرداخته و نحوه ایجاد یک ماژول جدید، پیکربندی آن و ارسال پیام به ماژول را بررسی کردیم. ماژول‌ها ابزارهای قدرتمندی هستند که به شما این امکان را می‌دهند که بلاکچین خود را به شکلی انعطاف‌پذیر توسعه دهید و ویژگی‌های جدیدی به آن اضافه کنید. با استفاده از دستوراتی که در این بخش به آن اشاره شد، شما می‌توانید به راحتی ماژول‌های جدیدی را در پروژه‌های Cosmos SDK خود ایجاد کنید و آن‌ها را به سیستم بلاکچین خود اضافه کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه تعامل ماژول‌ها با بلاکچین” subtitle=”توضیحات کامل”]در معماری Cosmos SDK، ماژول‌ها به‌طور مستقیم با بلاکچین تعامل دارند و وظایف مختلفی را انجام می‌دهند. این تعاملات به‌وسیله اجزای مختلف Cosmos SDK مانند state, handlers, messages, و keepers انجام می‌شود. ماژول‌ها با استفاده از این اجزا می‌توانند به‌طور مؤثر و هماهنگ با یکدیگر درون بلاکچین عمل کنند. در این بخش، نحوه تعامل ماژول‌ها با بلاکچین را بررسی می‌کنیم.

1. وضعیت (State)

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

هر ماژول در Cosmos SDK از یک keeper استفاده می‌کند تا وضعیت خود را ذخیره کرده و داده‌ها را بازیابی کند. Keeperها مسئول انجام عملیات‌های ذخیره‌سازی و بازیابی داده‌ها از پایگاه داده هستند.

مسیر فایل مرتبط:

برای مثال، مسیر فایل keeper.go در ماژول شما که مسئول مدیریت وضعیت است به‌طور معمول در مسیر زیر قرار دارد:

./x/example/keeper.go

در این فایل، شما می‌توانید متدهای مختلفی برای ذخیره‌سازی و بازیابی داده‌ها تعریف کنید.

2. Handlers (مدیریت تراکنش‌ها)

Handlers در Cosmos SDK مسئول پردازش پیام‌ها (messages) و اجرای منطق کسب‌وکار هستند. به عبارت دیگر، زمانی که یک پیام از طرف کاربر به ماژول ارسال می‌شود، handler این پیام را پردازش کرده و عملیات مناسب را انجام می‌دهد. این عملیات‌ها می‌تواند شامل تغییر وضعیت، ارسال تراکنش به سایر ماژول‌ها، یا اجرای اقدامات خاص باشد.

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

مثال کد: یک Handler برای پردازش پیام در ماژول

مسیر فایل: ./x/example/handler.go

package example

import (
   "github.com/cosmos/cosmos-sdk/types"
   "github.com/cosmos/cosmos-sdk/x/example"
)

func NewHandler(k Keeper) sdk.Handler {
   return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) {
      switch msg := msg.(type) {
      case MsgExample:
         return handleMsgExample(ctx, k, msg)
      default:
         errMsg := fmt.Sprintf("unrecognized example message type: %T", msg)
         return nil, sdk.ErrUnknownRequest(errMsg)
      }
   }
}

func handleMsgExample(ctx sdk.Context, k Keeper, msg MsgExample) (*sdk.Result, error) {
   // منطق پردازش پیام‌ها
   k.SetExample(ctx, msg.Amount)
   return &sdk.Result{}, nil
}

در این کد، ما یک handler به نام NewHandler ایجاد کرده‌ایم که برای پردازش پیام‌هایی از نوع MsgExample عمل می‌کند. این handler سپس از keeper برای ذخیره‌سازی داده‌ها استفاده می‌کند.

3. Messages (پیام‌ها)

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

مثال کد: تعریف یک پیام برای تغییر وضعیت

مسیر فایل: ./x/example/msg.go

package example

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type MsgExample struct {
   From   sdk.AccAddress `json:"from" yaml:"from"`
   Amount sdk.Coins      `json:"amount" yaml:"amount"`
}

func (msg MsgExample) Route() string { return RouterKey }
func (msg MsgExample) Type() string  { return "Example" }
func (msg MsgExample) GetSigners() []sdk.AccAddress {
   return []sdk.AccAddress{msg.From}
}

func (msg MsgExample) ValidateBasic() error {
   if msg.Amount.IsAnyNegative() {
       return sdk.ErrInvalidCoins("amount cannot be negative").Result()
   }
   return nil
}

در اینجا، ما یک پیام MsgExample تعریف کرده‌ایم که اطلاعاتی مانند آدرس فرستنده و مقدار مبلغ را شامل می‌شود. همچنین، متد ValidateBasic برای اطمینان از صحت داده‌ها (مثلاً عدم وجود مقدار منفی) اضافه شده است.

4. Keepers (مدیریت داده‌ها)

Keeperها رابط‌هایی هستند که برای ذخیره‌سازی و بازیابی داده‌ها در بلاکچین استفاده می‌شوند. هر ماژول در Cosmos SDK معمولاً یک یا چند keeper دارد که مسئول انجام عملیات‌های مختلف ذخیره‌سازی هستند. Keeperها از storeها برای ذخیره‌سازی اطلاعات در پایگاه داده استفاده می‌کنند و می‌توانند داده‌ها را در طول زمان بازیابی کنند.

مثال کد: ایجاد یک Keeper برای مدیریت داده‌ها

مسیر فایل: ./x/example/keeper.go

package example

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type Keeper struct {
   storeKey sdk.StoreKey
}

func NewKeeper(storeKey sdk.StoreKey) Keeper {
   return Keeper{storeKey: storeKey}
}

func (k Keeper) SetExample(ctx sdk.Context, amount sdk.Coins) {
   store := ctx.KVStore(k.storeKey)
   store.Set([]byte("exampleKey"), amount)
}

func (k Keeper) GetExample(ctx sdk.Context) sdk.Coins {
   store := ctx.KVStore(k.storeKey)
   return store.Get([]byte("exampleKey"))
}

در اینجا، ما یک keeper تعریف کرده‌ایم که می‌تواند داده‌های مربوط به مقدار amount را در پایگاه داده ذخیره کند. متدهای SetExample و GetExample به ترتیب برای ذخیره و بازیابی این داده‌ها استفاده می‌شوند.

5. تعامل ماژول‌ها با یکدیگر

ماژول‌ها در Cosmos SDK می‌توانند به‌راحتی با یکدیگر تعامل داشته باشند. این تعاملات از طریق ارسال پیام‌ها (messages) به ماژول‌های دیگر و استفاده از keeperهای یکدیگر انجام می‌شود. به‌عنوان مثال، ماژولی که مسئول مدیریت حساب‌ها است می‌تواند پیام‌هایی را به ماژول دیگر ارسال کند تا وضعیت حساب‌های کاربران را تغییر دهد.

جمع‌بندی

در این بخش، نحوه تعامل ماژول‌ها با بلاکچین در Cosmos SDK را مورد بررسی قرار دادیم. ماژول‌ها از اجزای مختلفی مانند state, handlers, messages, و keepers برای تعامل با بلاکچین و انجام وظایف خود استفاده می‌کنند. این اجزا به ماژول‌ها این امکان را می‌دهند که به‌طور مؤثر با یکدیگر کار کنند و ویژگی‌های مختلف بلاکچین را گسترش دهند. از طریق این تعاملات، می‌توان بلاکچین‌هایی را ساخت که به‌طور مؤثر و بدون نقص عمل کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی ساختار کلی یک ماژول سفارشی” subtitle=”توضیحات کامل”]ماژول‌ها در Cosmos SDK بخش‌های اصلی و قابل توسعه بلاکچین‌ها هستند. این ماژول‌ها می‌توانند قابلیت‌ها و ویژگی‌های مختلفی را به بلاکچین اضافه کنند. ساختار کلی یک ماژول سفارشی به گونه‌ای طراحی شده که به راحتی می‌توان آن را گسترش داد و تغییرات دلخواه را به آن اعمال کرد.

در این بخش، به بررسی اجزای مختلف یک ماژول سفارشی و نحوه تنظیم آن خواهیم پرداخت.

1. ساختار فولدر ماژول

ساختار فولدر یک ماژول سفارشی در Cosmos SDK به‌طور معمول به صورت زیر خواهد بود:

./x/<module_name>/
├── genesis.go
├── handler.go
├── keeper.go
├── msg.go
├── types/
│   ├── abci.go
│   ├── codec.go
│   ├── types.go
├── module.go
└── simulation/
    └── genesis.go
  • genesis.go: این فایل مسئول تنظیمات ابتدایی ماژول است. در این فایل، وضعیت اولیه ماژول در هنگام راه‌اندازی بلاکچین تنظیم می‌شود.
  • handler.go: در این فایل، پردازش پیام‌ها و دستورات اجرایی ماژول انجام می‌شود.
  • keeper.go: این فایل مسئول مدیریت وضعیت و ذخیره‌سازی داده‌ها در پایگاه داده است. همچنین، از این فایل برای تعامل با سایر ماژول‌ها نیز استفاده می‌شود.
  • msg.go: پیام‌ها (messages) و ساختارهای آن‌ها که اطلاعات مربوط به تراکنش‌ها و دستورات ماژول را دربر می‌گیرند.
  • types/: شامل انواع داده‌ها، کدک‌ها، و متدهای مرتبط با داده‌های ماژول است.
  • module.go: فایل اصلی ماژول که اجزا و زیرماژول‌های آن را به هم متصل می‌کند.
  • simulation/: این بخش برای شبیه‌سازی و تست ماژول‌ها طراحی شده است. در این بخش، شرایط مختلف بلاکچین برای شبیه‌سازی و بررسی عملکرد ماژول بررسی می‌شود.

2. توضیحات فایل‌های اصلی ماژول

2.1. module.go

فایل module.go قلب ماژول است. این فایل مسئول اتصال تمام اجزای ماژول مانند keeper، handler، و genesis است و ماژول را برای تعامل با بقیه بخش‌های بلاکچین آماده می‌کند.

مسیر فایل: ./x/<module_name>/module.go

مثال:

package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/baseapp"
   "github.com/cosmos/cosmos-sdk/types"
   "github.com/cosmos/cosmos-sdk/x/<module_name>/keeper"
   "github.com/cosmos/cosmos-sdk/x/<module_name>/handler"
   "github.com/cosmos/cosmos-sdk/x/<module_name>/types"
)

type Module struct {
   keeper keeper.Keeper
}

func NewModule(k keeper.Keeper) *Module {
   return &Module{keeper: k}
}

func (m *Module) BeginBlock(ctx types.Context, req types.RequestBeginBlock) {
   // Logic for begin block
}

func (m *Module) EndBlock(ctx types.Context, req types.RequestEndBlock) {
   // Logic for end block
}

func (m *Module) InitGenesis(ctx types.Context, data json.RawMessage) ([]types.ValidatorUpdate, error) {
   // Logic to initialize genesis state
}

func (m *Module) Route() string {
   return "<module_name>"
}

func (m *Module) NewHandler() types.Handler {
   return handler.NewHandler(m.keeper)
}
2.2. keeper.go

فایل keeper.go مسئول مدیریت وضعیت ماژول است. این فایل شامل توابعی است که برای ذخیره‌سازی و بازیابی داده‌ها از پایگاه داده استفاده می‌شود.

مسیر فایل: ./x/<module_name>/keeper.go

مثال:

package keeper

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/types"
)

type Keeper struct {
   storeKey types.StoreKey
}

func NewKeeper(storeKey types.StoreKey) Keeper {
   return Keeper{storeKey: storeKey}
}

func (k Keeper) SetValue(ctx types.Context, key string, value []byte) {
   store := ctx.KVStore(k.storeKey)
   store.Set([]byte(key), value)
}

func (k Keeper) GetValue(ctx types.Context, key string) ([]byte, bool) {
   store := ctx.KVStore(k.storeKey)
   value := store.Get([]byte(key))
   return value, value != nil
}
2.3. handler.go

فایل handler.go مسئول پردازش پیام‌ها است. این فایل تمامی پیام‌هایی که به ماژول ارسال می‌شوند را پردازش می‌کند و بر اساس نوع پیام، عملیات مناسب را انجام می‌دهد.

مسیر فایل: ./x/<module_name>/handler.go

مثال:

package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

func NewHandler(k keeper.Keeper) types.Handler {
   return func(ctx types.Context, msg types.Msg) (*types.Result, error) {
      switch msg := msg.(type) {
      case types.MsgSend:
         return handleMsgSend(ctx, k, msg)
      default:
         return nil, types.ErrUnknownRequest("unrecognized message type")
      }
   }
}

func handleMsgSend(ctx types.Context, k keeper.Keeper, msg types.MsgSend) (*types.Result, error) {
   // Logic to process send message
   return &types.Result{}, nil
}
2.4. msg.go

در فایل msg.go پیام‌ها و درخواست‌های ماژول تعریف می‌شوند. هر پیام شامل اطلاعات مورد نیاز برای اجرای تراکنش‌ها است و باید از sdk.Msg ارث‌بری کند.

مسیر فایل: ./x/<module_name>/msg.go

مثال:

package types

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type MsgSend struct {
   From   sdk.AccAddress `json:"from"`
   To     sdk.AccAddress `json:"to"`
   Amount sdk.Coins      `json:"amount"`
}

func (msg MsgSend) Route() string {
   return "send"
}

func (msg MsgSend) Type() string {
   return "Send"
}

func (msg MsgSend) ValidateBasic() error {
   if msg.Amount.IsAnyNegative() {
       return sdk.ErrInvalidCoins("negative coins are not allowed")
   }
   return nil
}

func (msg MsgSend) GetSigners() []sdk.AccAddress {
   return []sdk.AccAddress{msg.From}
}

3. پیکربندی ماژول در بلاکچین

برای فعال‌سازی و پیکربندی ماژول در بلاکچین، باید ماژول را به‌طور صحیح به‌عنوان بخشی از بلاکچین تعریف کرده و آن را در فایل app.go که مسئول تنظیم بلاکچین است، ثبت کنیم.

مسیر فایل: ./app/app.go

مثال:

package app

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>"
)

func NewApp() *App {
   app := &App{}
   
   // Register module
   app.moduleManager = module.NewManager(
      <module_name>.NewModule(),
   )

   return app
}

جمع‌بندی

در این بخش، ساختار کلی یک ماژول سفارشی در Cosmos SDK را معرفی کردیم. ماژول‌ها از چندین جزء اصلی تشکیل شده‌اند که شامل handler, keeper, msg, و module هستند. این اجزا به ماژول‌ها این امکان را می‌دهند که بتوانند ویژگی‌های جدیدی به بلاکچین اضافه کنند و با سایر ماژول‌ها تعامل داشته باشند. از طریق این ساختار، شما می‌توانید به راحتی ماژول‌های سفارشی را توسعه دهید و آن‌ها را در بلاکچین‌های مبتنی بر Cosmos SDK پیاده‌سازی کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. ایجاد یک ماژول جدید در Cosmos SDK”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ایجاد ساختار اولیه ماژول” subtitle=”توضیحات کامل”]در این بخش، نحوه ایجاد ساختار اولیه برای یک ماژول سفارشی در Cosmos SDK را بررسی خواهیم کرد. این مراحل شامل تولید ساختار پایه‌ای ماژول، فایل‌های موردنیاز و کدهای اولیه برای راه‌اندازی ماژول خواهد بود. این مراحل به شما کمک خواهد کرد که ماژول‌های سفارشی خود را برای استفاده در یک بلاکچین Cosmos SDK طراحی و پیاده‌سازی کنید.

1. ایجاد ساختار دایرکتوری برای ماژول

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

دستور ساخت دایرکتوری ماژول
mkdir -p ./x/<module_name>
  • مسیر فایل‌ها: ./x/<module_name>/

این دستور دایرکتوری ماژول را در مسیر x/ ایجاد می‌کند. به جای <module_name>, نام ماژول خود را قرار دهید.

2. ایجاد فایل module.go

فایل module.go برای تعریف ماژول و راه‌اندازی ساختار اصلی آن استفاده می‌شود. این فایل وظیفه ایجاد و پیکربندی اجزای مختلف ماژول مانند keeper، handler و genesis را بر عهده دارد.

دستور ایجاد فایل module.go

در مسیر ./x/<module_name>/ یک فایل جدید به نام module.go بسازید.

touch ./x/<module_name>/module.go

سپس محتوای زیر را به فایل module.go اضافه کنید:

package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/types"
   "github.com/cosmos/cosmos-sdk/baseapp"
   "github.com/cosmos/cosmos-sdk/x/<module_name>/keeper"
   "github.com/cosmos/cosmos-sdk/x/<module_name>/handler"
)

type Module struct {
   keeper keeper.Keeper
}

func NewModule(k keeper.Keeper) *Module {
   return &Module{keeper: k}
}

func (m *Module) BeginBlock(ctx types.Context, req types.RequestBeginBlock) {
   // Logic for begin block
}

func (m *Module) EndBlock(ctx types.Context, req types.RequestEndBlock) {
   // Logic for end block
}

func (m *Module) InitGenesis(ctx types.Context, data json.RawMessage) ([]types.ValidatorUpdate, error) {
   // Logic to initialize genesis state
}

func (m *Module) Route() string {
   return "<module_name>"
}

func (m *Module) NewHandler() types.Handler {
   return handler.NewHandler(m.keeper)
}

3. ایجاد فایل keeper.go

فایل keeper.go مسئول ذخیره‌سازی و مدیریت وضعیت ماژول است. در این فایل، شما می‌توانید توابعی برای ذخیره‌سازی داده‌ها، بازیابی و تغییر وضعیت ماژول تعریف کنید.

دستور ایجاد فایل keeper.go
touch ./x/<module_name>/keeper.go

سپس محتوای زیر را به فایل keeper.go اضافه کنید:

package keeper

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/types"
)

type Keeper struct {
   storeKey types.StoreKey
}

func NewKeeper(storeKey types.StoreKey) Keeper {
   return Keeper{storeKey: storeKey}
}

func (k Keeper) SetValue(ctx types.Context, key string, value []byte) {
   store := ctx.KVStore(k.storeKey)
   store.Set([]byte(key), value)
}

func (k Keeper) GetValue(ctx types.Context, key string) ([]byte, bool) {
   store := ctx.KVStore(k.storeKey)
   value := store.Get([]byte(key))
   return value, value != nil
}

4. ایجاد فایل handler.go

فایل handler.go مسئول پردازش پیام‌ها و درخواست‌هایی است که به ماژول ارسال می‌شود. در این فایل، شما باید انواع پیام‌ها را تعریف کرده و نحوه پردازش آن‌ها را تعیین کنید.

دستور ایجاد فایل handler.go
touch ./x/<module_name>/handler.go

سپس محتوای زیر را به فایل handler.go اضافه کنید:

package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

func NewHandler(k keeper.Keeper) types.Handler {
   return func(ctx types.Context, msg types.Msg) (*types.Result, error) {
      switch msg := msg.(type) {
      case types.MsgSend:
         return handleMsgSend(ctx, k, msg)
      default:
         return nil, types.ErrUnknownRequest("unrecognized message type")
      }
   }
}

func handleMsgSend(ctx types.Context, k keeper.Keeper, msg types.MsgSend) (*types.Result, error) {
   // Logic to process send message
   return &types.Result{}, nil
}

5. ایجاد فایل msg.go

فایل msg.go مسئول تعریف پیام‌ها و درخواست‌های ماژول است. پیام‌ها شامل داده‌هایی هستند که به بلاکچین ارسال می‌شوند.

دستور ایجاد فایل msg.go
touch ./x/<module_name>/msg.go

سپس محتوای زیر را به فایل msg.go اضافه کنید:

package types

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type MsgSend struct {
   From   sdk.AccAddress `json:"from"`
   To     sdk.AccAddress `json:"to"`
   Amount sdk.Coins      `json:"amount"`
}

func (msg MsgSend) Route() string {
   return "send"
}

func (msg MsgSend) Type() string {
   return "Send"
}

func (msg MsgSend) ValidateBasic() error {
   if msg.Amount.IsAnyNegative() {
       return sdk.ErrInvalidCoins("negative coins are not allowed")
   }
   return nil
}

func (msg MsgSend) GetSigners() []sdk.AccAddress {
   return []sdk.AccAddress{msg.From}
}

6. پیکربندی ماژول در فایل app.go

برای فعال‌سازی ماژول، باید آن را در فایل app.go که مسئول پیکربندی بلاکچین است، ثبت کنیم.

دستور ایجاد تغییرات در فایل app.go
touch ./app/app.go

سپس محتوای زیر را به فایل app.go اضافه کنید:

package app

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>"
)

func NewApp() *App {
   app := &App{}
   
   // Register module
   app.moduleManager = module.NewManager(
      <module_name>.NewModule(),
   )

   return app
}

جمع‌بندی

در این بخش، نحوه ایجاد ساختار اولیه ماژول در Cosmos SDK را بررسی کردیم. ماژول‌ها از اجزای مختلفی تشکیل می‌شوند که شامل فایل‌های module.go، keeper.go، handler.go، msg.go و پیکربندی آن‌ها در فایل app.go است. هرکدام از این فایل‌ها نقش مهمی در عملکرد ماژول ایفا می‌کنند و به شما این امکان را می‌دهند که ماژول خود را به‌طور کامل پیاده‌سازی کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف پیام‌ها (Messages) و انواع تراکنش‌ها” subtitle=”توضیحات کامل”]در بلاکچین‌های مبتنی بر Cosmos SDK، پیام‌ها (Messages) یکی از اجزای کلیدی در فرآیند تعامل با شبکه هستند. پیام‌ها درخواست‌هایی هستند که از طرف کاربران ارسال می‌شوند تا تغییراتی در وضعیت بلاکچین ایجاد کنند. به عبارت دیگر، پیام‌ها نمایانگر تراکنش‌ها یا عملیات‌هایی هستند که در شبکه بلاکچین اجرا می‌شوند. هر پیام می‌تواند به ماژول‌های مختلف ارسال شود تا عملیات‌های مختلفی مانند انتقال توکن، ایجاد قرارداد یا سایر تغییرات در بلاکچین انجام شود.

1. ساختار کلی پیام‌ها (Messages)

پیام‌ها معمولاً ساختار خاصی دارند که باید شامل چندین بخش اصلی باشند:

  • Route: مسیری که پیام باید از آن عبور کند. معمولاً به نام ماژول مربوطه است.
  • Type: نوع عملیاتی که باید در شبکه انجام شود.
  • Signers: آدرس‌هایی که پیام را امضا می‌کنند. این معمولاً به حساب‌های ارسال‌کننده تراکنش مرتبط است.
  • ValidateBasic: تابعی که برای اعتبارسنجی داده‌های پیام استفاده می‌شود تا اطمینان حاصل شود که اطلاعات وارد شده صحیح و منطقی هستند.

برای مثال، در یک پیام انتقال توکن (Transfer), مسیر آن معمولاً به ماژول انتقال توکن (مثل bank) مربوط می‌شود.

2. تعریف پیام‌ها در Cosmos SDK

برای تعریف پیام‌ها در Cosmos SDK، باید یک ساختار جدید برای هر پیام ایجاد کنید. این ساختار باید از اینترفیس Msg که توسط Cosmos SDK ارائه شده، پیروی کند. همچنین برای هر پیام، باید متدهایی نظیر Route(), Type(), ValidateBasic() و GetSigners() را پیاده‌سازی کنید.

دستور ایجاد فایل msg.go

ابتدا، باید یک فایل msg.go در دایرکتوری ماژول خود بسازید.

touch ./x/<module_name>/msg.go

سپس، ساختار پیام را تعریف کرده و متدهای موردنیاز را پیاده‌سازی کنید.

مثال پیام برای انتقال توکن
package types

import (
   sdk "github.com/cosmos/cosmos-sdk/types"
)

type MsgSend struct {
   From   sdk.AccAddress `json:"from"`
   To     sdk.AccAddress `json:"to"`
   Amount sdk.Coins      `json:"amount"`
}

// Route returns the message route for MsgSend
func (msg MsgSend) Route() string {
   return "bank"
}

// Type returns the message type for MsgSend
func (msg MsgSend) Type() string {
   return "Send"
}

// ValidateBasic validates the MsgSend message
func (msg MsgSend) ValidateBasic() error {
   if msg.Amount.IsAnyNegative() {
      return sdk.ErrInvalidCoins("negative coins are not allowed")
   }
   if msg.From.Empty() || msg.To.Empty() {
      return sdk.ErrInvalidAddress("addresses cannot be empty")
   }
   return nil
}

// GetSigners returns the signers for MsgSend
func (msg MsgSend) GetSigners() []sdk.AccAddress {
   return []sdk.AccAddress{msg.From}
}

در این مثال، پیام MsgSend یک انتقال توکن از آدرس From به آدرس To با مقدار Amount است. متد ValidateBasic برای اطمینان از صحت داده‌ها استفاده می‌شود و GetSigners آدرس‌های امضا کننده را برمی‌گرداند.

3. انواع تراکنش‌ها در Cosmos SDK

تراکنش‌ها در Cosmos SDK به طور کلی از چند نوع مختلف هستند که از پیام‌های مختلف برای انجام عملیات‌های مختلف در شبکه استفاده می‌کنند. در زیر انواع رایج تراکنش‌ها آورده شده است:

  • تراکنش‌های انتقال توکن (MsgSend): این تراکنش‌ها برای انتقال توکن‌ها از یک حساب به حساب دیگر در شبکه استفاده می‌شوند. این تراکنش‌ها می‌توانند شامل یک یا چند توکن از یک یا چند نوع باشند.
  • تراکنش‌های ایجاد حساب یا ارتقاء حساب: برخی از تراکنش‌ها برای ایجاد حساب‌های جدید یا تغییرات در ویژگی‌های یک حساب (مثل ارتقاء یا تغییر دسترسی‌ها) استفاده می‌شوند.
  • تراکنش‌های قراردادهای هوشمند: در صورتی که شبکه از قراردادهای هوشمند پشتیبانی کند، پیام‌ها می‌توانند شامل درخواست‌هایی برای فراخوانی قراردادهای هوشمند و انجام عملیات خاص در بلاکچین باشند.
  • تراکنش‌های نظارت بر وضعیت شبکه (مثل ذخیره اطلاعات genesis): این تراکنش‌ها برای انجام تنظیمات مربوط به شبکه و بلاکچین، مانند راه‌اندازی بلاکچین یا ذخیره‌سازی اطلاعات حالت اولیه استفاده می‌شوند.

4. پردازش پیام‌ها و تراکنش‌ها در Cosmos SDK

پس از دریافت پیام‌ها، بلاکچین Cosmos SDK باید پیام‌ها را پردازش کند و بسته به نوع آن‌ها، عملیات مناسب را انجام دهد. این فرآیند در handler ماژول انجام می‌شود. در handler، پیام‌ها بر اساس نوع خود شناسایی شده و پردازش می‌شوند.

مثال پردازش پیام در handler.go
package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

func NewHandler(k keeper.Keeper) types.Handler {
   return func(ctx types.Context, msg types.Msg) (*types.Result, error) {
      switch msg := msg.(type) {
      case types.MsgSend:
         return handleMsgSend(ctx, k, msg)
      default:
         return nil, types.ErrUnknownRequest("unrecognized message type")
      }
   }
}

func handleMsgSend(ctx types.Context, k keeper.Keeper, msg types.MsgSend) (*types.Result, error) {
   // Logic to process send message
   // Update state or transfer tokens based on the message data
   k.SetValue(ctx, "key", []byte("value"))
   return &types.Result{}, nil
}

در اینجا، handler بر اساس نوع پیام (مثلاً MsgSend) پردازش را انجام می‌دهد. در این مثال، تابع handleMsgSend مسئول پردازش تراکنش‌های انتقال توکن است.

5. مسیر فایل‌های مربوط به پیام‌ها

  • مسیر فایل پیام‌ها: ./x/<module_name>/msg.go
  • مسیر فایل handler: ./x/<module_name>/handler.go

جمع‌بندی

در این بخش، نحوه تعریف و پردازش پیام‌ها در Cosmos SDK را بررسی کردیم. پیام‌ها به‌عنوان درخواست‌هایی برای تغییر وضعیت بلاکچین عمل می‌کنند و با استفاده از ماژول‌های مختلف در Cosmos SDK پردازش می‌شوند. هر پیام دارای ساختار خاصی است که شامل داده‌هایی نظیر آدرس‌های امضا کننده، نوع پیام و داده‌های مرتبط با پیام می‌باشد. برای پردازش این پیام‌ها در بلاکچین، از handler استفاده می‌شود که پیام‌ها را شناسایی کرده و عملیات مناسب را بر اساس آن‌ها انجام می‌دهد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیاده‌سازی منطق Handler برای پردازش تراکنش‌ها” subtitle=”توضیحات کامل”]در Cosmos SDK، پس از دریافت پیام‌ها (Messages)، پردازش تراکنش‌ها و اجرای منطق کسب‌وکار مرتبط با آن‌ها به عهده‌ی handler است. Handler یک تابع است که وظیفه‌ی پردازش پیام‌ها را بر عهده دارد و عملیات‌های مختلفی را بسته به نوع پیام‌ها انجام می‌دهد. در این بخش، نحوه پیاده‌سازی Handler و اتصال آن به پیام‌ها (Messages) و Keeper را بررسی خواهیم کرد.

1. مفهوم Handler در Cosmos SDK

Handler در Cosmos SDK یک واسط بین پیام‌ها و منطق پردازش تراکنش است. هر نوع پیام که ارسال می‌شود، باید یک handler مخصوص به خود داشته باشد که به آن نوع پیام پاسخ دهد. Handler مسئولیت‌های زیر را بر عهده دارد:

  • شناسایی پیام‌ها بر اساس نوع آن‌ها
  • اعتبارسنجی داده‌های پیام
  • انجام عملیات‌های مربوط به تغییر وضعیت در بلاکچین
  • برگرداندن نتایج و پیغام‌های تراکنش

2. ساختار کلی Handler

برای هر ماژول در Cosmos SDK، باید یک handler بسازید که مسئول پردازش پیام‌ها باشد. Handler باید با استفاده از متد NewHandler به Cosmos SDK معرفی شود.

تعریف یک handler برای ماژول

در ابتدا، یک تابع NewHandler ایجاد می‌کنیم که مسئولیت پردازش پیام‌ها را بر عهده دارد.

package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

// NewHandler returns a handler for the module
func NewHandler(k keeper.Keeper) types.Handler {
   return func(ctx types.Context, msg types.Msg) (*types.Result, error) {
      switch msg := msg.(type) {
      case types.MsgSend:
         return handleMsgSend(ctx, k, msg)
      default:
         return nil, types.ErrUnknownRequest("unrecognized message type")
      }
   }
}

در اینجا، تابع NewHandler یک handler جدید می‌سازد که پیام‌ها را بررسی کرده و بسته به نوع پیام، تابع مناسب برای پردازش آن را فراخوانی می‌کند. در این مثال، ما پیام نوع MsgSend را بررسی کرده‌ایم که معمولاً برای انتقال توکن‌ها استفاده می‌شود.

3. پردازش پیام‌ها در Handler

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

پیاده‌سازی handler برای MsgSend
package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
   "github.com/cosmos/cosmos-sdk/x/bank/types"
)

// handleMsgSend processes the MsgSend message
func handleMsgSend(ctx types.Context, k keeper.Keeper, msg types.MsgSend) (*types.Result, error) {
   // ابتدا اعتبارسنجی پیام
   if err := msg.ValidateBasic(); err != nil {
      return nil, err
   }

   // انجام عملیات انتقال توکن‌ها
   // در اینجا از keeper برای انتقال توکن‌ها استفاده می‌کنیم
   err := k.SendCoins(ctx, msg.From, msg.To, msg.Amount)
   if err != nil {
      return nil, err
   }

   // برگرداندن نتیجه تراکنش
   return &types.Result{}, nil
}

در این مثال، تابع handleMsgSend مسئول انجام عملیات انتقال توکن‌ها است. این تابع ابتدا داده‌های پیام را با استفاده از متد ValidateBasic() اعتبارسنجی می‌کند. سپس با استفاده از Keeper، توکن‌ها را از آدرس From به آدرس To منتقل می‌کند. در نهایت، یک نتیجه تراکنش به صورت types.Result{} برمی‌گرداند.

4. استفاده از Keeper برای تغییر وضعیت

در پیاده‌سازی‌های پیچیده‌تر، Handler باید از Keeper برای انجام تغییرات در وضعیت بلاکچین استفاده کند. Keeper به عنوان یک لایه میانه، ارتباط بین داده‌ها و وضعیت بلاکچین را فراهم می‌کند. در این مثال، از تابع SendCoins برای انتقال توکن‌ها استفاده کرده‌ایم.

مثال تابع SendCoins در Keeper
package keeper

import (
   "github.com/cosmos/cosmos-sdk/types"
   "github.com/cosmos/cosmos-sdk/x/bank/types"
)

// SendCoins handles transferring coins between two accounts
func (k Keeper) SendCoins(ctx types.Context, from types.AccAddress, to types.AccAddress, amount types.Coins) error {
   // دریافت اطلاعات موجودی از دو حساب
   fromBalance := k.GetBalance(ctx, from)
   toBalance := k.GetBalance(ctx, to)

   // بررسی موجودی حساب مبدا
   if fromBalance.IsAllLT(amount) {
      return types.ErrInsufficientFunds("insufficient funds in sender's account")
   }

   // به‌روز‌رسانی موجودی حساب‌ها
   k.SetBalance(ctx, from, fromBalance.Sub(amount))
   k.SetBalance(ctx, to, toBalance.Add(amount))

   return nil
}

در اینجا، تابع SendCoins موجودی حساب‌های ارسال‌کننده و گیرنده را بررسی کرده و در صورت کافی بودن موجودی، توکن‌ها را انتقال می‌دهد.

5. تنظیمات و فایل‌های مربوطه

  • فایل handler: ./x/<module_name>/handler.go
  • فایل keeper: ./x/<module_name>/keeper/keeper.go
  • فایل پیام‌ها: ./x/<module_name>/msg.go

6. ثبت Handler در module

پس از پیاده‌سازی handler، باید آن را به ماژول خود معرفی کنید. این کار در فایل module.go انجام می‌شود.

package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/handler"
   "<module_name>/keeper"
)

// RegisterHandlers registers the message handlers for the module
func RegisterHandlers(k keeper.Keeper) {
   types.RegisterModuleRoutes(k.Router(), handler.NewHandler(k))
}

در اینجا، تابع RegisterHandlers handler‌ها را به ماژول معرفی می‌کند. این handler‌ها به ماژول می‌گویند که چگونه پیام‌ها را پردازش کند.

جمع‌بندی

در این بخش، پیاده‌سازی منطق Handler برای پردازش تراکنش‌ها در Cosmos SDK را بررسی کردیم. Handler مسئول دریافت پیام‌ها و پردازش آن‌ها است. برای هر نوع پیام، باید handler مخصوص به آن را تعریف کنیم که می‌تواند عملیات‌های مختلفی مانند انتقال توکن، به‌روزرسانی وضعیت یا انجام محاسبات را انجام دهد. برای پردازش پیام‌ها، از Keeper برای تغییر وضعیت در بلاکچین استفاده می‌کنیم. این عملیات‌ها به صورت توابع جداگانه در handler پیاده‌سازی می‌شوند و در نهایت نتیجه به تراکنش بازگردانده می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”رجیستر کردن ماژول در بلاکچین” subtitle=”توضیحات کامل”]برای راه‌اندازی یک ماژول سفارشی در Cosmos SDK، بعد از پیاده‌سازی اجزای مختلف آن مانند handler، keeper و پیام‌ها، باید ماژول را در بلاکچین ثبت (رجیستر) کنیم. این کار به Cosmos SDK می‌گوید که این ماژول باید در فرآیندهای مختلف بلاکچین (مانند پردازش تراکنش‌ها، تغییر وضعیت و …) مورد استفاده قرار گیرد.

رجیستر کردن ماژول شامل ثبت کردن آن در قسمت‌های مختلف بلاکچین از جمله router, querier, handler و keeper است. این فرآیند اطمینان می‌دهد که ماژول در سیستم بلاکچین به‌درستی شناسایی و قابل دسترسی خواهد بود.

در این بخش، روند رجیستر کردن ماژول در بلاکچین Cosmos SDK را با جزئیات شرح خواهیم داد.

1. ساختار کلی رجیستر کردن ماژول

برای رجیستر کردن ماژول در Cosmos SDK، ابتدا باید فایل‌های اصلی مربوط به ماژول خود را معرفی کرده و آن‌ها را در فایل app.go یا module.go اضافه کنیم.

مراحل اصلی رجیستر کردن ماژول:
  • تعریف و معرفی handler ماژول
  • تعریف و معرفی keeper ماژول
  • رجیستر کردن routes و queriers
  • اضافه کردن ماژول به بلوک اصلی Cosmos SDK

2. رجیستر کردن handler

Handler ماژول را باید در تابع RegisterHandlers رجیستر کنیم تا بتوانیم پیام‌ها را پردازش کنیم. برای این کار، باید handler مربوطه را از فایل handler به ماژول اضافه کنیم.

تعریف handler و رجیستر کردن آن:
package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/handler"
   "<module_name>/keeper"
   "<module_name>/types"
)

// RegisterHandlers registers the message handlers for the module
func RegisterHandlers(k keeper.Keeper) {
   types.RegisterModuleRoutes(k.Router(), handler.NewHandler(k))
}

در اینجا، تابع RegisterHandlers مسئولیت ثبت handler ماژول را به عهده دارد. با استفاده از متد types.RegisterModuleRoutes، handler ماژول در بلاکچین ثبت می‌شود.

3. رجیستر کردن Keeper

برای مدیریت وضعیت، باید keeper را به بلاکچین اضافه کنیم. Keeper مسئول ذخیره‌سازی و بازیابی داده‌ها در بلاکچین است.

تعریف Keeper و رجیستر کردن آن:
package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/x/bank/keeper"
   "<module_name>/keeper"
   "github.com/cosmos/cosmos-sdk/types"
)

// RegisterKeeper registers the keeper for the module
func RegisterKeeper(k keeper.Keeper) {
   // ثبت Keeper در بلاکچین برای ذخیره و بازیابی داده‌ها
   k.SetModuleAccount(types.NewEmptyModuleAccount("<module_name>"))
}

در اینجا، تابع RegisterKeeper Keeper را در بلاکچین ثبت می‌کند تا به صورت موثر داده‌ها و تراکنش‌ها را مدیریت کند.

4. رجیستر کردن Routes و Queriers

برای ایجاد و مدیریت مسیرها و درخواست‌های query در ماژول، باید این اجزا را هم در بلاکچین ثبت کنیم. به این صورت می‌توانیم مسیرهای HTTP و توابع query برای دسترسی به داده‌ها را در بلاکچین معرفی کنیم.

تعریف routes و queriers:
package <module_name>

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/querier"
   "<module_name>/handler"
)

// RegisterRoutes registers the module's routes with the router
func RegisterRoutes(r types.Router) {
   // ثبت مسیرهای ماژول
   r.AddRoute("<module_name>/query", querier.QueryHandler)
   r.AddRoute("<module_name>/tx", handler.NewHandler(k))
}

در اینجا، RegisterRoutes مسیرها را برای انجام query و پردازش تراکنش‌ها تنظیم می‌کند.

5. ثبت ماژول در بلاکچین

برای ثبت کامل ماژول در بلاکچین، باید آن را در فایل app.go یا module.go به سیستم بلاکچین معرفی کنیم. این فایل‌ها وظیفه دارند که ماژول را به دنیای خارج از بلاکچین معرفی کنند.

ثبت ماژول در app.go یا module.go:
package app

import (
   "<module_name>/module"
   "github.com/cosmos/cosmos-sdk/types"
)

func (app *App) RegisterModules() {
   app.ModuleManager.RegisterModule("<module_name>", module.NewModule())
}

در اینجا، RegisterModules ماژول را به اپلیکیشن بلاکچین معرفی می‌کند تا از این پس از آن در پردازش‌ها استفاده شود.

6. ساختار نهایی رجیستر ماژول

در این بخش، ماژول به صورت کامل در بلاکچین ثبت شده است. در نهایت باید مطمئن شویم که ماژول تمامی نیازهای سیستم را برآورده می‌کند و آماده برای پردازش پیام‌ها و تعاملات با سایر ماژول‌ها است.

ساختار فایل‌ها برای رجیستر کردن ماژول:
  • فایل handler: ./x/<module_name>/handler.go
  • فایل keeper: ./x/<module_name>/keeper/keeper.go
  • فایل routes و queriers: ./x/<module_name>/querier.go
  • فایل module.go: ./x/<module_name>/module.go
  • فایل app.go: ./app.go

جمع‌بندی

رجیستر کردن ماژول در بلاکچین Cosmos SDK شامل چندین مرحله است که در آن ماژول‌ها به سیستم بلاکچین معرفی می‌شوند. ابتدا باید handler، keeper، و مسیرهای query ماژول را تعریف کرده و سپس آن‌ها را در فایل‌های مربوطه ثبت کنیم. پس از این مراحل، ماژول آماده است که در فرآیندهای مختلف بلاکچین مانند پردازش تراکنش‌ها و پاسخ به درخواست‌های query استفاده شود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. مدیریت State در ماژول‌های سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مفهوم Store و Key-Value Storage در Cosmos SDK” subtitle=”توضیحات کامل”]Store در Cosmos SDK یکی از اجزای کلیدی برای ذخیره و بازیابی داده‌ها در بلاکچین است. این سیستم ذخیره‌سازی به صورت Key-Value کار می‌کند، به این معنی که هر مقدار (Value) در مقابل یک کلید (Key) ذخیره می‌شود. این ساختار باعث افزایش سرعت خواندن و نوشتن داده‌ها شده و امکان پردازش موثر تراکنش‌ها را فراهم می‌کند.

هر ماژول در Cosmos SDK برای مدیریت داده‌های خود از یک KVStore (Key-Value Store) استفاده می‌کند. این پایگاه داده سطح پایین بر روی MultiStore ساخته شده است، که اجازه می‌دهد هر ماژول فضای ذخیره‌سازی اختصاصی خود را داشته باشد و فقط به داده‌های خود دسترسی پیدا کند.

در این بخش، ساختار کلی Store در Cosmos SDK، نحوه استفاده از آن، و پیاده‌سازی یک Key-Value Store برای ذخیره داده‌های یک ماژول را بررسی می‌کنیم.


۱. انواع Store در Cosmos SDK

Cosmos SDK چندین نوع Store برای ذخیره‌سازی داده‌ها ارائه می‌دهد:

۱.۱. KVStore (Key-Value Store)
  • یک پایگاه داده ساده که اطلاعات را به‌صورت کلید-مقدار ذخیره می‌کند.
  • سریع و بهینه برای خواندن و نوشتن داده‌ها.
۱.۲. Transient Store
  • برای ذخیره‌سازی موقت داده‌ها در یک بلاک استفاده می‌شود.
  • پس از اتمام بلاک، داده‌ها حذف می‌شوند.
۱.۳. Memory Store
  • داده‌ها را فقط در حافظه نگه می‌دارد و روی دیسک ذخیره نمی‌شود.
  • برای پردازش‌های موقت استفاده می‌شود.
۱.۴. Gas Meter Store
  • برای محاسبه هزینه گس (Gas) در تراکنش‌ها استفاده می‌شود.

۲. پیاده‌سازی Store در Cosmos SDK

برای استفاده از Store در یک ماژول، باید Keeper ماژول را پیاده‌سازی کرده و یک Key-Value Store تعریف کنیم.

۲.۱. تعریف Key برای ذخیره داده‌ها

قبل از اینکه داده‌ای را در Store ذخیره کنیم، باید یک کلید منحصر‌به‌فرد برای آن تعریف کنیم.

مسیر فایل:
./x/<module_name>/types/keys.go

package types

const (
   ModuleName = "<module_name>"
   StoreKey   = ModuleName
   RouterKey  = ModuleName
)

var (
   KeyPrefixMyData = []byte("my_data:")
)

در اینجا:

  • ModuleName نام ماژول را مشخص می‌کند.
  • StoreKey برای رجیستر کردن Store در MultiStore استفاده می‌شود.
  • KeyPrefixMyData یک پیشوند برای کلید‌های ذخیره‌سازی تعریف می‌کند.

۲.۲. تعریف Store در Keeper ماژول

برای مدیریت داده‌ها در ماژول، باید Keeper را پیاده‌سازی کنیم.

مسیر فایل:
./x/<module_name>/keeper/keeper.go

package keeper

import (
   "github.com/cosmos/cosmos-sdk/store/prefix"
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/types"
)

// Keeper ساختار داده‌ای برای مدیریت Store را تعریف می‌کند.
type Keeper struct {
   storeKey types.StoreKey
}

// SetMyData مقدار داده را در Store ذخیره می‌کند.
func (k Keeper) SetMyData(ctx types.Context, key string, value []byte) {
   store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
   store.Set([]byte(key), value)
}

// GetMyData مقدار داده را از Store بازیابی می‌کند.
func (k Keeper) GetMyData(ctx types.Context, key string) ([]byte, bool) {
   store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
   value := store.Get([]byte(key))
   if value == nil {
      return nil, false
   }
   return value, true
}

// DeleteMyData مقدار داده را از Store حذف می‌کند.
func (k Keeper) DeleteMyData(ctx types.Context, key string) {
   store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
   store.Delete([]byte(key))
}

در اینجا:

  • SetMyData: داده‌ای را در Store ذخیره می‌کند.
  • GetMyData: داده‌ای را از Store بازیابی می‌کند.
  • DeleteMyData: داده‌ای را از Store حذف می‌کند.

۲.۳. رجیستر کردن Store در بلاکچین

پس از تعریف Store در Keeper، باید آن را در app.go رجیستر کنیم.

مسیر فایل:
./app.go

package app

import (
   "<module_name>/keeper"
   "<module_name>/types"
)

func (app *App) RegisterStores() {
   app.MountStores(types.StoreKey)
}

با این کار، Store در سیستم بلاکچین ثبت می‌شود و داده‌ها قابل ذخیره و بازیابی خواهند بود.


۳. استفاده از Store در یک پیام (Message)

حالا که Store را پیاده‌سازی کردیم، می‌توانیم از آن برای پردازش تراکنش‌ها استفاده کنیم. در این مثال، یک پیام (Message) برای ذخیره‌سازی داده پیاده‌سازی می‌کنیم.

۳.۱. تعریف پیام ذخیره داده

مسیر فایل:
./x/<module_name>/types/messages.go

package types

import "github.com/cosmos/cosmos-sdk/types"

// MsgSetData پیام ذخیره‌سازی داده در Store را تعریف می‌کند.
type MsgSetData struct {
   Creator string
   Key     string
   Value   []byte
}

// NewMsgSetData مقدار جدیدی از داده را ایجاد می‌کند.
func NewMsgSetData(creator, key string, value []byte) MsgSetData {
   return MsgSetData{
      Creator: creator,
      Key:     key,
      Value:   value,
   }
}

۳.۲. پردازش پیام و ذخیره داده در Store

مسیر فایل:
./x/<module_name>/handler.go

package handler

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

// HandleMsgSetData پیام ذخیره داده را پردازش می‌کند.
func HandleMsgSetData(ctx types.Context, k keeper.Keeper, msg types.MsgSetData) (*types.Result, error) {
   k.SetMyData(ctx, msg.Key, msg.Value)
   return &types.Result{}, nil
}

۴. بررسی داده‌های ذخیره شده در Store

پس از اجرای تراکنش‌ها، می‌توان داده‌های ذخیره شده را با استفاده از query بازیابی کرد.

۴.۱. تعریف query برای بازیابی داده

مسیر فایل:
./x/<module_name>/querier.go

package querier

import (
   "github.com/cosmos/cosmos-sdk/types"
   "<module_name>/keeper"
   "<module_name>/types"
)

// QueryGetData داده‌ها را از Store بازیابی می‌کند.
func QueryGetData(ctx types.Context, k keeper.Keeper, key string) ([]byte, error) {
   data, found := k.GetMyData(ctx, key)
   if !found {
      return nil, types.ErrKeyNotFound
   }
   return data, nil
}

جمع‌بندی

در این بخش، نحوه پیاده‌سازی Store و Key-Value Storage در Cosmos SDK را بررسی کردیم. مراحل اصلی عبارت بودند از:

  • تعریف کلیدها برای ذخیره‌سازی داده‌ها
  • پیاده‌سازی Keeper برای مدیریت داده‌ها
  • ثبت Store در بلاکچین
  • استفاده از Store در پیام‌ها و تراکنش‌ها
  • پیاده‌سازی query برای بازیابی داده‌ها

با استفاده از این ساختار، می‌توان داده‌های مختلف را در بلاکچین Cosmos SDK ذخیره، بازیابی و حذف کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از Keeper برای خواندن و نوشتن داده‌ها” subtitle=”توضیحات کامل”]Keeper در Cosmos SDK، نقش واسط بین ماژول و Store را ایفا می‌کند و وظیفه‌ی مدیریت خواندن و نوشتن داده‌ها را بر عهده دارد. این ساختار باعث می‌شود که داده‌ها فقط از طریق توابع مشخص و کنترل‌شده در اختیار سایر قسمت‌های ماژول قرار بگیرند. استفاده از Keeper باعث جداسازی لایه‌های منطقی و افزایش امنیت و انعطاف‌پذیری کد می‌شود.

در این بخش، نحوه استفاده از Keeper برای خواندن و نوشتن داده‌ها را با مثال‌های عملی بررسی می‌کنیم.


تعریف Keeper و مقداردهی اولیه

قبل از پیاده‌سازی توابع خواندن و نوشتن داده‌ها، باید Keeper را در ماژول خود تعریف کنیم.

مسیر فایل:
./x/<module_name>/keeper/keeper.go

package keeper

import (
    "github.com/cosmos/cosmos-sdk/store/prefix"
    "github.com/cosmos/cosmos-sdk/types"
    "<module_name>/types"
)

// Keeper ساختار مدیریت داده‌ها را تعریف می‌کند.
type Keeper struct {
    storeKey types.StoreKey
}

// NewKeeper یک نمونه جدید از Keeper را مقداردهی اولیه می‌کند.
func NewKeeper(storeKey types.StoreKey) Keeper {
    return Keeper{storeKey: storeKey}
}

نوشتن داده‌ها در Store

برای ذخیره داده‌ها در بلاکچین، از Set استفاده می‌کنیم. این تابع یک مقدار (Value) را با استفاده از یک کلید (Key) در Store ذخیره می‌کند.

پیاده‌سازی تابع نوشتن داده‌ها

مسیر فایل:
./x/<module_name>/keeper/keeper.go

// SetData مقدار مشخصی را در Store ذخیره می‌کند.
func (k Keeper) SetData(ctx types.Context, key string, value []byte) {
    store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
    store.Set([]byte(key), value)
}

در اینجا:

  • ابتدا یک Prefix Store ایجاد می‌شود که تمام داده‌ها را با پیشوند KeyPrefixMyData ذخیره می‌کند.
  • سپس مقدار داده با استفاده از متد Set در Store ذخیره می‌شود.

خواندن داده‌ها از Store

برای خواندن داده‌های ذخیره‌شده، از Get استفاده می‌کنیم. این تابع مقدار متناظر با کلید داده‌شده را از Store بازیابی می‌کند.

پیاده‌سازی تابع خواندن داده‌ها

مسیر فایل:
./x/<module_name>/keeper/keeper.go

// GetData مقدار ذخیره‌شده را از Store بازیابی می‌کند.
func (k Keeper) GetData(ctx types.Context, key string) ([]byte, bool) {
    store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
    value := store.Get([]byte(key))
    if value == nil {
        return nil, false
    }
    return value, true
}

در اینجا:

  • ابتدا Prefix Store ایجاد می‌شود.
  • مقدار مربوط به کلید مشخص‌شده از Store خوانده می‌شود.
  • اگر مقدار یافت نشود، مقدار nil همراه با false برگردانده می‌شود.

حذف داده‌ها از Store

برای حذف یک مقدار خاص از Store، از Delete استفاده می‌کنیم.

پیاده‌سازی تابع حذف داده‌ها

مسیر فایل:
./x/<module_name>/keeper/keeper.go

// DeleteData مقدار مشخص‌شده را از Store حذف می‌کند.
func (k Keeper) DeleteData(ctx types.Context, key string) {
    store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixMyData)
    store.Delete([]byte(key))
}

استفاده از Keeper در Handler برای پردازش پیام‌ها

در Cosmos SDK، داده‌ها از طریق پیام‌ها (Msg) به ماژول ارسال می‌شوند. در این بخش، نحوه استفاده از Keeper برای ذخیره و بازیابی داده‌ها در پیام‌ها را بررسی می‌کنیم.

تعریف پیام برای ذخیره داده

مسیر فایل:
./x/<module_name>/types/messages.go

package types

import "github.com/cosmos/cosmos-sdk/types"

// MsgSetData پیام ذخیره‌سازی داده در Store را تعریف می‌کند.
type MsgSetData struct {
    Creator string
    Key     string
    Value   []byte
}

// NewMsgSetData مقدار جدیدی از داده را ایجاد می‌کند.
func NewMsgSetData(creator, key string, value []byte) MsgSetData {
    return MsgSetData{
        Creator: creator,
        Key:     key,
        Value:   value,
    }
}
پردازش پیام برای ذخیره داده

مسیر فایل:
./x/<module_name>/handler.go

package handler

import (
    "github.com/cosmos/cosmos-sdk/types"
    "<module_name>/keeper"
    "<module_name>/types"
)

// HandleMsgSetData پیام ذخیره داده را پردازش می‌کند.
func HandleMsgSetData(ctx types.Context, k keeper.Keeper, msg types.MsgSetData) (*types.Result, error) {
    k.SetData(ctx, msg.Key, msg.Value)
    return &types.Result{}, nil
}

استفاده از Keeper در Query برای بازیابی داده

پس از ذخیره داده‌ها، می‌توانیم از طریق Query آن‌ها را بازیابی کنیم.

تعریف Query برای بازیابی داده

مسیر فایل:
./x/<module_name>/querier.go

package querier

import (
    "github.com/cosmos/cosmos-sdk/types"
    "<module_name>/keeper"
    "<module_name>/types"
)

// QueryGetData داده‌های ذخیره‌شده را از Store بازیابی می‌کند.
func QueryGetData(ctx types.Context, k keeper.Keeper, key string) ([]byte, error) {
    data, found := k.GetData(ctx, key)
    if !found {
        return nil, types.ErrKeyNotFound
    }
    return data, nil
}

جمع‌بندی

در این بخش، نحوه استفاده از Keeper برای خواندن و نوشتن داده‌ها را بررسی کردیم. مراحل اصلی عبارت بودند از:

  • تعریف Keeper و مقداردهی اولیه آن
  • ذخیره داده‌ها در Store با استفاده از Set
  • خواندن داده‌ها از Store با استفاده از Get
  • حذف داده‌ها از Store با استفاده از Delete
  • پردازش پیام‌های تراکنش با استفاده از Keeper
  • پیاده‌سازی Query برای بازیابی داده‌ها

با این روش، می‌توان از Keeper برای کنترل دقیق ذخیره و بازیابی داده‌ها در ماژول‌های Cosmos SDK استفاده کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی MultiStore و نحوه تعامل ماژول‌ها با State” subtitle=”توضیحات کامل”]در Cosmos SDK، تمامی داده‌های ذخیره‌شده در بلاکچین در یک State Machine مدیریت می‌شوند. برای سازماندهی بهتر این داده‌ها، Cosmos SDK از MultiStore استفاده می‌کند که یک ساختار سطح بالا برای ذخیره و مدیریت داده‌های ماژول‌های مختلف است. در این بخش، به بررسی MultiStore و نحوه تعامل ماژول‌ها با State پرداخته می‌شود.


مفهوم MultiStore در Cosmos SDK

MultiStore ساختاری است که چندین KVStore را در خود جای می‌دهد. این ساختار امکان جداسازی داده‌های مربوط به ماژول‌های مختلف را فراهم می‌کند و هر ماژول دارای فضای ذخیره‌سازی مخصوص به خود است.

ویژگی‌های MultiStore:

  • جداسازی داده‌ها: هر ماژول می‌تواند یک Store اختصاصی داشته باشد.
  • افزایش امنیت و یکپارچگی داده‌ها: ماژول‌ها فقط به داده‌های خود دسترسی دارند.
  • بهینه‌سازی پردازش تراکنش‌ها: به دلیل ساختار مجزا، پردازش و به‌روزرسانی State بهینه‌تر انجام می‌شود.

ساختار MultiStore در Cosmos SDK

در Cosmos SDK، MultiStore به‌صورت سلسله‌مراتبی سازماندهی شده است:

  1. MultiStore: سطح بالایی که شامل چندین KVStore است.
  2. Root Store: ریشه‌ای که شامل Commit Store می‌شود.
  3. Commit Store: جایی که تغییرات ذخیره و در بلاکچین ثبت می‌شوند.
  4. KVStore: هر ماژول یک KVStore اختصاصی دارد.

نحوه تعریف StoreKey در ماژول‌ها

در هر ماژول، یک StoreKey برای دسترسی به KVStore آن ماژول تعریف می‌شود.

مسیر فایل:
./x/<module_name>/types/keys.go

package types

import "github.com/cosmos/cosmos-sdk/store/types"

// StoreKey نام کلیدی است که برای ذخیره داده‌های ماژول استفاده می‌شود.
const StoreKey = "<module_name>"

// KeyPrefix یک پیشوند برای ذخیره کلیدهای مربوط به ماژول
func KeyPrefix(p string) []byte {
    return []byte(p)
}

مقداردهی اولیه MultiStore

در فایل app.go، برای هر ماژول یک StoreKey ثبت می‌شود. این مقدار در زمان راه‌اندازی بلاکچین مقداردهی می‌شود.

مسیر فایل:
./app/app.go

package app

import (
    "github.com/cosmos/cosmos-sdk/store/types"
    "<module_name>/types"
)

// مقداردهی اولیه StoreKeys برای هر ماژول
storeKeys := map[string]*types.KVStoreKey{
    types.StoreKey: types.NewKVStoreKey(types.StoreKey),
}

نحوه تعامل ماژول با State

هر ماژول از طریق Context و KVStore خود می‌تواند به داده‌ها دسترسی داشته باشد.

خواندن و نوشتن داده‌ها در State

برای تعامل با State، از KVStore و MultiStore استفاده می‌شود.

// دریافت Store مخصوص ماژول
store := ctx.KVStore(k.storeKey)

// ذخیره مقدار در State
store.Set([]byte("key1"), []byte("value1"))

// خواندن مقدار از State
value := store.Get([]byte("key1"))

ایجاد Prefix Store برای جداسازی داده‌ها

برای سازماندهی بهتر داده‌ها، می‌توان از Prefix Store استفاده کرد که امکان استفاده از پیشوندهای مشخص را برای ذخیره داده‌ها فراهم می‌کند.

import "github.com/cosmos/cosmos-sdk/store/prefix"

// تعریف Prefix Store برای داده‌های ماژول
prefixStore := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix("myprefix"))

// ذخیره داده در Prefix Store
prefixStore.Set([]byte("key1"), []byte("value1"))

// دریافت داده از Prefix Store
value := prefixStore.Get([]byte("key1"))

نحوه تعامل چند ماژول با MultiStore

ماژول‌های مختلف می‌توانند از طریق MultiStore با یکدیگر تعامل داشته باشند. برای مثال، اگر ماژول A بخواهد داده‌ای از ماژول B را بخواند، باید از ctx.KVStore و StoreKey مربوط به ماژول B استفاده کند.

// دریافت Store مربوط به ماژول B
storeB := ctx.KVStore(app.storeKeys["moduleB"])

// خواندن مقدار از Store ماژول B
value := storeB.Get([]byte("key_in_moduleB"))

ثبت MultiStore در Genesis

در فایل genesis.go، اطلاعات مربوط به MultiStore در Genesis ثبت می‌شود.

مسیر فایل:
./x/<module_name>/genesis.go

package <module_name>

import (
    "github.com/cosmos/cosmos-sdk/types"
)

// مقداردهی اولیه Store هنگام راه‌اندازی بلاکچین
func InitGenesis(ctx types.Context, k keeper.Keeper, state GenesisState) {
    for _, data := range state.StoredData {
        k.SetData(ctx, data.Key, data.Value)
    }
}

جمع‌بندی

در این بخش، MultiStore و نحوه تعامل ماژول‌ها با State را بررسی کردیم. نکات مهم شامل:

  • MultiStore ساختاری برای ذخیره داده‌های ماژول‌های مختلف در Cosmos SDK است.
  • هر ماژول یک StoreKey خاص دارد که دسترسی به داده‌های مربوط به آن را مدیریت می‌کند.
  • از Prefix Store برای جداسازی بهتر داده‌ها در یک ماژول استفاده می‌شود.
  • ماژول‌ها می‌توانند از طریق MultiStore با یکدیگر تعامل داشته باشند.
  • مقداردهی اولیه MultiStore در app.go و genesis.go انجام می‌شود.

با این روش، هر ماژول می‌تواند به‌صورت مستقل داده‌های خود را مدیریت کند و درعین‌حال قابلیت تعامل با سایر ماژول‌ها را نیز داشته باشد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. تعریف و مدیریت پیام‌ها و رویدادها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”طراحی انواع پیام‌های سفارشی (Msg)” subtitle=”توضیحات کامل”]در Cosmos SDK، پیام‌ها (Msg) عناصر اصلی برای اجرای تراکنش‌ها در بلاکچین هستند. هر پیام نشان‌دهنده یک عمل خاص است که کاربران می‌توانند آن را ارسال کنند. در این بخش، نحوه طراحی پیام‌های سفارشی برای ماژول‌های Cosmos SDK را بررسی می‌کنیم.


مفهوم پیام (Msg) در Cosmos SDK

هر Msg یک ساختار Go Struct است که داده‌های موردنیاز برای اجرای یک عملیات را ذخیره می‌کند. این پیام‌ها در داخل تراکنش‌ها قرار می‌گیرند و توسط Handler پردازش می‌شوند.

ویژگی‌های پیام‌ها در Cosmos SDK:

  • هر پیام باید ساختار Go Struct باشد.
  • باید رابط sdk.Msg را پیاده‌سازی کند.
  • باید شامل یک تابع ValidateBasic() برای بررسی داده‌های ورودی باشد.
  • باید تابع GetSigners() را پیاده‌سازی کند که آدرس امضاکنندگان پیام را مشخص کند.

ایجاد پیام سفارشی

برای تعریف یک پیام سفارشی، باید یک فایل msg.go در پوشه types ماژول خود ایجاد کنیم.

مسیر فایل: ./x/<module_name>/types/msg.go

package types

import (
    "fmt"

    sdk "github.com/cosmos/cosmos-sdk/types"
)

// تعریف پیام MsgCreateItem
type MsgCreateItem struct {
    Creator sdk.AccAddress `json:"creator" yaml:"creator"`
    Name    string         `json:"name" yaml:"name"`
    Price   int64          `json:"price" yaml:"price"`
}

// NewMsgCreateItem مقداردهی اولیه پیام را انجام می‌دهد
func NewMsgCreateItem(creator sdk.AccAddress, name string, price int64) *MsgCreateItem {
    return &MsgCreateItem{
        Creator: creator,
        Name:    name,
        Price:   price,
    }
}

// پیاده‌سازی متد Route که مسیر ماژول را مشخص می‌کند
func (msg MsgCreateItem) Route() string {
    return RouterKey
}

// پیاده‌سازی متد Type که نوع پیام را مشخص می‌کند
func (msg MsgCreateItem) Type() string {
    return "CreateItem"
}

// بررسی داده‌های ورودی پیام
func (msg MsgCreateItem) ValidateBasic() error {
    if msg.Creator.Empty() {
        return fmt.Errorf("address cannot be empty")
    }
    if len(msg.Name) == 0 {
        return fmt.Errorf("name cannot be empty")
    }
    if msg.Price < 0 {
        return fmt.Errorf("price must be non-negative")
    }
    return nil
}

// مشخص کردن امضاکنندگان پیام
func (msg MsgCreateItem) GetSigners() []sdk.AccAddress {
    return []sdk.AccAddress{msg.Creator}
}

تعریف پیام‌های دیگر

می‌توان پیام‌های مختلفی را برای ماژول ایجاد کرد. برای مثال، پیام ویرایش اطلاعات یک آیتم:

// تعریف پیام MsgUpdateItem
type MsgUpdateItem struct {
    Creator sdk.AccAddress `json:"creator" yaml:"creator"`
    ID      uint64         `json:"id" yaml:"id"`
    Name    string         `json:"name" yaml:"name"`
    Price   int64          `json:"price" yaml:"price"`
}

// مقداردهی اولیه پیام ویرایش
func NewMsgUpdateItem(creator sdk.AccAddress, id uint64, name string, price int64) *MsgUpdateItem {
    return &MsgUpdateItem{
        Creator: creator,
        ID:      id,
        Name:    name,
        Price:   price,
    }
}

// پیاده‌سازی متد Route
func (msg MsgUpdateItem) Route() string {
    return RouterKey
}

// پیاده‌سازی متد Type
func (msg MsgUpdateItem) Type() string {
    return "UpdateItem"
}

// بررسی داده‌های ورودی پیام
func (msg MsgUpdateItem) ValidateBasic() error {
    if msg.Creator.Empty() {
        return fmt.Errorf("address cannot be empty")
    }
    if msg.ID == 0 {
        return fmt.Errorf("invalid ID")
    }
    if len(msg.Name) == 0 {
        return fmt.Errorf("name cannot be empty")
    }
    if msg.Price < 0 {
        return fmt.Errorf("price must be non-negative")
    }
    return nil
}

// مشخص کردن امضاکنندگان پیام
func (msg MsgUpdateItem) GetSigners() []sdk.AccAddress {
    return []sdk.AccAddress{msg.Creator}
}

ثبت پیام‌ها در Msg Service

برای اینکه پیام‌ها در بلاکچین قابل پردازش باشند، باید در interface.go ثبت شوند.

مسیر فایل: ./x/<module_name>/types/msgs_interface.go

package types

import (
    sdk "github.com/cosmos/cosmos-sdk/types"
)

// ثبت پیام‌ها در رابط Msg
func RegisterMsgService(msgServer sdk.MsgServiceRouter) {
    msgServer.RegisterService(&MsgCreateItem{})
    msgServer.RegisterService(&MsgUpdateItem{})
}

افزودن پیام‌ها به gRPC Service

برای پشتیبانی از gRPC، پیام‌ها باید در proto تعریف شوند.

مسیر فایل: ./proto/<module_name>/tx.proto

syntax = "proto3";
package <module_name>;

import "cosmos/base/v1beta1/coin.proto";
import "cosmos/msg/v1/msg.proto";

service Msg {
    rpc CreateItem(MsgCreateItem) returns (MsgCreateItemResponse);
    rpc UpdateItem(MsgUpdateItem) returns (MsgUpdateItemResponse);
}

message MsgCreateItem {
    string creator = 1;
    string name = 2;
    int64 price = 3;
}

message MsgCreateItemResponse {}

message MsgUpdateItem {
    string creator = 1;
    uint64 id = 2;
    string name = 3;
    int64 price = 4;
}

message MsgUpdateItemResponse {}

جمع‌بندی

در این بخش، نحوه طراحی پیام‌های سفارشی در Cosmos SDK را بررسی کردیم. مراحل اصلی شامل موارد زیر بود:

  • تعریف ساختار پیام (Msg) در Go
  • پیاده‌سازی متدهای موردنیاز برای تعامل با Cosmos SDK
  • ثبت پیام‌ها در Msg Service
  • افزودن پشتیبانی gRPC برای پیام‌ها

با این روش، می‌توان هرگونه پیام سفارشی برای تراکنش‌های بلاکچین را تعریف کرد و آن‌ها را در ماژول پیاده‌سازی نمود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ثبت و اعتبارسنجی پیام‌ها” subtitle=”توضیحات کامل”]در Cosmos SDK، پیام‌ها (Msg) برای ارسال داده‌ها و اجرای عملیات روی بلاکچین استفاده می‌شوند. پس از طراحی پیام‌های سفارشی، باید آن‌ها را در ماژول ثبت کرده و فرآیند اعتبارسنجی را پیاده‌سازی کنیم تا از صحت و امنیت داده‌های ارسالی اطمینان حاصل شود.


مراحل ثبت و اعتبارسنجی پیام‌ها

برای پیاده‌سازی کامل پیام‌ها، باید مراحل زیر را دنبال کنیم:

  1. ایجاد پیام‌های سفارشی (Msg)
  2. پیاده‌سازی رابط sdk.Msg برای پیام‌ها
  3. ثبت پیام‌ها در ماژول
  4. اعتبارسنجی پیام‌ها از طریق ValidateBasic
  5. اضافه کردن پیام‌ها به MsgServer برای پردازش درخواست‌ها
  6. ایجاد تست‌های واحد برای بررسی عملکرد صحیح پیام‌ها

۱. تعریف پیام‌های سفارشی

در ابتدا، پیام‌ها را در فایل msg.go در پوشه types ماژول تعریف می‌کنیم.

مسیر فایل: ./x/<module_name>/types/msg.go

package types

import (
    "fmt"

    sdk "github.com/cosmos/cosmos-sdk/types"
)

// پیام ایجاد یک آیتم جدید
type MsgCreateItem struct {
    Creator sdk.AccAddress `json:"creator" yaml:"creator"`
    Name    string         `json:"name" yaml:"name"`
    Price   int64          `json:"price" yaml:"price"`
}

// مقداردهی اولیه پیام
func NewMsgCreateItem(creator sdk.AccAddress, name string, price int64) *MsgCreateItem {
    return &MsgCreateItem{
        Creator: creator,
        Name:    name,
        Price:   price,
    }
}

// مسیر ماژول
func (msg MsgCreateItem) Route() string {
    return RouterKey
}

// نوع پیام
func (msg MsgCreateItem) Type() string {
    return "CreateItem"
}

// اعتبارسنجی اولیه پیام
func (msg MsgCreateItem) ValidateBasic() error {
    if msg.Creator.Empty() {
        return fmt.Errorf("آدرس فرستنده نمی‌تواند خالی باشد")
    }
    if len(msg.Name) == 0 {
        return fmt.Errorf("نام آیتم نمی‌تواند خالی باشد")
    }
    if msg.Price < 0 {
        return fmt.Errorf("قیمت باید مقدار غیرمنفی باشد")
    }
    return nil
}

// مشخص کردن امضاکنندگان پیام
func (msg MsgCreateItem) GetSigners() []sdk.AccAddress {
    return []sdk.AccAddress{msg.Creator}
}

۲. ثبت پیام‌ها در msg_server.go

مسیر فایل: ./x/<module_name>/keeper/msg_server.go

package keeper

import (
    "context"

    "github.com/cosmos/cosmos-sdk/types"
    "github.com/username/blockchain/x/<module_name>/types"
)

// تعریف سرور پیام‌ها
type msgServer struct {
    Keeper
}

// متد ایجاد آیتم جدید
func (k msgServer) CreateItem(ctx context.Context, msg *types.MsgCreateItem) (*types.MsgCreateItemResponse, error) {
    sdkCtx := types.UnwrapSDKContext(ctx)

    // اعتبارسنجی پیام
    if err := msg.ValidateBasic(); err != nil {
        return nil, err
    }

    // ذخیره اطلاعات در بلاکچین
    item := types.Item{
        Creator: msg.Creator.String(),
        Name:    msg.Name,
        Price:   msg.Price,
    }
    k.Keeper.SetItem(sdkCtx, item)

    return &types.MsgCreateItemResponse{}, nil
}

۳. رجیستر کردن پیام‌ها در interface.go

مسیر فایل: ./x/<module_name>/types/msgs_interface.go

package types

import (
    sdk "github.com/cosmos/cosmos-sdk/types"
)

// ثبت پیام‌ها در `sdk.Msg`
func RegisterMsgService(msgServer sdk.MsgServiceRouter) {
    msgServer.RegisterService(&MsgCreateItem{})
}

۴. اعتبارسنجی پیام‌ها در ValidateBasic

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

در پیام MsgCreateItem، متد ValidateBasic را پیاده‌سازی کردیم که شرایط زیر را بررسی می‌کند:

  • آدرس فرستنده معتبر باشد
  • نام آیتم خالی نباشد
  • قیمت مقدار غیرمنفی باشد

اگر یکی از این شرایط رعایت نشود، پیام پردازش نخواهد شد و یک خطا بازگردانده می‌شود.


۵. ثبت پیام‌ها در gRPC

برای پشتیبانی از gRPC، پیام‌ها را در proto ثبت می‌کنیم.

مسیر فایل: ./proto/<module_name>/tx.proto

syntax = "proto3";
package <module_name>;

import "cosmos/base/v1beta1/coin.proto";
import "cosmos/msg/v1/msg.proto";

service Msg {
    rpc CreateItem(MsgCreateItem) returns (MsgCreateItemResponse);
}

message MsgCreateItem {
    string creator = 1;
    string name = 2;
    int64 price = 3;
}

message MsgCreateItemResponse {}

۶. اجرای تست برای پیام‌ها

برای اطمینان از عملکرد صحیح پیام‌ها، تست‌های واحد در msg_server_test.go ایجاد می‌کنیم.

مسیر فایل: ./x/<module_name>/keeper/msg_server_test.go

package keeper_test

import (
    "testing"

    sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/stretchr/testify/require"
    "github.com/username/blockchain/x/<module_name>/types"
)

func TestMsgCreateItem_Validation(t *testing.T) {
    creator := sdk.AccAddress([]byte("creator"))

    // تست پیام معتبر
    validMsg := types.NewMsgCreateItem(creator, "TestItem", 100)
    require.NoError(t, validMsg.ValidateBasic())

    // تست خطای آدرس خالی
    invalidMsg1 := types.NewMsgCreateItem(sdk.AccAddress{}, "TestItem", 100)
    require.Error(t, invalidMsg1.ValidateBasic())

    // تست خطای نام خالی
    invalidMsg2 := types.NewMsgCreateItem(creator, "", 100)
    require.Error(t, invalidMsg2.ValidateBasic())

    // تست خطای قیمت منفی
    invalidMsg3 := types.NewMsgCreateItem(creator, "TestItem", -10)
    require.Error(t, invalidMsg3.ValidateBasic())
}

جمع‌بندی

در این بخش، فرآیند ثبت و اعتبارسنجی پیام‌ها را در Cosmos SDK بررسی کردیم. مراحل انجام‌شده شامل موارد زیر بود:

  • تعریف پیام‌های سفارشی (MsgCreateItem)
  • پیاده‌سازی متد ValidateBasic برای اعتبارسنجی پیام
  • ایجاد msg_server.go برای پردازش پیام‌ها
  • رجیستر کردن پیام‌ها در MsgServiceRouter
  • تعریف پیام‌ها در gRPC
  • اجرای تست‌های واحد برای اطمینان از صحت پیام‌ها

با انجام این مراحل، پیام‌های سفارشی با اعتبارسنجی دقیق در بلاکچین Cosmos SDK پیاده‌سازی شده و آماده پردازش تراکنش‌ها خواهند بود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ایجاد و ارسال رویدادها (Events) در بلاکچین” subtitle=”توضیحات کامل”]در Cosmos SDK، رویدادها (Events) مکانیزمی برای ثبت و انتشار اطلاعات مربوط به تراکنش‌ها هستند. این رویدادها می‌توانند توسط ماژول‌های بلاکچین تولید شده و در لاگ‌های بلاک قرار گیرند تا کلاینت‌ها و سرویس‌های خارجی بتوانند آن‌ها را مشاهده و پردازش کنند.


مفهوم رویدادها در Cosmos SDK

رویدادها برای موارد زیر استفاده می‌شوند:

  • اطلاع‌رسانی درباره تراکنش‌ها
  • ثبت تغییرات در وضعیت بلاکچین
  • دریافت اطلاعات خاص از ماژول‌های مختلف
  • ایجاد قابلیت شنود برای تعاملات زنجیره‌ای

هر رویداد شامل ویژگی‌های کلیدی زیر است:

  • نام رویداد: نامی که ماژول برای رویداد در نظر می‌گیرد.
  • ویژگی‌ها (Attributes): مجموعه‌ای از کلید-مقدارها که اطلاعات رویداد را مشخص می‌کنند.

مراحل ایجاد و ارسال رویدادها

  1. تعریف رویدادها و مشخص کردن داده‌های مورد نیاز
  2. ایجاد رویداد در ماژول و اضافه کردن آن به ctx.EventManager
  3. ثبت رویدادها در تراکنش‌ها
  4. ایجاد تست‌های واحد برای بررسی رویدادها

۱. تعریف رویدادها

رویدادها معمولاً در فایل events.go در پوشه types ماژول تعریف می‌شوند.

مسیر فایل: ./x/<module_name>/types/events.go

package types

import (
    sdk "github.com/cosmos/cosmos-sdk/types"
)

// نام ثابت برای رویدادها
const (
    EventTypeCreateItem = "create_item"

    AttributeKeyCreator = "creator"
    AttributeKeyName    = "name"
    AttributeKeyPrice   = "price"
)

// ایجاد یک رویداد جدید برای ایجاد آیتم
func NewEventCreateItem(creator sdk.AccAddress, name string, price int64) sdk.Event {
    return sdk.NewEvent(
        EventTypeCreateItem,
        sdk.NewAttribute(AttributeKeyCreator, creator.String()),
        sdk.NewAttribute(AttributeKeyName, name),
        sdk.NewAttribute(AttributeKeyPrice, fmt.Sprintf("%d", price)),
    )
}

۲. ایجاد و ارسال رویداد در msg_server.go

بعد از اینکه تراکنش پردازش شد، باید رویداد مربوط به آن تراکنش را ایجاد کرده و به مدیریت‌کننده رویدادها (EventManager) اضافه کنیم.

مسیر فایل: ./x/<module_name>/keeper/msg_server.go

package keeper

import (
    "context"

    sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/username/blockchain/x/<module_name>/types"
)

// متد ایجاد آیتم جدید
func (k msgServer) CreateItem(ctx context.Context, msg *types.MsgCreateItem) (*types.MsgCreateItemResponse, error) {
    sdkCtx := sdk.UnwrapSDKContext(ctx)

    // اعتبارسنجی پیام
    if err := msg.ValidateBasic(); err != nil {
        return nil, err
    }

    // ذخیره اطلاعات در بلاکچین
    item := types.Item{
        Creator: msg.Creator.String(),
        Name:    msg.Name,
        Price:   msg.Price,
    }
    k.Keeper.SetItem(sdkCtx, item)

    // ایجاد و ارسال رویداد
    event := types.NewEventCreateItem(msg.Creator, msg.Name, msg.Price)
    sdkCtx.EventManager().EmitEvent(event)

    return &types.MsgCreateItemResponse{}, nil
}

۳. بررسی رویداد در CLI

هنگامی که یک تراکنش ارسال می‌شود، اگر رویداد به درستی در بلاکچین ثبت شده باشد، می‌توان آن را در لاگ‌های بلاک مشاهده کرد.

برای مشاهده لاگ تراکنش‌ها و بررسی رویدادهای ثبت‌شده، از دستور زیر استفاده می‌کنیم:

gaiad query tx <TX_HASH> --output json | jq '.logs'

مثال خروجی:

{
  "events": [
    {
      "type": "create_item",
      "attributes": [
        {
          "key": "creator",
          "value": "cosmos1xyz..."
        },
        {
          "key": "name",
          "value": "Test Item"
        },
        {
          "key": "price",
          "value": "100"
        }
      ]
    }
  ]
}

۴. ایجاد تست برای رویدادها

برای بررسی اینکه آیا رویدادها به درستی ایجاد و ثبت می‌شوند، تست‌های زیر را در msg_server_test.go اضافه می‌کنیم.

مسیر فایل: ./x/<module_name>/keeper/msg_server_test.go

package keeper_test

import (
    "testing"

    sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/stretchr/testify/require"
    "github.com/username/blockchain/x/<module_name>/keeper"
    "github.com/username/blockchain/x/<module_name>/types"
)

func TestCreateItem_EmitEvent(t *testing.T) {
    ctx, k := keeper.CreateTestContextAndKeeper(t)
    msgServer := keeper.NewMsgServerImpl(k)

    creator := sdk.AccAddress([]byte("creator"))
    msg := types.NewMsgCreateItem(creator, "TestItem", 100)

    // اجرای تراکنش
    _, err := msgServer.CreateItem(ctx, msg)
    require.NoError(t, err)

    // بررسی رویدادها
    events := ctx.EventManager().Events()
    require.Len(t, events, 1)

    event := events[0]
    require.Equal(t, event.Type, types.EventTypeCreateItem)

    attributes := event.Attributes
    require.Equal(t, string(attributes[0].Key), "creator")
    require.Equal(t, string(attributes[0].Value), creator.String())
    require.Equal(t, string(attributes[1].Key), "name")
    require.Equal(t, string(attributes[1].Value), "TestItem")
    require.Equal(t, string(attributes[2].Key), "price")
    require.Equal(t, string(attributes[2].Value), "100")
}

جمع‌بندی

در این بخش، فرآیند ایجاد و ارسال رویدادها را در بلاکچین Cosmos SDK بررسی کردیم. مراحل انجام‌شده شامل موارد زیر بود:

  • تعریف رویدادها و ویژگی‌های آن‌ها در events.go
  • ایجاد و ارسال رویداد هنگام پردازش تراکنش‌ها
  • مشاهده لاگ رویدادها در CLI
  • نوشتن تست‌های واحد برای بررسی رویدادها

با انجام این مراحل، رویدادهای سفارشی در Cosmos SDK پیاده‌سازی شده و قابل پردازش در سیستم‌های خارجی مانند کاوشگرهای بلاکچین و سرویس‌های ناظر خواهند بود.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. مدیریت تراکنش‌ها و اجرای آنها در ماژول”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه پردازش تراکنش‌ها و ثبت تغییرات” subtitle=”توضیحات کامل”]در Cosmos SDK، تراکنش‌ها (Transactions) مهم‌ترین جزء تعامل با بلاکچین هستند. این تراکنش‌ها باعث تغییر در State (حالت) بلاکچین می‌شوند. فرآیند پردازش یک تراکنش شامل اعتبارسنجی، اجرای منطق ماژول و ثبت تغییرات در Store است.


مراحل پردازش یک تراکنش در Cosmos SDK

  1. دریافت و اعتبارسنجی اولیه تراکنش
  2. ارسال تراکنش به mempool و انتخاب برای پردازش
  3. اعتبارسنجی پیام‌های تراکنش در AnteHandler
  4. اجرای منطق کسب‌وکار در Handler
  5. ثبت تغییرات در Store و انتشار رویدادها
  6. ثبت تراکنش در بلاک جدید و تأیید نهایی

۱. دریافت و اعتبارسنجی اولیه تراکنش

هنگامی که یک کاربر تراکنشی را ارسال می‌کند، این تراکنش شامل اطلاعات زیر است:

  • پیام‌ها (Msgs): وظایفی که باید اجرا شوند (مثلاً انتقال توکن، ایجاد یک آیتم جدید، ثبت رأی و …)
  • امضای دیجیتال: برای تأیید صحت تراکنش
  • فی (Fee): کارمزدی که کاربر برای پردازش تراکنش پرداخت می‌کند

تراکنش ابتدا توسط Full Node دریافت شده و بررسی اولیه روی آن انجام می‌شود.


۲. ارسال تراکنش به Mempool و انتخاب برای پردازش

Mempool مکانی است که در آن تراکنش‌های تأییدنشده ذخیره می‌شوند تا زمانی که یک Validator آن‌ها را در یک بلاک جدید ثبت کند. تراکنش‌هایی که فی بیشتری پرداخت کنند، اولویت بالاتری برای پردازش دارند.


۳. اعتبارسنجی پیام‌های تراکنش در AnteHandler

قبل از اجرای تراکنش، AnteHandler مسئول بررسی موارد زیر است:

  • اعتبارسنجی امضای تراکنش
  • مطمئن شدن از پرداخت کارمزد تراکنش
  • بررسی محدودیت‌های گس (Gas Limit)

فایل مرتبط: ./app/ante.go

package app

import (
    "github.com/cosmos/cosmos-sdk/types/ante"
)

// AnteHandler برای اعتبارسنجی اولیه تراکنش‌ها
func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
    return sdk.ChainAnteDecorators(
        ante.NewSetUpContextDecorator(),
        ante.NewValidateBasicDecorator(),
        ante.NewConsumeGasForTxSizeDecorator(),
        ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper),
        ante.NewSigVerificationDecorator(options.AccountKeeper),
    )
}

۴. اجرای منطق کسب‌وکار در MsgServer

اگر تراکنش اعتبارسنجی را گذراند، پیام‌های آن به MsgServer مربوطه ارسال می‌شوند.

فایل مرتبط: ./x/<module_name>/keeper/msg_server.go

package keeper

import (
    "context"

    sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/username/blockchain/x/<module_name>/types"
)

// پردازش پیام ایجاد آیتم جدید
func (k msgServer) CreateItem(ctx context.Context, msg *types.MsgCreateItem) (*types.MsgCreateItemResponse, error) {
    sdkCtx := sdk.UnwrapSDKContext(ctx)

    // بررسی پیام ورودی
    if err := msg.ValidateBasic(); err != nil {
        return nil, err
    }

    // ایجاد و ذخیره آیتم جدید در Store
    item := types.Item{
        Creator: msg.Creator.String(),
        Name:    msg.Name,
        Price:   msg.Price,
    }
    k.Keeper.SetItem(sdkCtx, item)

    // ایجاد رویداد تراکنش
    sdkCtx.EventManager().EmitEvent(
        sdk.NewEvent(
            types.EventTypeCreateItem,
            sdk.NewAttribute(types.AttributeKeyCreator, msg.Creator.String()),
            sdk.NewAttribute(types.AttributeKeyName, msg.Name),
            sdk.NewAttribute(types.AttributeKeyPrice, fmt.Sprintf("%d", msg.Price)),
        ),
    )

    return &types.MsgCreateItemResponse{}, nil
}

۵. ثبت تغییرات در Store و انتشار رویدادها

Store در Cosmos SDK بر اساس Key-Value Storage کار می‌کند. داده‌ها در Store ذخیره می‌شوند و ماژول‌ها می‌توانند آن‌ها را خوانده یا تغییر دهند.

۵.۱. ذخیره‌سازی داده‌ها در Store با استفاده از Keeper

فایل مرتبط: ./x/<module_name>/keeper/item.go

package keeper

import (
    sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/username/blockchain/x/<module_name>/types"
)

// ذخیره‌سازی آیتم جدید در Store
func (k Keeper) SetItem(ctx sdk.Context, item types.Item) {
    store := ctx.KVStore(k.storeKey)
    key := []byte(types.ItemKeyPrefix + item.Name)
    value := k.cdc.MustMarshalBinaryBare(&item)
    store.Set(key, value)
}

// دریافت آیتم از Store
func (k Keeper) GetItem(ctx sdk.Context, name string) (types.Item, bool) {
    store := ctx.KVStore(k.storeKey)
    key := []byte(types.ItemKeyPrefix + name)
    value := store.Get(key)

    if value == nil {
        return types.Item{}, false
    }

    var item types.Item
    k.cdc.MustUnmarshalBinaryBare(value, &item)
    return item, true
}
۵.۲. انتشار رویدادها در بلاکچین

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

مثال رویداد در msg_server.go:

sdkCtx.EventManager().EmitEvent(
    sdk.NewEvent(
        types.EventTypeCreateItem,
        sdk.NewAttribute(types.AttributeKeyCreator, msg.Creator.String()),
        sdk.NewAttribute(types.AttributeKeyName, msg.Name),
        sdk.NewAttribute(types.AttributeKeyPrice, fmt.Sprintf("%d", msg.Price)),
    ),
)

۶. ثبت تراکنش در بلاک جدید و تأیید نهایی

وقتی تراکنش در یک بلاک جدید ثبت شد، به عنوان یک تراکنش تأیید‌شده در نظر گرفته می‌شود.

می‌توان تراکنش‌های تأیید‌شده را با دستور زیر مشاهده کرد:

gaiad query tx <TX_HASH> --output json

جمع‌بندی

در این بخش، فرآیند پردازش تراکنش‌ها و ثبت تغییرات را در Cosmos SDK بررسی کردیم. این مراحل شامل:

  • دریافت تراکنش و ارسال به mempool
  • اعتبارسنجی اولیه با AnteHandler
  • اجرای پیام‌ها در MsgServer
  • ذخیره داده‌ها در Store با Keeper
  • ایجاد و ارسال رویدادها
  • ثبت تراکنش در بلاک جدید و مشاهده آن

این فرایند تضمین می‌کند که تراکنش‌ها به درستی پردازش شده و تغییرات مورد نظر در وضعیت بلاکچین اعمال شوند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیاده‌سازی روش‌های اعتبارسنجی تراکنش‌ها” subtitle=”توضیحات کامل”]در Cosmos SDK، تراکنش‌ها باید قبل از اجرا، از نظر اعتبارسنجی امضا، مقدار کارمزد، محدودیت گس (Gas Limit) و سایر فاکتورهای امنیتی بررسی شوند. این وظیفه بر عهده AnteHandler است که به عنوان یک فیلتر اولیه برای پردازش تراکنش‌ها عمل می‌کند.


مراحل اعتبارسنجی تراکنش‌ها

  1. بررسی امضای دیجیتال و فرستنده تراکنش
  2. بررسی مقدار گس و کارمزد تراکنش
  3. اعتبارسنجی داده‌های درون تراکنش
  4. بررسی موجودی حساب برای پرداخت هزینه‌ها
  5. اعتبارسنجی محدودیت‌های بلاکچین

۱. بررسی امضای دیجیتال و فرستنده تراکنش

هر تراکنش باید یک امضای معتبر داشته باشد تا هویت فرستنده تأیید شود. این بررسی در AnteHandler انجام می‌شود.

مسیر فایل: ./app/ante.go

کد پیاده‌سازی:

package app

import (
    "github.com/cosmos/cosmos-sdk/types/ante"
    "github.com/cosmos/cosmos-sdk/types"
)

func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
    return sdk.ChainAnteDecorators(
        ante.NewSetUpContextDecorator(),
        ante.NewValidateBasicDecorator(),
        ante.NewSigVerificationDecorator(options.AccountKeeper),
    )
}

دستور کامندی برای بررسی امضا:

gaiad query tx <TX_HASH> --output json

۲. بررسی مقدار گس و کارمزد تراکنش

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

مسیر فایل: ./app/ante.go

کد مربوطه:

func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
    return sdk.ChainAnteDecorators(
        ante.NewSetUpContextDecorator(),
        ante.NewValidateBasicDecorator(),
        ante.NewConsumeGasForTxSizeDecorator(),
    )
}

دستور کامندی برای بررسی گس تراکنش:

gaiad tx estimate-gas --from <wallet_address> --chain-id <chain_id>

۳. اعتبارسنجی داده‌های درون تراکنش

تمام پیام‌های داخل یک تراکنش باید مقداردهی اولیه درستی داشته باشند. این کار در تابع ValidateBasic() انجام می‌شود.

مسیر فایل: ./x/<module_name>/types/msgs.go

کد مربوطه:

func (msg *MsgCreateItem) ValidateBasic() error {
    if len(msg.Name) == 0 {
        return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "نام آیتم نمی‌تواند خالی باشد")
    }
    return nil
}

۴. بررسی موجودی حساب برای پرداخت هزینه‌ها

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

مسیر فایل: ./app/ante.go

کد مربوطه:

func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
    return sdk.ChainAnteDecorators(
        ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper),
    )
}

دستور کامندی برای بررسی موجودی حساب:

gaiad query bank balances <wallet_address>

۵. اعتبارسنجی محدودیت‌های بلاکچین

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

مسیر فایل: ./x/<module_name>/keeper/limits.go

کد مربوطه:

func (k Keeper) CheckBlockLimit(ctx sdk.Context) error {
    if ctx.BlockGasMeter().GasConsumed() > MaxBlockGasLimit {
        return sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "محدودیت گس بلاک بیشتر از حد مجاز است")
    }
    return nil
}

جمع‌بندی

در این بخش، روش‌های اعتبارسنجی تراکنش‌ها را بررسی کردیم. فرآیند تأیید شامل بررسی امضا، کارمزد، محدودیت‌های بلاک، داده‌های تراکنش و موجودی حساب است. این مراحل تضمین می‌کنند که تراکنش‌ها امن و معتبر باشند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اجرای تراکنش‌های سفارشی و بررسی خروجی آن‌ها” subtitle=”توضیحات کامل”]در Cosmos SDK، پس از طراحی و پیاده‌سازی پیام‌های سفارشی (Msg) و روش‌های اعتبارسنجی، باید نحوه اجرای تراکنش‌های سفارشی و بررسی خروجی آن‌ها را در نظر بگیریم. این فرآیند شامل مراحل زیر است:

  • ایجاد تراکنش حاوی پیام سفارشی
  • امضای تراکنش و ارسال آن به بلاکچین
  • بررسی وضعیت اجرای تراکنش و مشاهده خروجی

ایجاد تراکنش حاوی پیام سفارشی

در Cosmos SDK، یک تراکنش شامل یک یا چند پیام (Msg) است که به ترتیب توسط بلاکچین پردازش می‌شوند. برای ایجاد یک تراکنش سفارشی، ابتدا باید یک Msg سفارشی بسازیم و سپس تراکنشی شامل آن را ایجاد کنیم.

در مسیر x/custommodule/types/tx.go، یک پیام سفارشی به‌صورت زیر تعریف شده است:

package types

import (
    "github.com/cosmos/cosmos-sdk/types"
)

// MsgCustomTransaction پیام سفارشی
type MsgCustomTransaction struct {
    Creator types.AccAddress `json:"creator" yaml:"creator"`
    Value   string           `json:"value" yaml:"value"`
}

// NewMsgCustomTransaction مقداردهی اولیه پیام
func NewMsgCustomTransaction(creator types.AccAddress, value string) *MsgCustomTransaction {
    return &MsgCustomTransaction{
        Creator: creator,
        Value:   value,
    }
}

// Route نام مسیر ماژول
func (msg MsgCustomTransaction) Route() string { return RouterKey }

// Type نوع پیام
func (msg MsgCustomTransaction) Type() string { return "CustomTransaction" }

// ValidateBasic اعتبارسنجی اولیه پیام
func (msg MsgCustomTransaction) ValidateBasic() error {
    if msg.Creator.Empty() {
        return types.ErrInvalidAddress
    }
    if len(msg.Value) == 0 {
        return errors.New("value cannot be empty")
    }
    return nil
}

ثبت و امضای تراکنش

برای اجرای تراکنش، ابتدا یک کلید کاربری می‌سازیم (اگر قبلاً وجود ندارد):

gaiad keys add mywallet

سپس، تراکنش حاوی پیام سفارشی را ایجاد و امضا می‌کنیم:

gaiad tx custommodule CustomTransaction "Hello, Cosmos" --from mywallet --chain-id test-chain

ارسال تراکنش و بررسی وضعیت

پس از امضای تراکنش، آن را به بلاکچین ارسال کرده و خروجی را بررسی می‌کنیم:

gaiad tx broadcast signed_tx.json

برای بررسی وضعیت تراکنش و تأیید اجرا، از دستور زیر استفاده می‌کنیم:

gaiad query tx <TX_HASH>

جمع‌بندی

در این بخش، نحوه ایجاد، امضا، ارسال و بررسی خروجی تراکنش‌های سفارشی را در Cosmos SDK بررسی کردیم. در اجرای واقعی، این تراکنش‌ها می‌توانند منجر به تغییر وضعیت شبکه شده و در زنجیره ثبت شوند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. ایجاد و مدیریت Queryها برای خواندن داده‌ها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیاده‌سازی Endpoints برای خواندن اطلاعات از بلاکچین” subtitle=”توضیحات کامل”]در Cosmos SDK، برای خواندن داده‌ها از بلاکچین، باید Endpoints API مناسبی پیاده‌سازی کنیم. این APIها معمولاً برای دسترسی به داده‌های ذخیره‌شده در Key-Value Store از طریق gRPC و REST استفاده می‌شوند. در این بخش، نحوه پیاده‌سازی این Endpoints را بررسی خواهیم کرد.

تعریف یک gRPC Query برای خواندن داده‌ها

برای پیاده‌سازی یک gRPC Query Endpoint در Cosmos SDK، ابتدا باید یک Service در فایل .proto ماژول تعریف کنیم. در مسیر proto/custommodule/query.proto، یک متد برای دریافت مقدار یک داده خاص اضافه می‌کنیم:

syntax = "proto3";
package custommodule;

import "gogoproto/gogo.proto";
import "cosmos/base/query/v1beta1/pagination.proto";

option go_package = "github.com/username/custommodule/x/custommodule/types";

// تعریف سرویس Query برای خواندن داده‌ها
service Query {
  rpc GetCustomValue(QueryCustomRequest) returns (QueryCustomResponse) {
    option (google.api.http) = { get: "/custommodule/value/{key}" };
  }
}

// درخواست دریافت مقدار یک کلید
message QueryCustomRequest {
  string key = 1;
}

// پاسخ شامل مقدار کلید در بلاکچین
message QueryCustomResponse {
  string value = 1;
}

پیاده‌سازی gRPC Query در Keeper

بعد از تعریف gRPC Service در فایل .proto، باید منطق پردازش آن را در Keeper پیاده‌سازی کنیم. در مسیر x/custommodule/keeper/query.go، متد موردنظر را اضافه می‌کنیم:

package keeper

import (
    "context"

    "github.com/cosmos/cosmos-sdk/types"
    "github.com/username/custommodule/x/custommodule/types"
)

// GetCustomValue خواندن مقدار یک کلید خاص از Store
func (k Keeper) GetCustomValue(ctx context.Context, req *types.QueryCustomRequest) (*types.QueryCustomResponse, error) {
    if req == nil {
        return nil, types.ErrInvalidRequest
    }

    // دسترسی به Store
    sdkCtx := types.UnwrapSDKContext(ctx)
    store := sdkCtx.KVStore(k.storeKey)
    
    // خواندن مقدار کلید
    value := store.Get([]byte(req.Key))
    if value == nil {
        return nil, types.ErrKeyNotFound
    }

    return &types.QueryCustomResponse{Value: string(value)}, nil
}

اضافه کردن gRPC Query به ماژول

برای ثبت این gRPC Query در ماژول، باید در x/custommodule/keeper/grpc_query.go، متد RegisterQueryServer را اضافه کنیم:

package keeper

import (
    "github.com/username/custommodule/x/custommodule/types"
    "google.golang.org/grpc"
)

// RegisterQueryServer ثبت سرویس gRPC در بلاکچین
func (k Keeper) RegisterQueryServer(server grpc.Server) {
    types.RegisterQueryServer(server, k)
}

ایجاد Endpoint REST برای خواندن داده‌ها

علاوه بر gRPC، می‌توان یک API RESTful برای دسترسی به این داده‌ها پیاده‌سازی کرد. در مسیر x/custommodule/client/rest/query.go، یک Handler برای پردازش درخواست‌های REST اضافه می‌کنیم:

package rest

import (
    "net/http"

    "github.com/cosmos/cosmos-sdk/client"
    "github.com/cosmos/cosmos-sdk/types/rest"
    "github.com/username/custommodule/x/custommodule/types"
)

// QueryCustomValueHandler پردازش درخواست خواندن مقدار کلید
func QueryCustomValueHandler(clientCtx client.Context) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        key := r.URL.Query().Get("key")
        if key == "" {
            rest.WriteErrorResponse(w, http.StatusBadRequest, "key parameter is required")
            return
        }

        req := &types.QueryCustomRequest{Key: key}
        res, err := clientCtx.QueryWithData("custommodule/value", req)
        if err != nil {
            rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
            return
        }

        rest.PostProcessResponseBare(w, clientCtx, res)
    }
}

ثبت مسیر REST در ماژول

در مسیر x/custommodule/client/rest/rest.go، باید این مسیر را به Router اضافه کنیم:

package rest

import (
    "github.com/cosmos/cosmos-sdk/client"
    "github.com/gorilla/mux"
)

// RegisterRoutes ثبت مسیرهای REST ماژول
func RegisterRoutes(clientCtx client.Context, r *mux.Router) {
    r.HandleFunc("/custommodule/value", QueryCustomValueHandler(clientCtx)).Methods("GET")
}

اجرای ماژول و تست Queryها

اکنون ماژول را کامپایل و اجرا می‌کنیم:

make install
gaiad start

برای خواندن مقدار یک کلید خاص از بلاکچین با استفاده از gRPC، از دستور زیر استفاده می‌کنیم:

grpcurl -plaintext -d '{"key": "mydata"}' localhost:9090 custommodule.Query/GetCustomValue

برای درخواست داده از طریق REST:

curl http://localhost:1317/custommodule/value?key=mydata

جمع‌بندی

در این بخش، نحوه پیاده‌سازی Endpoints برای خواندن اطلاعات از بلاکچین را بررسی کردیم. این شامل موارد زیر بود:

  • ایجاد gRPC Query در فایل proto
  • پیاده‌سازی گره gRPC در Keeper
  • ثبت gRPC در ماژول
  • ایجاد یک API RESTful برای دسترسی به داده‌ها
  • اجرای ماژول و تست خروجی

این روش‌ها به کاربران و دیگر ماژول‌ها امکان می‌دهد که داده‌های موردنیاز خود را به‌صورت امن و بهینه از بلاکچین دریافت کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف Queryها برای دریافت اطلاعات از Store” subtitle=”توضیحات کامل”]در سیستم‌های پایگاه داده (مانند SQL و NoSQL) برای دریافت اطلاعات از Store از دستورات Query استفاده می‌شود. Queryها به طور کلی درخواست‌هایی هستند که برای بازیابی داده‌ها از پایگاه داده ارسال می‌شوند. در این بخش، به تعریف و نحوه استفاده از Queryها در محیط‌های مختلف پرداخته خواهد شد و برای هر بخش به طور عملی دستوراتی برای تنظیم و استفاده از آن‌ها ارائه خواهد شد.

انواع Queryها برای دریافت اطلاعات از Store

برای دریافت اطلاعات از Store، معمولاً از انواع مختلف Queryها استفاده می‌شود:

  1. SELECT Query: در پایگاه‌های داده رابطه‌ای مانند MySQL یا PostgreSQL برای انتخاب و بازیابی داده‌ها از جداول مختلف استفاده می‌شود.
  2. Aggregation Query: برای انجام محاسبات و تجزیه و تحلیل‌های پیچیده بر روی داده‌ها.
  3. NoSQL Query: در پایگاه‌های داده غیررابطه‌ای (مانند MongoDB) برای دریافت اطلاعات استفاده می‌شود.
  4. Filtering Query: برای محدود کردن نتایج بر اساس شرایط خاص.
  5. Join Query: برای ترکیب داده‌ها از چند جدول مختلف.

مثال‌های عملی برای هر نوع Query

1. SELECT Query (MySQL)

در MySQL، برای دریافت اطلاعات از یک جدول مشخص، از دستور SELECT استفاده می‌شود. این دستور به شما امکان می‌دهد تا داده‌های مورد نیاز را از جدول‌های مختلف بر اساس شرایط دلخواه فیلتر کنید.

دستور MySQL برای دریافت اطلاعات:

SELECT * FROM customers WHERE age > 25;

این دستور تمام رکوردهای جدول customers را که سن آن‌ها بیشتر از ۲۵ است، انتخاب می‌کند.

مسیر فایل برای ویرایش یا قرار دادن این دستور: این دستور معمولاً در فایل‌های SQL یا در ابزارهای مدیریت پایگاه داده مانند phpMyAdmin یا MySQL Workbench وارد می‌شود. می‌توانید این کد را در فایل‌های .sql قرار دهید.

2. Aggregation Query (PostgreSQL)

در PostgreSQL، برای تجزیه و تحلیل داده‌ها و انجام محاسبات بر روی آن‌ها، می‌توان از توابع تجمیعی مانند COUNT(), SUM(), AVG() و غیره استفاده کرد.

دستور PostgreSQL برای محاسبه مجموع فروش:

SELECT SUM(sales_amount) FROM sales WHERE sale_date > '2025-01-01';

این دستور مجموع فروش‌هایی که پس از تاریخ اول ژانویه ۲۰۲۵ ثبت شده‌اند، را محاسبه می‌کند.

مسیر فایل برای ویرایش یا قرار دادن این دستور: این دستور نیز می‌تواند در فایل‌های .sql ذخیره شده و در ابزارهایی مانند pgAdmin یا psql استفاده شود.

3. NoSQL Query (MongoDB)

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

دستور MongoDB برای دریافت کاربران بالای ۳۰ سال:

db.users.find({ age: { $gt: 30 } });

این دستور تمام مستندات از مجموعه users را که سن آن‌ها بیشتر از ۳۰ است، بازیابی می‌کند.

مسیر فایل برای ویرایش یا قرار دادن این دستور: این دستور می‌تواند در فایل‌های جاوا اسکریپت برای MongoDB قرار بگیرد و در محیط‌های مختلف توسعه یا ابزار MongoDB اجرا شود.

4. Filtering Query (MySQL)

در MySQL، برای فیلتر کردن نتایج می‌توان از دستورات WHERE و عملگرهای مختلف مانند =, >, <, IN استفاده کرد.

دستور MySQL برای فیلتر کردن مشتریانی که در شهر خاصی زندگی می‌کنند:

SELECT name, city FROM customers WHERE city = 'Tehran';

این دستور تنها مشتریانی را که در شهر تهران زندگی می‌کنند نمایش می‌دهد.

مسیر فایل برای ویرایش یا قرار دادن این دستور: این دستور را می‌توان در فایل‌های .sql یا ابزارهای مدیریت پایگاه داده قرار داد.

5. Join Query (MySQL)

در MySQL، برای ترکیب داده‌ها از چند جدول مختلف از دستور JOIN استفاده می‌شود. این دستور می‌تواند داده‌ها را از چندین جدول بر اساس یک کلید مشترک ترکیب کند.

دستور MySQL برای اتصال دو جدول:

SELECT customers.name, orders.order_date
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id;

این دستور اطلاعات مشتریان و تاریخ سفارشات آن‌ها را از دو جدول customers و orders به هم متصل می‌کند.

مسیر فایل برای ویرایش یا قرار دادن این دستور: این دستور می‌تواند در فایل‌های .sql یا در ابزارهای مدیریتی مانند phpMyAdmin قرار گیرد.

پیکربندی‌ها و تنظیمات

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

1. پیکربندی اتصال به MySQL در PHP

برای اتصال به پایگاه داده MySQL از PHP، می‌توان از کد زیر استفاده کرد:

<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "store";

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}
?>

مسیر فایل برای ویرایش یا قرار دادن این دستور: این کد معمولاً در فایل‌هایی مانند config.php قرار می‌گیرد.

جمع‌بندی

در این بخش، انواع مختلف Queryها برای دریافت اطلاعات از Store معرفی شد. از دستورات SELECT, Aggregation, NoSQL Queries, Filtering, و Join برای استخراج داده‌ها و تجزیه و تحلیل آن‌ها استفاده می‌شود. هر کدام از این دستورها می‌توانند در پایگاه‌های داده مختلف مورد استفاده قرار گیرند و تنظیمات و پیکربندی‌ها می‌توانند در فایل‌های مربوطه ذخیره شوند.

تمامی دستورات و پیکربندی‌های این بخش به صورت عملی و همراه با مسیر فایل‌ها و دستوراتی که باید استفاده شوند، ارائه شدند تا شما بتوانید در محیط‌های مختلف از آن‌ها بهره‌برداری کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعامل با gRPC و REST API در Cosmos SDK” subtitle=”توضیحات کامل”]Cosmos SDK یکی از چارچوب‌های پیشرفته برای ساخت بلاکچین‌های مستقل و مقیاس‌پذیر است. این SDK از gRPC و REST API به‌عنوان دو روش اصلی برای تعامل با شبکه‌های مبتنی بر Cosmos استفاده می‌کند. در این بخش، به تفصیل نحوه تعامل با gRPC و REST API در Cosmos SDK بررسی خواهد شد.

۱. gRPC در Cosmos SDK

gRPC یک فریم‌ورک RPC (Remote Procedure Call) است که توسط Google طراحی شده و بر پایه پروتکل‌های HTTP/2 ساخته شده است. در Cosmos SDK، gRPC برای ارتباط میان نودها و همچنین میان کلاینت‌ها و نودهای شبکه استفاده می‌شود. این پروتکل به‌خوبی از انتقال داده‌های سریع و مقیاس‌پذیر پشتیبانی می‌کند و در تعاملات مبتنی بر Cosmos کاربرد زیادی دارد.

۱.۱. راه‌اندازی gRPC در Cosmos SDK

برای استفاده از gRPC در Cosmos SDK، ابتدا باید سرویس gRPC را در نود Cosmos خود فعال کنید. برای این کار نیاز به پیکربندی برخی از فایل‌ها دارید.

مثال پیکربندی gRPC در فایل app.go:

// gRPC Server Initialization
grpcServer := grpc.NewServer()

// Register your services here (example)
yourmodule.RegisterQueryServer(grpcServer, yourModuleHandler)

// Create listener for the gRPC server
lis, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", grpcPort))
if err != nil {
    panic("failed to listen: " + err.Error())
}

// Start the gRPC server
go func() {
    if err := grpcServer.Serve(lis); err != nil {
        panic("failed to serve: " + err.Error())
    }
}()

مسیر فایل برای ویرایش یا قرار دادن این دستور:
این کد باید در فایل app.go یا هر فایل اصلی که مربوط به راه‌اندازی سرویس‌ها و نود است، قرار گیرد.

۱.۲. استفاده از gRPC برای ارسال درخواست‌ها

برای ارسال درخواست به gRPC سرویس‌ها از کلاینت gRPC استفاده می‌شود. به‌عنوان مثال، اگر بخواهید از gRPC برای ارسال درخواست به یک بلاکچین Cosmos استفاده کنید، می‌توانید از کد زیر استفاده کنید:

// Client connection to gRPC server
conn, err := grpc.Dial(fmt.Sprintf("%s:%d", grpcHost, grpcPort), grpc.WithInsecure())
if err != nil {
    log.Fatalf("did not connect: %v", err)
}
defer conn.Close()

client := yourmodule.NewQueryClient(conn)
response, err := client.YourQuery(context.Background(), &yourmodule.YourQueryRequest{})
if err != nil {
    log.Fatalf("Error calling gRPC query: %v", err)
}
fmt.Println(response)

مسیر فایل برای ویرایش یا قرار دادن این دستور:
این کد می‌تواند در فایل‌های اصلی پروژه یا در فایل‌هایی که مسئولیت تعامل با gRPC را دارند، قرار گیرد.

۲. REST API در Cosmos SDK

REST API در Cosmos SDK برای ارائه ارتباطات مبتنی بر HTTP/1.1 و به‌عنوان رابط کاربری برای تعاملات غیر همزمان استفاده می‌شود. در Cosmos SDK، REST API برای ارسال درخواست‌ها به نودها و دریافت پاسخ‌ها در قالب JSON بسیار مفید است. این API بیشتر برای تعاملات میان سرویس‌ها یا برای دسترسی به داده‌ها از طریق HTTP استفاده می‌شود.

۲.۱. راه‌اندازی REST API در Cosmos SDK

برای فعال‌سازی REST API، ابتدا باید یک سرور REST را در نود خود راه‌اندازی کنید.

مثال پیکربندی REST API در فایل app.go:

// REST Server Initialization
restServer := rest.NewServer()

// Register your REST handlers here (example)
yourmodule.RegisterHandlers(restServer, yourModuleHandler)

// Start the REST server
go func() {
    if err := restServer.Start(fmt.Sprintf("0.0.0.0:%d", restPort)); err != nil {
        panic("failed to start REST server: " + err.Error())
    }
}()

مسیر فایل برای ویرایش یا قرار دادن این دستور:
این کد باید در فایل app.go قرار گیرد تا سرویس REST به‌درستی راه‌اندازی شود.

۲.۲. ارسال درخواست به REST API

برای ارسال درخواست به REST API در Cosmos SDK، معمولاً از ابزارهایی مانند cURL یا کتابخانه‌های زبان‌های مختلف (مانند Python یا JavaScript) استفاده می‌شود. در اینجا یک مثال از ارسال درخواست به REST API را مشاهده می‌کنید:

curl -X GET "http://localhost:1317/yourmodule/endpoint" -H "accept: application/json"

در این مثال، درخواست GET به endpoint مشخص شده در REST API ارسال می‌شود.

مسیر فایل برای ویرایش یا قرار دادن این دستور:
این دستور معمولاً در خط فرمان برای برقراری ارتباط با نود REST API Cosmos استفاده می‌شود.

۳. مقایسه gRPC و REST API در Cosmos SDK

ویژگی gRPC REST API
پروتکل HTTP/2 HTTP/1.1
سرعت سریع‌تر و بهینه‌تر برای انتقال داده‌ها ممکن است کندتر از gRPC باشد
پشتیبانی از استریمینگ پشتیبانی از استریمینگ دوطرفه معمولاً استریمینگ پشتیبانی نمی‌شود
پشتیبانی از JSON ندارد (ولی می‌تواند به protobuf تبدیل شود) استفاده از JSON
کاربرد برای تعاملات همزمان و مقیاس‌پذیر برای تعاملات ساده و درخواست‌های غیرهمزمان
سهولت استفاده نیاز به تنظیمات بیشتر ساده‌تر و متداول‌تر در بسیاری از اپلیکیشن‌ها

جمع‌بندی

در این بخش، نحوه تعامل با gRPC و REST API در Cosmos SDK بررسی شد. gRPC برای تعاملات سریع و مقیاس‌پذیر استفاده می‌شود و برای مواردی که نیاز به عملکرد بالا و استریمینگ دارند، بسیار مناسب است. از سوی دیگر، REST API برای درخواست‌های ساده و دسترسی به داده‌ها از طریق HTTP و JSON به‌طور گسترده استفاده می‌شود.

تمامی کدها و پیکربندی‌های مربوط به راه‌اندازی و استفاده از هر دو پروتکل در Cosmos SDK با جزئیات ارائه شد تا شما بتوانید از آن‌ها در پروژه‌های خود استفاده کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. اتصال ماژول به IBC (Inter-Blockchain Communication)”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی پروتکل IBC و نحوه ارتباط بین بلاکچین‌ها” subtitle=”توضیحات کامل”]پروتکل IBC (Inter-Blockchain Communication) یک پروتکل ارتباطی است که به بلاکچین‌های مختلف این امکان را می‌دهد تا به‌صورت امن و قابل اعتماد با یکدیگر ارتباط برقرار کنند. این پروتکل به‌ویژه در اکوسیستم Cosmos طراحی شده است تا بلاکچین‌های مختلف بتوانند به‌طور مستقل و همزمان به‌یکدیگر متصل شده و داده‌ها و دارایی‌ها را بین خود منتقل کنند.

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

۱. مفهوم پروتکل IBC

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

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

۲. نحوه عملکرد پروتکل IBC

پروتکل IBC از سه بخش اصلی تشکیل شده است:

  1. Channels (کانال‌ها): هر ارتباط بین دو بلاکچین از طریق کانال‌ها انجام می‌شود. کانال‌ها دو بلاکچین را از طریق یک کانال ارتباطی متصل می‌کنند.
  2. Clients (کلاینت‌ها): در هر بلاکچین، یک کلاینت IBC به‌طور دائم وضعیت بلاکچین را رصد می‌کند و به‌طور مستمر وضعیت بلاکچین دیگر را از طریق کانال‌ها دریافت می‌کند.
  3. Connections (اتصالات): اتصالات، مسیرهای ارتباطی امن میان دو بلاکچین را ایجاد می‌کنند و از انسجام و صحت داده‌ها در هر بلاکچین اطمینان حاصل می‌کنند.

این سه بخش به‌طور مشترک این امکان را فراهم می‌کنند که بلاکچین‌ها به‌صورت امن و به‌صورت real-time (در زمان واقعی) داده‌ها و دارایی‌ها را مبادله کنند.

۳. فرآیند ارتباط بین بلاکچین‌ها با استفاده از IBC

در این بخش، نحوه ارتباط بلاکچین‌ها از طریق IBC و مراحل مختلفی که برای انتقال داده یا دارایی لازم است، توضیح داده می‌شود.

۳.۱. اتصال دو بلاکچین از طریق IBC

برای ایجاد ارتباط بین دو بلاکچین از IBC، ابتدا باید یک اتصال (connection) بین آن‌ها برقرار شود. این اتصال از طریق کلاینت‌ها و کانال‌ها برقرار می‌شود.

  1. ایجاد اتصال (Connection Establishment):
    • بلاکچین‌ها یک کلاینت IBC بر روی بلاکچین خود ایجاد می‌کنند که وضعیت بلاکچین را رصد کرده و اطلاعات آن را به بلاکچین دیگر ارسال می‌کند.
    • سپس یک کانال ارتباطی از طریق اتصال ایجاد می‌شود تا اطلاعات میان دو بلاکچین ارسال شود.
  2. برقراری کانال ارتباطی (Channel Setup):
    • پس از برقراری اتصال، کانال‌ها راهی برای ارسال اطلاعات و داده‌ها میان بلاکچین‌ها فراهم می‌کنند.
    • این کانال‌ها می‌توانند درخواست‌ها و پاسخ‌ها را به‌صورت secure و قابل اعتماد بین بلاکچین‌ها منتقل کنند.
۳.۲. ارسال تراکنش‌ها و دارایی‌ها از یک بلاکچین به بلاکچین دیگر
  1. ارسال تراکنش‌ها:
    • پس از برقراری اتصال و کانال، کاربران می‌توانند تراکنش‌هایی مانند انتقال دارایی، قراردادهای هوشمند یا داده‌ها را از یک بلاکچین به بلاکچین دیگر ارسال کنند.
    • این تراکنش‌ها توسط کلاینت‌های IBC که در هر بلاکچین فعال هستند، تایید و به بلاکچین مقصد ارسال می‌شوند.
  2. گواهی‌نامه‌ها (Proofs):
    • گواهی‌نامه‌ها برای اثبات اینکه یک تراکنش به‌طور صحیح در بلاکچین مقصد ثبت شده است، استفاده می‌شوند. این گواهی‌نامه‌ها می‌توانند به‌صورت اعتبارسنجی داده‌ها در بلاکچین مقصد عمل کنند.
۳.۳. فرآیند ثبت و تایید تراکنش‌ها
  1. فرایند ثبت تراکنش‌ها:
    • هنگامی که تراکنشی از بلاکچین A به بلاکچین B ارسال می‌شود، بلاکچین A تراکنش را تایید کرده و آن را به بلاکچین B می‌فرستد.
    • پس از آن، بلاکچین B این تراکنش را ثبت و تایید می‌کند.
  2. تایید صحت داده‌ها:
    • پس از ثبت تراکنش، بلاکچین B باید صحت و اعتبار تراکنش را از طریق گواهی‌نامه‌ها و با استفاده از کلاینت‌های IBC تایید کند.

۴. کاربردهای پروتکل IBC

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

  1. انتقال دارایی‌ها (Token Transfers): یکی از مهم‌ترین کاربردهای IBC، انتقال توکن‌ها میان بلاکچین‌ها است. این امکان به کاربران این اجازه را می‌دهد تا دارایی‌ها را از یک بلاکچین به بلاکچین دیگر منتقل کنند.
  2. ارتباط میان بلاکچین‌های مختلف: IBC این امکان را می‌دهد که بلاکچین‌های مختلف که ممکن است اهداف متفاوتی داشته باشند، بتوانند به‌طور مستقیم با یکدیگر ارتباط برقرار کنند.
  3. مقیاس‌پذیری بلاکچین‌ها: با استفاده از IBC، بلاکچین‌ها می‌توانند به‌صورت موازی کار کنند و بار تراکنش‌ها را بین چندین بلاکچین توزیع کنند، که به مقیاس‌پذیری بیشتر سیستم کمک می‌کند.

جمع‌بندی

پروتکل IBC در Cosmos SDK به‌طور مؤثر ارتباط بین بلاکچین‌های مختلف را فراهم می‌کند. این پروتکل به بلاکچین‌ها این امکان را می‌دهد که به‌طور امن و به‌صورت real-time داده‌ها و دارایی‌ها را به یکدیگر منتقل کنند. IBC با استفاده از کانال‌ها، کلاینت‌ها و اتصالات به ایجاد یک شبکه مقیاس‌پذیر و ارتباط‌پذیر بین بلاکچین‌ها کمک می‌کند. این امر به بلاکچین‌ها اجازه می‌دهد تا به‌صورت مستقل عمل کرده و در عین حال به هم متصل باشند.

پروتکل IBC به‌ویژه در مقیاس‌پذیری و انتقال دارایی‌ها در اکوسیستم Cosmos اهمیت زیادی دارد و می‌تواند به‌عنوان یکی از فناوری‌های اصلی در دنیای بلاکچین‌ها در آینده عمل کند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیاده‌سازی قابلیت ارسال و دریافت پیام‌های IBC” subtitle=”توضیحات کامل”]برای پیاده‌سازی قابلیت ارسال و دریافت پیام‌ها در پروتکل IBC، باید مراحل مختلفی را در بلاکچین مقصد و بلاکچین ارسال‌کننده طی کنیم. در این بخش، تمامی مراحل به‌طور جامع و کاربردی برای استفاده در پروژه‌های عملی و واقعی شرح داده خواهد شد.

۱. مقدمه‌ای بر ارسال و دریافت پیام‌ها با IBC

پروتکل IBC به بلاکچین‌ها این امکان را می‌دهد که پیام‌ها را به‌طور امن و قابل اعتماد از یک بلاکچین به بلاکچین دیگر ارسال و دریافت کنند. این پیام‌ها می‌توانند شامل داده‌ها یا درخواست‌های مختلفی باشند که به‌طور معمول برای اجرای عملیات‌های بین زنجیره‌ای (cross-chain) نیاز است.

پیاده‌سازی IBC برای ارسال و دریافت پیام‌ها در بلاکچین، به‌ویژه برای بلاکچین‌هایی که با Cosmos SDK ساخته شده‌اند، شامل ایجاد اتصال، کانال و کلاینت‌های مربوطه می‌شود.

۲. مراحل پیاده‌سازی ارسال و دریافت پیام‌های IBC

۲.۱. نصب و تنظیمات اولیه

برای شروع پیاده‌سازی، ابتدا باید تمام تنظیمات لازم برای پیکربندی IBC انجام شود. فرض می‌کنیم که دو بلاکچین داریم که باید پیام‌ها را از یکدیگر ارسال و دریافت کنند.

در این مثال، برای بلاکچین A و بلاکچین B که بر اساس Cosmos SDK ساخته شده‌اند، مراحل زیر را دنبال می‌کنیم.

  1. ایجاد بلاکچین‌ها: ابتدا باید هر دو بلاکچین را ایجاد کنیم. در اینجا، از Cosmos SDK برای ساخت بلاکچین‌های نمونه استفاده می‌کنیم.
    # ایجاد بلاکچین A
    cosmos-sdk init blockchain_a --chain-id blockchain_a
    
    # ایجاد بلاکچین B
    cosmos-sdk init blockchain_b --chain-id blockchain_b
    

    این دستورات بلاکچین‌های A و B را با استفاده از Cosmos SDK ایجاد خواهند کرد.

  2. ایجاد اتصال بین بلاکچین‌ها: برای اتصال دو بلاکچین از طریق IBC، باید اتصال‌های IBC را میان دو بلاکچین برقرار کنیم. برای این کار باید فایل تنظیمات Cosmos SDK را به‌روز کنیم.مسیر فایل‌های پیکربندی معمولاً در پوشه config در دایرکتوری بلاکچین‌ها قرار دارد.تنظیمات این بلاکچین‌ها باید به‌گونه‌ای باشد که از نظر IBC به یکدیگر متصل شوند.
    # بلاکچین A: تنظیم اتصال IBC
    cosmos-sdk config add connection --chain-id blockchain_b --client-id blockchain_a
    
    # بلاکچین B: تنظیم اتصال IBC
    cosmos-sdk config add connection --chain-id blockchain_a --client-id blockchain_b
    
۲.۲. ایجاد کانال‌های IBC

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

# بلاکچین A: ایجاد کانال برای ارسال پیام‌ها
cosmos-sdk create ibc-channel --chain-id blockchain_b --port port_a --client blockchain_a

# بلاکچین B: ایجاد کانال برای دریافت پیام‌ها
cosmos-sdk create ibc-channel --chain-id blockchain_a --port port_b --client blockchain_b

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

۲.۳. ارسال پیام از بلاکچین A به بلاکچین B

برای ارسال پیام از بلاکچین A به بلاکچین B، نیاز است تا پیامی را از طریق کانال IBC ارسال کنیم. در اینجا، فرض بر این است که پیام شامل یک درخواست خاص یا داده برای پردازش در بلاکچین B باشد.

  1. فرستادن پیام از بلاکچین A: در بلاکچین A، یک پیام ارسال می‌شود که اطلاعاتی را به بلاکچین B می‌فرستد.
    # بلاکچین A: ارسال پیام
    cosmos-sdk ibc send --channel port_a --recipient blockchain_b --message "پیام آزمایشی"
    

    این دستور پیام "پیام آزمایشی" را از بلاکچین A به بلاکچین B از طریق کانال port_a ارسال می‌کند.

۲.۴. دریافت پیام در بلاکچین B

در بلاکچین B، باید از طریق کانال پیام‌های ارسال‌شده را دریافت کنیم.

  1. دریافت پیام در بلاکچین B: برای دریافت پیام در بلاکچین B، می‌توانیم از ابزارهای خاصی برای رصد کانال‌ها استفاده کنیم.
    # بلاکچین B: دریافت پیام‌ها
    cosmos-sdk ibc receive --channel port_b --client blockchain_b
    

    این دستور پیام‌هایی را که از بلاکچین A ارسال شده‌اند، دریافت می‌کند.

۳. بررسی وضعیت پیام‌ها و گواهی‌نامه‌ها

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

# بررسی وضعیت ارسال پیام در بلاکچین A
cosmos-sdk ibc status --channel port_a --client blockchain_a

# بررسی وضعیت دریافت پیام در بلاکچین B
cosmos-sdk ibc status --channel port_b --client blockchain_b

این دستورات وضعیت پیام‌ها را در بلاکچین‌های مبدا و مقصد بررسی می‌کنند و اطلاعات گواهی‌نامه‌ها را نشان می‌دهند.

جمع‌بندی

پیاده‌سازی قابلیت ارسال و دریافت پیام‌های IBC در بلاکچین‌های مبتنی بر Cosmos SDK شامل چندین مرحله است که ابتدا باید اتصال‌ها و کانال‌ها ایجاد شوند، سپس پیام‌ها به‌طور امن از بلاکچین ارسال‌شده به بلاکچین مقصد منتقل شوند. این پروسه به بلاکچین‌ها این امکان را می‌دهد که به‌صورت همزمان و مستقل از یکدیگر به پردازش داده‌ها و تراکنش‌ها بپردازند. تمامی مراحل شامل ایجاد بلاکچین‌ها، تنظیم اتصال‌ها، ایجاد کانال‌ها و ارسال و دریافت پیام‌ها به‌صورت کاملاً عملی و با استفاده از دستوراتی که در اینجا آورده شد، قابل پیاده‌سازی هستند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی کاربرد IBC در تعامل بین ماژول‌های مختلف” subtitle=”توضیحات کامل”]پروتکل IBC (Inter-Blockchain Communication) علاوه بر اتصال بلاکچین‌ها به یکدیگر، نقش مهمی در تعامل بین ماژول‌های مختلف داخل یک بلاکچین ایفا می‌کند. این تعاملات باعث افزایش قابلیت‌های بلاکچین می‌شود و امکان انجام عملیات‌های پیچیده و متنوع را فراهم می‌آورد. در این بخش، کاربرد IBC در تعامل بین ماژول‌های مختلف در یک بلاکچین بر اساس Cosmos SDK بررسی می‌شود.

۱. مقدمه‌ای بر ماژول‌ها در Cosmos SDK

Cosmos SDK یک فریم‌ورک توسعه بلاکچین است که از ماژول‌ها برای ایجاد بلاکچین‌های سفارشی استفاده می‌کند. هر بلاکچین در Cosmos SDK می‌تواند شامل تعدادی ماژول باشد که هرکدام وظایف خاصی را انجام می‌دهند، مانند مدیریت تراکنش‌ها، اعتبارسنجی‌ها، و ذخیره‌سازی داده‌ها.

ماژول‌های Cosmos SDK می‌توانند به‌طور مستقل عمل کنند، اما گاهی نیاز به تعامل با یکدیگر دارند تا عملکردهای پیچیده‌تر و متنوع‌تری ایجاد کنند. در اینجا، IBC به عنوان ابزاری برای تسهیل این تعاملات میان ماژول‌ها شناخته می‌شود.

۲. نقش IBC در تعامل بین ماژول‌ها

در این بخش، چندین مثال کاربردی برای نشان دادن نحوه استفاده از IBC در تعامل بین ماژول‌ها آورده شده است:

۲.۱. ارسال و دریافت پیام‌ها بین ماژول‌ها

ماژول‌های مختلف در یک بلاکچین ممکن است نیاز به ارسال پیام‌ها یا داده‌ها به یکدیگر داشته باشند. با استفاده از IBC، پیام‌ها می‌توانند از یک ماژول به ماژول دیگر منتقل شوند.

مثال عملی: فرض کنید دو ماژول در بلاکچین داریم: یکی برای مدیریت حساب‌ها و دیگری برای مدیریت تراکنش‌ها. برای پردازش یک تراکنش، باید از اطلاعات حساب‌ها استفاده شود. IBC می‌تواند این تعامل را بین این ماژول‌ها مدیریت کند.

# ماژول حساب‌ها (Account Module): ارسال اطلاعات حساب به ماژول تراکنش‌ها
cosmos-sdk ibc send --channel port_account_module --recipient transaction_module --message "اطلاعات حساب"

در این دستور، پیام حاوی اطلاعات حساب‌ها از ماژول account_module به ماژول transaction_module ارسال می‌شود.

۲.۲. استفاده از IBC برای هماهنگی عملیات‌های پیچیده

در برخی موارد، برای انجام یک عملیات پیچیده، چندین ماژول باید به‌طور هماهنگ عمل کنند. IBC می‌تواند برای هماهنگی این عملیات‌ها بین ماژول‌ها مورد استفاده قرار گیرد.

مثال عملی: فرض کنید نیاز داریم تا یک درخواست پردازش داده در ماژول تحلیل (Analytics Module) به ماژول ثبت تراکنش (Transaction Module) ارسال شود تا تراکنش‌هایی که توسط ماژول تحلیل انجام شده‌اند، ثبت شوند.

# ارسال درخواست پردازش از ماژول تحلیل به ماژول تراکنش‌ها
cosmos-sdk ibc send --channel port_analytics_module --recipient transaction_module --message "درخواست پردازش داده"

در اینجا، IBC تضمین می‌کند که پیام‌ها به‌صورت ایمن و با تایید از ماژول تحلیل به ماژول تراکنش ارسال می‌شوند.

۲.۳. پردازش داده‌ها از ماژول‌های مختلف با استفاده از IBC

ماژول‌ها ممکن است نیاز به پردازش داده‌ها به‌طور هم‌زمان داشته باشند. در این صورت، IBC می‌تواند پیام‌هایی که نیاز به پردازش هم‌زمان دارند را بین ماژول‌ها ارسال کند.

مثال عملی: فرض کنید دو ماژول داریم: یکی برای مدیریت داده‌های کاربران و دیگری برای تحلیل داده‌ها. هنگام ارسال داده از ماژول اول به ماژول دوم، پیام باید در همان کانال IBC بین ماژول‌ها منتقل شود.

# ارسال داده از ماژول داده‌های کاربران به ماژول تحلیل داده‌ها
cosmos-sdk ibc send --channel port_user_data_module --recipient analytics_module --message "داده‌های کاربر"

۳. پیاده‌سازی تنظیمات IBC برای تعامل ماژول‌ها

برای تنظیم IBC در یک بلاکچین برای استفاده بین ماژول‌ها، ابتدا باید کانال‌های IBC ایجاد شوند و سپس مسیرهای ارتباطی میان ماژول‌ها تعریف شوند.

۳.۱. ایجاد کانال برای تعامل ماژول‌ها

برای هر تعامل بین ماژول‌ها، نیاز به ایجاد کانال IBC داریم. در اینجا، نحوه ایجاد یک کانال IBC میان دو ماژول توضیح داده شده است.

# بلاکچین: ایجاد کانال بین ماژول‌ها
cosmos-sdk create ibc-channel --chain-id blockchain_id --port port_module_a --client blockchain_a
cosmos-sdk create ibc-channel --chain-id blockchain_id --port port_module_b --client blockchain_b

این دستورات کانال‌های IBC را برای ارتباط بین دو ماژول ایجاد می‌کنند.

۳.۲. ارسال و دریافت پیام از طریق IBC

پس از ایجاد کانال، می‌توان پیام‌ها را بین ماژول‌ها ارسال و دریافت کرد. به‌طور مثال، می‌توان پیام‌هایی از ماژول‌های مختلف را از طریق IBC ارسال کرد.

# ارسال پیام از ماژول A به ماژول B
cosmos-sdk ibc send --channel port_module_a --recipient module_b --message "پیام از ماژول A"

جمع‌بندی

پروتکل IBC در Cosmos SDK تنها برای اتصال بلاکچین‌ها به‌کار نمی‌رود، بلکه نقش کلیدی در تعامل بین ماژول‌های مختلف داخل یک بلاکچین دارد. این پروتکل با ارسال و دریافت ایمن پیام‌ها و داده‌ها بین ماژول‌ها، باعث افزایش تعاملات و هماهنگی بین بخش‌های مختلف بلاکچین می‌شود. استفاده از IBC برای تسهیل این ارتباطات به‌طور چشمگیری کارایی و انعطاف‌پذیری بلاکچین‌ها را افزایش می‌دهد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. تست و دیباگ ماژول سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اجرای تست‌های واحد (Unit Tests) برای ماژول” subtitle=”توضیحات کامل”]تست‌های واحد (Unit Tests) ابزارهای مهمی برای اطمینان از صحت عملکرد ماژول‌ها و کدهای مختلف در بلاکچین‌ها هستند. این تست‌ها به‌ویژه در هنگام توسعه ماژول‌های جدید یا هنگام اعمال تغییرات در ماژول‌های موجود اهمیت زیادی دارند. در این بخش، نحوه اجرای تست‌های واحد برای ماژول‌ها در Cosmos SDK را بررسی خواهیم کرد.

۱. مقدمه‌ای بر تست‌های واحد

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

در Cosmos SDK، تست‌های واحد معمولاً برای ماژول‌ها به‌طور خاص طراحی می‌شوند تا عملکرد هر ماژول به‌طور مجزا بررسی شود. این تست‌ها به‌طور معمول با استفاده از زبان‌های برنامه‌نویسی مانند Go نوشته می‌شوند که زبان اصلی برای توسعه در Cosmos SDK است.

۲. تست‌های واحد در Cosmos SDK

Cosmos SDK از فریم‌ورک‌های مختلفی برای نوشتن و اجرای تست‌های واحد استفاده می‌کند. معمول‌ترین فریم‌ورک برای نوشتن تست‌های واحد در Cosmos SDK، فریم‌ورک testing است که در زبان Go وجود دارد.

۲.۱. نوشتن تست واحد برای ماژول

برای نوشتن تست‌های واحد برای ماژول‌ها در Cosmos SDK، ابتدا باید یک فایل تست (با پسوند .go) ایجاد کنید که حاوی توابع تست باشد. در این فایل، می‌توانید از فریم‌ورک testing برای ایجاد و اجرای تست‌ها استفاده کنید.

مثال عملی: فرض کنید ما یک ماژول به نام bank داریم که عملکردهای مختلفی را برای انتقال وجه و مدیریت حساب‌ها انجام می‌دهد. برای نوشتن یک تست واحد برای تابع انتقال وجه از ماژول bank، می‌توان از کد زیر استفاده کرد:

// bank_test.go
package bank

import (
    "testing"
    "github.com/stretchr/testify/assert"
    sdk "github.com/cosmos/cosmos-sdk/types"
)

func TestSendCoins(t *testing.T) {
    // تنظیمات اولیه
    sender := sdk.AccAddress([]byte("sender"))
    recipient := sdk.AccAddress([]byte("recipient"))
    amount := sdk.NewCoins(sdk.NewCoin("atom", sdk.NewInt(100)))

    // فراخوانی تابع ارسال پول
    err := SendCoins(sender, recipient, amount)

    // بررسی نتایج
    assert.Nil(t, err, "باید خطایی وجود نداشته باشد")
    assert.True(t, amount.IsEqual(GetAccountBalance(recipient)), "میزان موجودی دریافت‌کننده باید درست باشد")
}

در این مثال:

  • ابتدا مقادیر اولیه مانند آدرس‌های فرستنده و گیرنده و مقدار انتقال داده می‌شود.
  • سپس تابع SendCoins که مسئول انتقال وجه است فراخوانی می‌شود.
  • بعد از آن، با استفاده از ابزارهای موجود مانند assert بررسی می‌شود که آیا خطایی در انجام انتقال وجود ندارد و موجودی گیرنده به درستی بروزرسانی شده است یا خیر.
۲.۲. اجرای تست‌های واحد

برای اجرای تست‌های واحد در Cosmos SDK، باید از دستور go test استفاده کنید. این دستور به‌طور خودکار تمامی توابع تست موجود در پروژه را پیدا کرده و آنها را اجرا می‌کند.

دستور اجرای تست‌ها:

# اجرای تمامی تست‌های واحد
go test ./...

در این دستور، ./... به این معناست که تمامی تست‌ها در پروژه (در تمامی دایرکتوری‌ها) اجرا شوند.

اگر بخواهید فقط تست‌های یک فایل خاص را اجرا کنید، می‌توانید از دستور زیر استفاده کنید:

# اجرای تست‌های یک فایل خاص
go test ./path/to/your/test/file
۲.۳. بررسی نتایج تست‌ها

پس از اجرای دستور go test، نتایج تست‌ها در کنسول نمایش داده می‌شود. اگر تمامی تست‌ها با موفقیت انجام شوند، پیام PASS نشان داده می‌شود و در غیر این صورت، پیام FAIL نمایش خواهد یافت و خطاهای مربوطه همراه با جزئیات آن‌ها نمایش داده می‌شود.

۳. نحوه استفاده از Mocking برای تست‌ها

برای تست عملکرد ماژول‌ها به‌ویژه در مواقعی که ماژول‌ها به منابع خارجی یا دیگر ماژول‌ها نیاز دارند، می‌توان از تکنیک Mocking برای شبیه‌سازی این وابستگی‌ها استفاده کرد.

در Cosmos SDK، از کتابخانه‌هایی مانند testify و mockery برای شبیه‌سازی توابع و ساختارهای پیچیده استفاده می‌شود.

مثال عملی Mocking: فرض کنید ما نیاز داریم تا تابعی را که به یک ماژول خارجی برای دریافت داده‌ها وابسته است، آزمایش کنیم. با استفاده از mocking می‌توان این وابستگی‌ها را شبیه‌سازی کرد.

package bank

import (
    "testing"
    "github.com/stretchr/testify/mock"
)

type MockModule struct {
    mock.Mock
}

func (m *MockModule) GetBalance(address string) int {
    args := m.Called(address)
    return args.Int(0)
}

func TestMockedModule(t *testing.T) {
    // ایجاد نمونه Mock
    mockModule := new(MockModule)
    mockModule.On("GetBalance", "address123").Return(100)

    // انجام تست
    result := mockModule.GetBalance("address123")

    // بررسی نتایج
    assert.Equal(t, 100, result, "موجودی باید 100 باشد")
}

در این مثال، از Mocking برای شبیه‌سازی عملکرد ماژول استفاده شده است تا بدون نیاز به وابستگی به ماژول‌های واقعی، تست‌ها اجرا شوند.

۴. پیاده‌سازی تنظیمات در فایل‌ها

تست‌ها معمولاً در دایرکتوری test یا x/<module>/test در داخل پروژه قرار می‌گیرند. مسیر فایل‌های تست باید به‌گونه‌ای باشد که به‌راحتی قابل شناسایی و دسترسی باشند.

# مسیر فایل تست‌ها در پروژه
/path/to/project/x/bank/test/bank_test.go

جمع‌بندی

اجرای تست‌های واحد در توسعه بلاکچین‌های مبتنی بر Cosmos SDK یکی از بهترین روش‌ها برای اطمینان از عملکرد صحیح ماژول‌ها و کدهای مختلف است. با نوشتن تست‌های واحد، می‌توان از صحت عملکرد هر بخش از بلاکچین مطمئن شد و به راحتی مشکلات احتمالی را شناسایی و رفع کرد. استفاده از ابزارهای Mocking برای شبیه‌سازی وابستگی‌ها به منابع خارجی و دیگر ماژول‌ها، امکان انجام تست‌های پیچیده‌تر و کارآمدتر را فراهم می‌آورد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از ابزارهای Cosmos SDK برای خطایابی” subtitle=”توضیحات کامل”]خطایابی (Debugging) یکی از مهم‌ترین بخش‌های فرآیند توسعه نرم‌افزار است که در بلاکچین‌ها به‌ویژه در پروژه‌های مبتنی بر Cosmos SDK اهمیت زیادی دارد. این ابزارها به توسعه‌دهندگان کمک می‌کنند تا مشکلات مختلف در کد را شناسایی و برطرف کنند. در این بخش، به معرفی ابزارهای مختلف Cosmos SDK برای خطایابی و نحوه استفاده از آن‌ها خواهیم پرداخت.

۱. ابزارهای خطایابی در Cosmos SDK

Cosmos SDK ابزارهای مختلفی را برای خطایابی در اختیار توسعه‌دهندگان قرار می‌دهد. این ابزارها معمولاً شامل ابزارهای لاگ‌برداری، مانیتورینگ، بررسی وضعیت بلاک‌چین و تست‌های واحد هستند. در اینجا به بررسی برخی از این ابزارها خواهیم پرداخت.

۱.۱. استفاده از لاگ‌ها (Logging)

یکی از مهم‌ترین ابزارها برای خطایابی در Cosmos SDK، استفاده از لاگ‌ها است. در Cosmos SDK، از فریم‌ورک Log برای ثبت اطلاعات و خطاها استفاده می‌شود. با استفاده از این ابزار، می‌توانید به‌طور دقیق‌تر فرآیندهای مختلف را پیگیری کرده و خطاهای احتمالی را شناسایی کنید.

برای استفاده از لاگ‌برداری، باید ابتدا یک شیء logger ایجاد کنید. سپس می‌توانید از متدهای مختلف مانند Info(), Error() و Debug() برای ثبت انواع لاگ‌ها استفاده کنید.

مثال عملی: در این مثال، به‌طور ساده لاگ‌هایی برای نمایش وضعیت درخواست‌های ورودی به ماژول bank ثبت می‌کنیم:

package bank

import (
    "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/log"
)

func (k Keeper) SendCoins(ctx types.Context, fromAddr types.AccAddress, toAddr types.AccAddress, amount types.Coins) error {
    // ایجاد شیء logger
    logger := ctx.Logger()

    // ثبت لاگ برای بررسی عملیات انتقال
    logger.Info("Starting SendCoins operation", "from", fromAddr, "to", toAddr, "amount", amount)

    // شبیه‌سازی عملیات انتقال
    err := k.bankKeeper.SendCoins(ctx, fromAddr, toAddr, amount)
    if err != nil {
        logger.Error("Failed to send coins", "error", err.Error())
        return err
    }

    logger.Info("Successfully sent coins", "from", fromAddr, "to", toAddr, "amount", amount)
    return nil
}

در این کد:

  • ابتدا یک شیء logger از طریق ctx.Logger() ایجاد می‌شود.
  • سپس با استفاده از متدهای Info() و Error(), اطلاعات مربوط به عملیات انتقال ثبت می‌شود.
  • در صورتی که خطایی رخ دهد، این خطا در لاگ ثبت می‌شود.
۱.۲. استفاده از gRPC برای برقراری ارتباط و خطایابی

gRPC یک پروتکل قدرتمند است که برای برقراری ارتباط بین سرور و کلاینت در Cosmos SDK استفاده می‌شود. با استفاده از gRPC می‌توانید درخواست‌های مختلف را به بلاک‌چین ارسال کرده و نتایج آن‌ها را برای خطایابی بررسی کنید.

در زمان توسعه، گاهی اوقات لازم است که درخواست‌ها و پاسخ‌های gRPC را برای خطایابی دقیق‌تر بررسی کنید. برای این کار می‌توانید از ابزارهای grpcurl یا grpcui استفاده کنید.

استفاده از grpcurl:

grpcurl یک ابزار خط فرمان است که به شما این امکان را می‌دهد که به‌راحتی درخواست‌های gRPC ارسال کرده و پاسخ‌ها را مشاهده کنید.

# ارسال درخواست به بلاک‌چین با استفاده از grpcurl
grpcurl -d '{"from": "cosmos1xyz", "to": "cosmos1abc", "amount": "100atom"}' \
    -H "Authorization: Bearer <token>" \
    <blockchain-node-address>:<port> cosmos.bank.v1beta1.MsgSend

در این دستور:

  • -d داده‌های درخواست ارسال‌شده را به صورت JSON نمایش می‌دهد.
  • -H هدرهایی مانند توکن‌های دسترسی را اضافه می‌کند.
  • <blockchain-node-address>:<port> آدرس و پورت نود بلاک‌چین مقصد است.

استفاده از grpcui:

grpcui یک ابزار گرافیکی است که امکان ارسال درخواست‌های gRPC به بلاک‌چین را از طریق رابط کاربری گرافیکی فراهم می‌کند. با استفاده از این ابزار می‌توانید درخواست‌های مختلف را ارسال کرده و به‌صورت گرافیکی پاسخ‌ها و خطاها را مشاهده کنید.

برای نصب و استفاده از grpcui، کافیست دستور زیر را اجرا کنید:

# نصب grpcui
go install github.com/fullstorydev/grpcui/cmd/grpcui@latest

# استفاده از grpcui برای اتصال به نود
grpcui <blockchain-node-address>:<port>

۲. ابزارهای خطایابی سطح پایین

برای خطایابی در سطح پایین‌تر، برخی از ابزارها مانند delve برای بررسی حالت‌های داخلی برنامه و pprof برای تحلیل عملکرد سیستم نیز در Cosmos SDK کاربرد دارند.

۲.۱. استفاده از Delve برای خطایابی

Delve یک ابزار دیباگر برای زبان Go است که امکان بررسی دقیق وضعیت متغیرها و اجرای کد را به‌صورت گام‌به‌گام فراهم می‌کند.

برای استفاده از delve می‌توانید دستور زیر را برای شروع دیباگ کردن بلاک‌چین خود اجرا کنید:

# شروع دیباگ با Delve
dlv debug ./cosmosd

سپس با استفاده از دستورات break, step, next و continue می‌توانید کد را به‌صورت گام‌به‌گام اجرا کرده و وضعیت متغیرها و توابع را بررسی کنید.

۲.۲. استفاده از pprof برای تحلیل عملکرد

pprof یک ابزار قدرتمند برای تحلیل عملکرد (Performance Profiling) برنامه‌ها است. در Cosmos SDK، برای بهبود عملکرد و شناسایی مشکلات احتمالی در زمان اجرا می‌توانید از pprof برای بررسی مصرف منابع و وضعیت سیستم استفاده کنید.

برای فعال‌سازی pprof در Cosmos SDK، کافیست در فایل پیکربندی تنظیمات مربوطه را انجام دهید:

# فعال‌سازی pprof در فایل پیکربندی
cosmosd start --pprof

سپس با استفاده از ابزارهایی مانند go tool pprof می‌توانید به تحلیل مصرف منابع پرداخته و بخش‌های مختلف کد که عملکرد ضعیف دارند را شناسایی کنید.

۳. بررسی وضعیت بلاک‌چین با استفاده از CLI

از ابزارهای CLI در Cosmos SDK می‌توان برای بررسی وضعیت بلاک‌چین و شناسایی مشکلات احتمالی استفاده کرد. با استفاده از دستورات CLI می‌توانید اطلاعات مختلفی مانند وضعیت نود، حساب‌ها، تراکنش‌ها و بلاک‌ها را دریافت کنید.

برای بررسی وضعیت نود می‌توانید از دستور زیر استفاده کنید:

# بررسی وضعیت نود
cosmosd status

همچنین می‌توانید با استفاده از دستور زیر اطلاعات مربوط به حساب‌ها را بررسی کنید:

# بررسی موجودی حساب
cosmosd query bank balances <account-address>

جمع‌بندی

ابزارهای خطایابی در Cosmos SDK شامل موارد مختلفی مانند لاگ‌برداری، gRPC، Delve، pprof و ابزارهای CLI هستند که هرکدام قابلیت‌های خاص خود را برای شناسایی و رفع مشکلات فراهم می‌آورند. با استفاده از این ابزارها می‌توانید به‌طور دقیق‌تر مشکلات کدهای بلاک‌چین خود را شناسایی و برطرف کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی لاگ‌ها و دیباگ تراکنش‌ها” subtitle=”توضیحات کامل”]لاگ‌ها و دیباگ تراکنش‌ها در فرآیند توسعه بلاک‌چین، به‌ویژه در Cosmos SDK، ابزارهای قدرتمندی برای شناسایی مشکلات و خطاها به‌شمار می‌آیند. این ابزارها به توسعه‌دهندگان این امکان را می‌دهند که رفتار سیستم را به‌طور دقیق مشاهده کرده و در صورت بروز مشکل، آن را شناسایی و اصلاح کنند.

در این بخش، به بررسی نحوه استفاده از لاگ‌ها و ابزارهای دیباگ برای بررسی تراکنش‌ها در بلاک‌چین‌های مبتنی بر Cosmos SDK خواهیم پرداخت.

۱. بررسی لاگ‌ها

۱.۱. استفاده از سیستم لاگ‌برداری در Cosmos SDK

سیستم لاگ‌برداری در Cosmos SDK از فریم‌ورک Log برای ثبت انواع لاگ‌ها (اطلاعات، هشدار، خطا) استفاده می‌کند. این فریم‌ورک به شما کمک می‌کند تا در طول فرآیند پردازش تراکنش‌ها، اطلاعات مرتبط با وضعیت سیستم و خطاهای احتمالی را ثبت کنید.

برای استفاده از لاگ‌ها در تراکنش‌ها، می‌توانید به‌طور مستقیم در کد مربوطه از متدهای Info(), Error(), Debug() و غیره استفاده کنید. این متدها امکان ثبت انواع لاگ‌ها را فراهم می‌کنند که می‌تواند برای بررسی تراکنش‌ها و عیب‌یابی استفاده شود.

مثال عملی:

در این مثال، قصد داریم لاگ‌هایی را برای تراکنش‌های مربوط به ارسال ارز از یک حساب به حساب دیگر ثبت کنیم:

package bank

import (
    "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/log"
)

func (k Keeper) SendCoins(ctx types.Context, fromAddr types.AccAddress, toAddr types.AccAddress, amount types.Coins) error {
    // ایجاد شیء logger
    logger := ctx.Logger()

    // ثبت لاگ برای شروع عملیات
    logger.Info("Starting SendCoins operation", "from", fromAddr, "to", toAddr, "amount", amount)

    // اجرای عملیات انتقال
    err := k.bankKeeper.SendCoins(ctx, fromAddr, toAddr, amount)
    if err != nil {
        // ثبت لاگ در صورت وقوع خطا
        logger.Error("Failed to send coins", "error", err.Error())
        return err
    }

    // ثبت لاگ در صورت موفقیت
    logger.Info("Successfully sent coins", "from", fromAddr, "to", toAddr, "amount", amount)
    return nil
}

در این کد:

  • از ctx.Logger() برای ایجاد یک شیء logger استفاده می‌کنیم.
  • با استفاده از Info() اطلاعات مربوط به تراکنش‌ها را ثبت می‌کنیم.
  • در صورت بروز خطا، از Error() برای ثبت خطاها استفاده می‌کنیم.
۱.۲. بررسی لاگ‌ها در فایل‌های ذخیره‌شده

لاگ‌ها معمولاً در فایل‌هایی ذخیره می‌شوند که در مسیر پیش‌فرض بلاک‌چین یا از طریق پیکربندی قابل دسترسی هستند. در Cosmos SDK، مسیر فایل‌های لاگ به‌طور معمول در فایل پیکربندی نود بلاک‌چین مشخص می‌شود.

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

~/.cosmosd/logs/

برای مشاهده لاگ‌ها، می‌توانید از ابزارهایی مانند cat, less یا tail استفاده کنید:

# نمایش لاگ‌ها در فایل
tail -f ~/.cosmosd/logs/cosmosd.log

۲. دیباگ تراکنش‌ها

۲.۱. استفاده از gRPC برای دیباگ تراکنش‌ها

gRPC یکی از ابزارهای قدرتمند برای برقراری ارتباط با بلاک‌چین است. با استفاده از gRPC می‌توانید درخواست‌های مختلف مربوط به تراکنش‌ها را ارسال کرده و پاسخ آن‌ها را بررسی کنید. این ابزار برای دیباگ و بررسی دقیق تراکنش‌ها بسیار مفید است.

برای استفاده از gRPC در دیباگ تراکنش‌ها، می‌توانید از ابزارهایی مانند grpcurl برای ارسال درخواست‌ها و بررسی پاسخ‌ها استفاده کنید.

مثال عملی با grpcurl:

برای ارسال یک درخواست gRPC و دیباگ تراکنش، دستور زیر را اجرا کنید:

# ارسال درخواست برای تراکنش ارسال ارز با استفاده از grpcurl
grpcurl -d '{"from": "cosmos1xyz", "to": "cosmos1abc", "amount": "100atom"}' \
    -H "Authorization: Bearer <token>" \
    <blockchain-node-address>:<port> cosmos.bank.v1beta1.MsgSend

در این دستور:

  • -d داده‌های JSON مربوط به تراکنش ارسال می‌شود.
  • -H هدرهای مورد نیاز (مانند توکن دسترسی) به درخواست اضافه می‌شود.
  • <blockchain-node-address>:<port> آدرس و پورت نود بلاک‌چین مقصد است.

با استفاده از این ابزار می‌توانید درخواست‌های تراکنش ارسال کنید و نتیجه آن را به‌طور دقیق بررسی نمایید.

۲.۲. استفاده از Delve برای دیباگ کد

Delve یک ابزار دیباگر برای زبان Go است که برای بررسی و دیباگ کردن کدهای Cosmos SDK بسیار مفید است. با استفاده از Delve می‌توانید به‌طور دقیق کد را گام‌به‌گام اجرا کرده و وضعیت متغیرها و عملیات را بررسی کنید.

برای شروع دیباگ تراکنش‌ها با Delve، ابتدا باید نود خود را با استفاده از دستور dlv debug راه‌اندازی کنید:

# شروع دیباگ با Delve
dlv debug ./cosmosd

سپس با استفاده از دستورات مختلف Delve مانند break, step, next و continue می‌توانید به بررسی دقیق‌تر تراکنش‌ها بپردازید.

۲.۳. استفاده از pprof برای تحلیل تراکنش‌ها

pprof یکی دیگر از ابزارهای مفید برای تحلیل عملکرد تراکنش‌ها است. با استفاده از pprof می‌توانید مصرف منابع و وضعیت تراکنش‌ها را تجزیه و تحلیل کنید. برای فعال‌سازی pprof در بلاک‌چین، می‌توانید از دستور زیر استفاده کنید:

# فعال‌سازی pprof در بلاک‌چین
cosmosd start --pprof

پس از فعال‌سازی، می‌توانید از ابزار go tool pprof برای بررسی دقیق‌تر عملکرد و شناسایی بخش‌هایی که ممکن است باعث مشکلات در تراکنش‌ها شوند استفاده کنید.

۳. بررسی وضعیت تراکنش‌ها با استفاده از CLI

از دستورات CLI در Cosmos SDK می‌توان برای بررسی وضعیت تراکنش‌ها و شناسایی مشکلات احتمالی استفاده کرد. برای بررسی وضعیت یک تراکنش خاص، می‌توانید از دستور زیر استفاده کنید:

# بررسی وضعیت تراکنش
cosmosd query tx <transaction-hash>

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

جمع‌بندی

بررسی لاگ‌ها و دیباگ تراکنش‌ها در Cosmos SDK از اهمیت بالایی برخوردار است و ابزارهای مختلفی برای این کار وجود دارد. با استفاده از لاگ‌برداری، gRPC، Delve، pprof و ابزارهای CLI می‌توانید به‌طور دقیق‌تر وضعیت تراکنش‌ها را بررسی کرده و مشکلات احتمالی را شناسایی و رفع کنید. این ابزارها به توسعه‌دهندگان کمک می‌کنند تا بلاک‌چین‌های مبتنی بر Cosmos SDK را با کارایی و دقت بالا توسعه دهند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 9. استقرار و استفاده از ماژول در بلاکچین سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اضافه کردن ماژول به بلاکچین سفارشی” subtitle=”توضیحات کامل”]در این بخش، نحوه اضافه کردن ماژول به یک بلاکچین سفارشی که با استفاده از Cosmos SDK ساخته شده است، مورد بررسی قرار خواهد گرفت. این فرآیند شامل مراحل مختلفی از جمله ایجاد ماژول جدید، تنظیمات پیکربندی، و افزودن آن به بلاکچین است.

اضافه کردن ماژول به بلاکچین سفارشی در Cosmos SDK به‌عنوان یک وظیفه استاندارد و یکی از اصلی‌ترین اقدامات در فرآیند توسعه بلاکچین‌های مبتنی بر این SDK در نظر گرفته می‌شود. ماژول‌ها به‌طور عمده برای پیاده‌سازی ویژگی‌های مختلف بلاکچین نظیر پردازش تراکنش‌ها، ذخیره‌سازی داده‌ها، و مدیریت حساب‌ها استفاده می‌شوند.

۱. ساختار ماژول‌ها در Cosmos SDK

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

ساختار یک ماژول معمولاً شامل این بخش‌ها است:

  • Keeper: مسئول دسترسی به داده‌ها و ذخیره‌سازی وضعیت.
  • Handler: مدیریت تراکنش‌ها و پردازش آن‌ها.
  • Types: شامل انواع داده‌ها و ساختارهای مورد استفاده در ماژول.
  • Genesis: داده‌های مربوط به وضعیت اولیه هنگام راه‌اندازی بلاکچین.

۲. ایجاد یک ماژول جدید

۲.۱. تعریف پوشه ماژول

اولین قدم برای اضافه کردن یک ماژول به بلاکچین سفارشی، ایجاد یک پوشه جدید در پروژه است. این پوشه باید شامل کدهای اصلی ماژول باشد. برای مثال، ماژول جدیدی به نام mymodule می‌سازیم:

# ایجاد پوشه برای ماژول جدید
mkdir -p ~/cosmos-project/x/mymodule
۲.۲. فایل‌های ماژول

در داخل این پوشه، فایل‌های اصلی ماژول ایجاد می‌شوند. به‌طور معمول، برای یک ماژول جدید این فایل‌ها شامل موارد زیر خواهند بود:

  • keeper.go: نگهداری و مدیریت وضعیت.
  • handler.go: پردازش تراکنش‌ها.
  • types.go: تعریف انواع داده‌ها و ساختارهای مورد نیاز.
  • genesis.go: داده‌های ژنزیس و وضعیت اولیه.

برای مثال، ابتدا فایل keeper.go را به شکل زیر می‌سازیم:

// x/mymodule/keeper.go
package mymodule

import (
    "github.com/cosmos/cosmos-sdk/types"
)

type Keeper struct {
    storeKey types.StoreKey
    cdc      *types.Codec
}

func NewKeeper(storeKey types.StoreKey, cdc *types.Codec) Keeper {
    return Keeper{
        storeKey: storeKey,
        cdc:      cdc,
    }
}
۲.۳. اضافه کردن Handler

در فایل handler.go، باید منطق پردازش تراکنش‌های مرتبط با ماژول خود را اضافه کنیم. این فایل مسئول پردازش درخواست‌های ورودی و انجام عملیات‌های لازم است.

// x/mymodule/handler.go
package mymodule

import (
    "github.com/cosmos/cosmos-sdk/types"
)

func NewHandler(k Keeper) types.Handler {
    return func(ctx types.Context, msg types.Msg) (*types.Result, error) {
        switch msg := msg.(type) {
        case types.MsgSend:
            return handleMsgSend(ctx, k, msg)
        default:
            errMsg := "unrecognized message type"
            return nil, types.ErrUnknownRequest(errMsg)
        }
    }
}

func handleMsgSend(ctx types.Context, k Keeper, msg types.MsgSend) (*types.Result, error) {
    // منطق ارسال پیام
    return &types.Result{}, nil
}
۲.۴. تعریف Types و Genesis

در فایل types.go، انواع داده‌هایی که در ماژول شما استفاده می‌شوند، تعریف می‌شوند. به‌عنوان مثال، در این بخش می‌توانید ساختارهای پیام (message) و انواع داده‌های مربوط به وضعیت یا تراکنش‌ها را تعریف کنید.

// x/mymodule/types.go
package mymodule

import (
    "github.com/cosmos/cosmos-sdk/types"
)

type MsgSend struct {
    From   types.AccAddress `json:"from"`
    To     types.AccAddress `json:"to"`
    Amount types.Coins       `json:"amount"`
}

func NewMsgSend(from, to types.AccAddress, amount types.Coins) MsgSend {
    return MsgSend{
        From:   from,
        To:     to,
        Amount: amount,
    }
}

در فایل genesis.go، می‌توانید داده‌های ژنزیس را تعریف کنید تا هنگام راه‌اندازی بلاکچین وضعیت اولیه تنظیم شود.

// x/mymodule/genesis.go
package mymodule

import (
    "github.com/cosmos/cosmos-sdk/types"
)

func NewGenesisState() GenesisState {
    return GenesisState{}
}

۳. افزودن ماژول به بلاکچین

۳.۱. ثبت ماژول در app.go

برای افزودن ماژول به بلاکچین، باید آن را در فایل app.go که در پوشه cmd قرار دارد، ثبت کنیم. در این فایل، باید ماژول را به‌عنوان بخشی از پروژه بلاکچین خود تعریف کرده و آن را به‌عنوان یک ماژول فعال در بلاکچین وارد کنید.

// cmd/cosmosd/app.go
package app

import (
    "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/types/module"
    "github.com/cosmos/cosmos-sdk/x/mymodule"
)

type CosmosApp struct {
    moduleManager *module.Manager
}

func NewCosmosApp() *CosmosApp {
    app := &CosmosApp{}
    
    // ثبت ماژول
    app.moduleManager.RegisterModules(
        mymodule.NewAppModule(),
    )

    return app
}
۳.۲. پیکربندی ماژول در بلاکچین

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

۴. کامپایل و اجرای بلاکچین

پس از افزودن ماژول به پروژه، باید بلاکچین را کامپایل کرده و تست کنید. برای این کار از دستورات زیر استفاده کنید:

# کامپایل بلاکچین
go build -o cosmosd .

# اجرای بلاکچین
./cosmosd start

جمع‌بندی

اضافه کردن ماژول به بلاکچین سفارشی در Cosmos SDK فرآیند ساده‌ای است که شامل ایجاد پوشه و فایل‌های مورد نیاز، تنظیم ماژول در app.go و پیکربندی آن برای بلاکچین است. با استفاده از این روش می‌توانید ویژگی‌های جدید را به بلاکچین‌های مبتنی بر Cosmos SDK اضافه کرده و آن‌ها را به‌طور مؤثر در برنامه‌های خود پیاده‌سازی کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”راه‌اندازی Node برای اجرای ماژول” subtitle=”توضیحات کامل”]در این بخش، به توضیح نحوه راه‌اندازی یک Node در بلاکچین سفارشی مبتنی بر Cosmos SDK برای اجرای ماژول جدیدی که به بلاکچین اضافه کرده‌ایم، می‌پردازیم. اجرای این Node به‌عنوان یک گره (node) در شبکه بلاکچین، امکان تعامل با دیگر گره‌ها و پیاده‌سازی ویژگی‌های جدید ماژول را فراهم می‌کند.

برای راه‌اندازی Node، لازم است که تمامی تنظیمات مربوط به شبکه، ماژول‌ها، و پیکربندی‌های لازم در بلاکچین اعمال شوند.

۱. پیکربندی و راه‌اندازی گره (Node)

۱.۱. پیکربندی فایل‌های تنظیمات

برای راه‌اندازی گره، باید فایل‌های پیکربندی مربوط به بلاکچین را تنظیم کنیم. این فایل‌ها شامل تنظیمات مربوط به بلاکچین، شبکه، و ویژگی‌های امنیتی هستند. فایل‌های پیکربندی در مسیر ~/.cosmosd/config/ قرار دارند.

فایل‌هایی که نیاز به تنظیم دارند عبارتند از:

  • config.toml
  • app.toml
  • genesis.json
۱.۲. تنظیمات فایل config.toml

در ابتدا، فایل config.toml را بررسی و تنظیمات آن را مطابق نیاز شبکه تنظیم می‌کنیم. این فایل شامل پیکربندی‌های عمومی گره است، نظیر آدرس‌های گره، پورت‌ها، و سایر تنظیمات شبکه.

مسیر فایل:

~/.cosmosd/config/config.toml

مهم‌ترین تنظیماتی که باید بررسی و تنظیم شوند عبارتند از:

  • rpc.laddr: آدرس و پورت برای RPC.
  • p2p.laddr: آدرس و پورت برای ارتباطات P2P (Peer-to-Peer).
  • seeds: لیست گره‌های seed برای اتصال به شبکه.
# پیکربندی شبکه و RPC
rpc.laddr = "tcp://0.0.0.0:26657"

# پیکربندی ارتباطات P2P
p2p.laddr = "tcp://0.0.0.0:26656"

# پیکربندی گره‌های seed
seeds = "seed-node:26656"
۱.۳. تنظیمات فایل app.toml

در این فایل تنظیمات مربوط به ماژول‌ها و ویژگی‌های خاص بلاکچین قرار دارند. باید ماژول جدید خود را به این فایل اضافه کنیم تا به‌طور صحیح در گره بارگذاری شود.

مسیر فایل:

~/.cosmosd/config/app.toml

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

# پیکربندی ماژول‌ها
[mymodule]
enabled = true
۱.۴. تنظیمات فایل genesis.json

این فایل مربوط به وضعیت اولیه بلاکچین است و باید شامل داده‌هایی باشد که در ابتدای راه‌اندازی بلاکچین استفاده می‌شود. این داده‌ها می‌توانند شامل اطلاعات مربوط به حساب‌ها، مقدار اولیه کوین‌ها، و تنظیمات ماژول‌ها باشند.

مسیر فایل:

~/.cosmosd/config/genesis.json

در این فایل، شما باید داده‌های ژنزیس برای ماژول‌های جدید خود را اضافه کنید. برای نمونه، می‌توانید حساب‌های اولیه یا داده‌های دیگر ماژول را اضافه کنید.

{
  "app_state": {
    "mymodule": {
      "accounts": [
        {
          "address": "cosmos1xxxxxxxxx",
          "balance": "1000stake"
        }
      ]
    }
  }
}

۲. ساخت و راه‌اندازی گره

۲.۱. ساخت بلاکچین

برای ساخت بلاکچین خود، ابتدا باید پروژه را کامپایل کرده و فایل‌های اجرایی را ایجاد کنید. برای این کار از دستور زیر استفاده می‌کنیم:

# کامپایل بلاکچین
go build -o cosmosd .
۲.۲. راه‌اندازی گره

پس از کامپایل بلاکچین، می‌توانیم گره خود را راه‌اندازی کنیم. دستور زیر برای راه‌اندازی گره در بلاکچین سفارشی استفاده می‌شود:

# اجرای گره
./cosmosd start
۲.۳. همگام‌سازی و اتصال به شبکه

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

برای نظارت بر وضعیت گره و بررسی همگام‌سازی، می‌توانید از دستورات زیر استفاده کنید:

# بررسی وضعیت گره
./cosmosd status

۳. تعامل با ماژول از طریق CLI

پس از راه‌اندازی گره، شما می‌توانید از طریق Command-Line Interface (CLI) با ماژول خود تعامل کنید. برای این کار باید دستورات CLI را برای ارسال تراکنش‌ها، خواندن داده‌ها، و انجام عملیات‌های مختلف استفاده کنید.

۳.۱. ارسال تراکنش به ماژول

برای ارسال تراکنش به ماژول جدید خود، ابتدا باید پیامی از نوع MsgSend یا نوع دیگری که برای ماژول خود تعریف کرده‌اید، ایجاد کنید. به‌عنوان مثال، برای ارسال یک تراکنش از طریق CLI از دستور زیر استفاده می‌کنیم:

# ارسال تراکنش با استفاده از CLI
cosmosd tx mymodule send cosmos1xxxxxxxxx cosmos1yyyyyyyy 100stake --from=<your_account>
۳.۲. دریافت وضعیت ماژول

برای دریافت وضعیت یا اطلاعات از ماژول خود، می‌توانید از دستورات مشابه استفاده کنید. به‌عنوان مثال، برای مشاهده موجودی یک حساب خاص می‌توانید از دستور زیر استفاده کنید:

# دریافت اطلاعات حساب
cosmosd query mymodule balance cosmos1xxxxxxxxx

جمع‌بندی

راه‌اندازی Node برای اجرای ماژول جدید در Cosmos SDK شامل پیکربندی فایل‌های تنظیمات، کامپایل بلاکچین، و راه‌اندازی گره است. پس از راه‌اندازی، گره قادر به پردازش تراکنش‌ها و تعامل با شبکه بلاکچین خواهد بود. همچنین، CLI ابزار مناسبی برای ارسال تراکنش‌ها و دریافت اطلاعات از ماژول‌ها فراهم می‌کند. این فرایند به شما امکان می‌دهد تا ماژول‌های سفارشی خود را در بلاکچین Cosmos SDK اجرا کرده و با آن‌ها تعامل کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی عملکرد ماژول در شبکه آزمایشی” subtitle=”توضیحات کامل”]پس از پیاده‌سازی و راه‌اندازی ماژول جدید در بلاکچین مبتنی بر Cosmos SDK، مرحله بعدی بررسی عملکرد ماژول در شبکه آزمایشی (Testnet) است. این فرآیند به ما این امکان را می‌دهد که قبل از راه‌اندازی ماژول در شبکه اصلی (Mainnet)، از عملکرد صحیح آن اطمینان حاصل کنیم.

برای بررسی عملکرد ماژول در شبکه آزمایشی، باید به چند نکته کلیدی توجه کنیم: راه‌اندازی شبکه آزمایشی، ارسال تراکنش‌ها، بررسی لاگ‌ها، و نظارت بر گره‌ها و عملکرد ماژول.

۱. راه‌اندازی شبکه آزمایشی (Testnet)

۱.۱. پیکربندی شبکه آزمایشی

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

مسیر فایل‌ها:

  • ~/.cosmosd/config/config.toml
  • ~/.cosmosd/config/genesis.json
  • ~/.cosmosd/config/app.toml
۱.۲. ایجاد شبکه آزمایشی

برای ایجاد شبکه آزمایشی، ابتدا باید ژنسیس بلاک (genesis block) را تنظیم کنید. این فایل شامل داده‌های شبکه و اطلاعات ضروری برای راه‌اندازی شبکه است.

برای ایجاد شبکه آزمایشی، دستور زیر را استفاده می‌کنیم:

# ایجاد شبکه آزمایشی
cosmosd init my-testnet --chain-id=testnet

این دستور بلاکچین را با نام my-testnet و شناسه شبکه testnet راه‌اندازی می‌کند.

۱.۳. اضافه کردن گره‌ها به شبکه

برای اضافه کردن گره‌ها به شبکه آزمایشی، باید فایل‌های پیکربندی مربوط به گره‌ها را در مسیرهای مناسب قرار دهید. به‌عنوان مثال، باید فایل config.toml را برای هر گره تنظیم کنید و سپس گره‌ها را شروع کنید.

# اجرای گره‌ها در شبکه آزمایشی
cosmosd start --chain-id=testnet

۲. ارسال تراکنش‌ها در شبکه آزمایشی

برای ارزیابی عملکرد ماژول جدید در شبکه آزمایشی، باید تراکنش‌هایی را ارسال کرده و نتایج آن‌ها را بررسی کنیم. از این طریق می‌توانیم عملکرد ماژول را در شبکه آزمایشی تست کنیم.

۲.۱. ارسال تراکنش با استفاده از CLI

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

# ارسال تراکنش
cosmosd tx mymodule send cosmos1xxxxxxxxx cosmos1yyyyyyyy 100stake --from=validator1
۲.۲. بررسی وضعیت تراکنش‌ها

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

# بررسی وضعیت تراکنش
cosmosd query tx <transaction_hash>

این دستور وضعیت تراکنش ارسال شده را از شبکه آزمایشی استخراج کرده و در اختیار شما قرار می‌دهد.

۳. بررسی لاگ‌ها و گزارش‌ها

برای نظارت دقیق‌تر بر عملکرد ماژول، باید لاگ‌ها و گزارش‌های گره‌ها را بررسی کنیم. این گزارش‌ها اطلاعات دقیقی در مورد عملکرد ماژول، پردازش تراکنش‌ها، و خطاهای احتمالی به ما می‌دهند.

۳.۱. دسترسی به لاگ‌ها

لاگ‌های گره‌ها در مسیر /~/.cosmosd/data/logs/ ذخیره می‌شوند. برای مشاهده لاگ‌های گره، از دستور زیر استفاده می‌کنیم:

# مشاهده لاگ‌های گره
tail -f ~/.cosmosd/data/logs/cosmosd.log

این دستور لاگ‌های گره را به‌صورت زنده نمایش می‌دهد و به شما این امکان را می‌دهد که خطاها یا مشکلات در اجرای ماژول را شناسایی کنید.

۳.۲. بررسی گزارش‌های خطا

در صورت بروز مشکلات یا خطاها در شبکه آزمایشی، بررسی گزارش‌های خطا به ما کمک می‌کند تا علت بروز مشکل را شناسایی کنیم. برای مشاهده جزئیات بیشتر در خصوص خطاهای گره و ماژول، می‌توانید از ابزارهای debugging و profiling استفاده کنید.

۴. نظارت بر عملکرد شبکه آزمایشی

پس از ارسال تراکنش‌ها و بررسی لاگ‌ها، باید عملکرد کلی شبکه آزمایشی را نظارت کنیم. این کار شامل نظارت بر گره‌ها، تراکنش‌ها، و وضعیت بلاکچین است.

۴.۱. نظارت بر وضعیت گره‌ها

برای بررسی وضعیت گره‌ها در شبکه آزمایشی، از دستور زیر استفاده می‌کنیم:

# بررسی وضعیت گره‌ها
cosmosd status

این دستور وضعیت گره و وضعیت همگام‌سازی شبکه را نشان می‌دهد.

۴.۲. نظارت بر استفاده از منابع

نظارت بر استفاده از منابع سرور و گره‌ها (CPU، RAM، Disk) برای اطمینان از عملکرد بهینه شبکه آزمایشی بسیار مهم است. ابزارهایی مانند htop و iotop می‌توانند به شما کمک کنند تا مصرف منابع را در زمان واقعی مشاهده کنید.

# نظارت بر مصرف منابع
htop

جمع‌بندی

بررسی عملکرد ماژول در شبکه آزمایشی شامل پیکربندی و راه‌اندازی شبکه آزمایشی، ارسال تراکنش‌ها، بررسی لاگ‌ها، و نظارت بر وضعیت گره‌ها است. این فرآیند به شما کمک می‌کند تا مطمئن شوید که ماژول جدید به‌درستی کار می‌کند و هیچ خطایی در تراکنش‌ها یا پردازش‌ها وجود ندارد. پس از اطمینان از عملکرد صحیح ماژول در شبکه آزمایشی، می‌توانید به مراحل بعدی انتقال به شبکه اصلی (Mainnet) و راه‌اندازی بلاکچین با ماژول جدید بپردازید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 10. بهینه‌سازی و ارتقای ماژول‌های سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بهینه‌سازی عملکرد و کاهش مصرف منابع” subtitle=”توضیحات کامل”]در هر شبکه بلاکچین، به ویژه در بلاکچین‌های مبتنی بر Cosmos SDK، بهینه‌سازی عملکرد و کاهش مصرف منابع از جمله مهم‌ترین جنبه‌ها برای اطمینان از کارایی شبکه و گره‌ها است. این فرآیند می‌تواند شامل بهینه‌سازی کد، استفاده بهینه از منابع سرور، کاهش بار تراکنش‌ها، و بهینه‌سازی نحوه ارتباط میان گره‌ها و ماژول‌ها باشد.

در این بخش، روش‌ها و تکنیک‌های مختلف برای بهینه‌سازی عملکرد و کاهش مصرف منابع در شبکه‌های مبتنی بر Cosmos SDK مورد بررسی قرار می‌گیرد.

۱. بهینه‌سازی مصرف منابع سرور

۱.۱. استفاده از منابع سیستم

برای کاهش مصرف منابع سیستم (CPU، RAM و Disk)، اولین قدم این است که استفاده از منابع را نظارت کنیم و مشکلات را شناسایی کنیم. استفاده از ابزارهایی مانند htop و iotop به شما کمک می‌کند که میزان مصرف منابع را به‌صورت زنده مشاهده کنید.

# برای نظارت بر مصرف CPU و RAM
htop

# برای نظارت بر استفاده از دیسک
iotop

این ابزارها به شما کمک می‌کنند تا منابعی که بیشترین بار را دارند شناسایی کرده و اقدامات لازم برای بهینه‌سازی آن‌ها را انجام دهید.

۱.۲. بهینه‌سازی تنظیمات گره‌ها

برای بهینه‌سازی مصرف منابع گره‌ها، می‌توانید تنظیمات مختلفی را اعمال کنید که در مسیر فایل‌های پیکربندی در Cosmos SDK قرار دارند.

  1. بهینه‌سازی تنظیمات حافظه:
    • کاهش سایز حافظه کش (cache size) در فایل config.toml:
    [mempool]
    size = 10000
    

    این تنظیم موجب کاهش حافظه استفاده‌شده برای نگهداری تراکنش‌ها می‌شود و می‌تواند در محیط‌های با محدودیت منابع به کار آید.

  2. تنظیمات همگام‌سازی:
    • تغییر نوع همگام‌سازی گره به fast-sync یا block-sync برای کاهش مصرف منابع و زمان همگام‌سازی:
    [p2p]
    sync_mode = "fast-sync"
    
۱.۳. انتخاب مناسب سخت‌افزار

برای کاهش مصرف منابع، استفاده از سخت‌افزار مناسب نقش مهمی دارد. برای شبکه‌های آزمایشی یا حتی شبکه‌های اصلی (Mainnet)، انتخاب سرورهایی با پردازنده‌های قدرتمند و حافظه کافی ضروری است. به‌ویژه، انتخاب دیسک‌های SSD به جای HDD می‌تواند زمان خواندن و نوشتن را به‌طور قابل‌توجهی کاهش دهد.

۲. بهینه‌سازی عملکرد تراکنش‌ها

۲.۱. کاهش پیچیدگی تراکنش‌ها

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

۲.۲. استفاده از تراکنش‌های دسته‌ای

برای کاهش تعداد تراکنش‌های فردی و افزایش کارایی، می‌توان از Batch Transactions استفاده کرد. تراکنش‌های دسته‌ای به گره‌ها این امکان را می‌دهند که چندین تراکنش را به‌طور همزمان پردازش کنند.

برای ارسال تراکنش‌های دسته‌ای در Cosmos SDK، از دستور زیر می‌توانید استفاده کنید:

# ارسال تراکنش دسته‌ای
cosmosd tx batch send cosmos1xxxxxxxxx cosmos1yyyyyyyy 100stake --from=validator1

این کار می‌تواند تعداد تراکنش‌ها را به‌طور چشمگیری کاهش داده و بار روی گره‌ها و شبکه را کمتر کند.

۳. بهینه‌سازی کد ماژول

۳.۱. بهینه‌سازی منطق تجاری ماژول

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

  • حذف کدهای اضافی یا تکراری.
  • استفاده از الگوریتم‌های بهینه‌تر برای پردازش داده‌ها.
  • ذخیره‌سازی داده‌ها در پایگاه‌های داده به‌صورت بهینه (به‌عنوان مثال، استفاده از کش برای کاهش درخواست‌های تکراری).
۳.۲. استفاده از Lazy Loading

Lazy Loading تکنیکی است که در آن منابع فقط زمانی که به آن‌ها نیاز است بارگذاری می‌شوند، نه پیش از آن. این تکنیک می‌تواند به‌ویژه در سیستم‌های بزرگ و پیچیده کمک‌کننده باشد، زیرا بار اضافی را از دوش سیستم برمی‌دارد.

در Cosmos SDK، می‌توانید از ویژگی‌هایی مانند Lazy State Transitions برای جلوگیری از بارگذاری داده‌های غیرضروری استفاده کنید.

۴. بهینه‌سازی ارتباطات میان گره‌ها

۴.۱. کاهش تعداد ارتباطات غیرضروری

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

برای محدود کردن تعداد همسایگان (peers) در config.toml می‌توانید از تنظیمات زیر استفاده کنید:

[p2p]
max_num_inbound_peers = 20
max_num_outbound_peers = 20
۴.۲. استفاده از پروتکل‌های ارتباطی بهینه

استفاده از پروتکل‌های ارتباطی بهینه مانند gRPC و WebSockets می‌تواند موجب کاهش بار شبکه و افزایش سرعت انتقال داده‌ها شود. این پروتکل‌ها به‌طور گسترده‌ای برای کاهش تأخیر و مصرف منابع مورد استفاده قرار می‌گیرند.

۵. نظارت و تحلیل عملکرد

۵.۱. استفاده از ابزارهای نظارتی

برای بهینه‌سازی عملکرد به‌طور مداوم، نظارت بر عملکرد گره‌ها و شبکه از اهمیت ویژه‌ای برخوردار است. از ابزارهایی مانند Prometheus و Grafana برای نظارت بر سلامت و عملکرد شبکه می‌توان استفاده کرد.

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

۵.۲. تحلیل و گزارش‌گیری

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

جمع‌بندی

بهینه‌سازی عملکرد و کاهش مصرف منابع در شبکه‌های بلاکچینی مبتنی بر Cosmos SDK یک فرآیند پیچیده است که نیاز به تنظیمات دقیق و مدیریت هوشمند منابع دارد. از ابزارهای نظارتی، بهینه‌سازی کد، و استفاده از بهترین شیوه‌ها برای بهینه‌سازی شبکه می‌توان بهره برد. با استفاده از این تکنیک‌ها، می‌توان عملکرد شبکه را بهبود بخشید و مصرف منابع را کاهش داد، که در نهایت موجب کارایی بهتر و مقیاس‌پذیری بیشتر شبکه می‌شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اعمال تغییرات و ارتقا بدون ایجاد هارد فورک” subtitle=”توضیحات کامل”]در شبکه‌های بلاکچین مبتنی بر Cosmos SDK، یکی از اهداف مهم و چالش‌برانگیز، انجام ارتقاها و اعمال تغییرات به گونه‌ای است که بدون ایجاد هارد فورک (Hard Fork) بتوان شبکه را به نسخه‌های جدید ارتقا داد. هارد فورک‌ها معمولا نیاز به تغییرات عمده در پروتکل دارند و ممکن است باعث ناسازگاری میان نسخه‌های مختلف بلاکچین شوند. بنابراین، هدف در اینجا این است که تغییرات را بدون ایجاد هرگونه ناسازگاری در شبکه و بدون قطعیت‌هایی که از یک هارد فورک ناشی می‌شود، اعمال کنیم.

۱. ارتقاهای نرم‌افزاری (Soft Forks) در Cosmos SDK

۱.۱. تفاوت بین هارد فورک و سافت فورک
  • هارد فورک (Hard Fork): تغییراتی که باعث عدم تطابق نسخه‌های جدید با نسخه‌های قدیمی می‌شوند. به این معنی که پس از اعمال این تغییرات، گره‌های قدیمی قادر به اتصال و تعامل با شبکه جدید نخواهند بود.
  • سافت فورک (Soft Fork): تغییراتی که باعث ناسازگاری می‌شوند، اما همچنان گره‌های قدیمی می‌توانند به شبکه متصل شده و با گره‌های جدید تعامل داشته باشند. در این حالت، گره‌های قدیمی همچنان قادر به پردازش تراکنش‌ها هستند، اما ممکن است به ویژگی‌های جدید دسترسی نداشته باشند.

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

۱.۲. استفاده از سافت فورک در Cosmos SDK

در Cosmos SDK، می‌توان از قابلیت‌های خاصی برای اعمال تغییرات و ارتقا بدون ایجاد هارد فورک استفاده کرد. این اقدامات عبارتند از:

  1. تغییرات غیرقابل برگشت در پروتکل (Backward-compatible):
    • تغییراتی که باعث تغییر رفتار پروتکل نمی‌شوند یا به‌گونه‌ای طراحی می‌شوند که با گره‌های قدیمی سازگار باشند.
    • این تغییرات می‌توانند به‌صورت آپدیت‌هایی در کدهای ماژول‌ها، تغییرات در پیکربندی شبکه و اضافه کردن قابلیت‌های جدید به پروتکل‌ها باشند.
  2. استفاده از پیاده‌سازی‌های جدید با قابلیت افزونه:
    • ایجاد ویژگی‌های جدید در شبکه بدون نیاز به تغییرات عمده در پروتکل بلاکچین.
    • افزودن گزینه‌های جدید برای گره‌ها و کاربران بدون نیاز به تغییرات در اجماع شبکه.
۱.۳. استفاده از ارتقاهای دوره‌ای با به‌روزرسانی‌های امنیتی و عملکردی

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

برای این منظور، می‌توان از ابزارهایی که توسط Cosmos SDK ارائه شده‌اند، مانند Cosmos Hub استفاده کرد. این ابزارها به گره‌ها این امکان را می‌دهند که ارتقاها را به‌صورت امن و بدون ایجاد شکاف در شبکه اعمال کنند.

۲. استفاده از مکانیزم‌های Governance برای اعمال تغییرات

۲.۱. مفهوم Governance در Cosmos SDK

در Cosmos SDK، قابلیت Governance (حکمرانی) به کاربران و گره‌ها این امکان را می‌دهد که تصمیمات مهم شبکه را از طریق پیشنهاد و رای‌گیری اتخاذ کنند. این مکانیزم‌ها به گره‌ها این امکان را می‌دهند که ارتقاها، تغییرات پیکربندی و بهبودهای عملکردی را به‌طور غیرمستقیم و بدون ایجاد نیاز به هارد فورک اعمال کنند.

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

۲.۲. فرآیند پیشنهاد و تصویب تغییرات از طریق Governance
  1. پیشنهاد تغییرات:
    • کاربران یا گره‌ها پیشنهاداتی برای تغییرات پروتکل ارسال می‌کنند. این پیشنهادات می‌تواند شامل ارتقاهای امنیتی، بهبودهای عملکردی یا تغییرات پیکربندی باشند.
  2. رای‌گیری برای تغییرات:
    • پس از ارسال پیشنهاد، فرآیند رای‌گیری شروع می‌شود. گره‌ها و اعضای شبکه می‌توانند در مورد پیشنهاد رأی دهند و تغییرات موردنظر را تصویب کنند.
  3. اعمال تغییرات:
    • در صورت تصویب پیشنهاد، تغییرات به شبکه اعمال می‌شود و پس از مدتی، گره‌ها به نسخه جدید به‌طور خودکار ارتقا می‌یابند.

۳. تکنیک‌های مختلف برای ارتقا بدون هارد فورک

۳.۱. استفاده از قابلیت Versioning در ماژول‌ها

در Cosmos SDK، ماژول‌ها می‌توانند از سیستم versioning استفاده کنند تا تغییرات را بدون ایجاد مشکلات ناسازگاری با گره‌های قدیمی اعمال کنند. با استفاده از versioning، می‌توانید نسخه‌های مختلفی از یک ماژول را در شبکه پشتیبانی کنید و گره‌ها می‌توانند به‌طور تدریجی به نسخه‌های جدید ارتقا یابند.

۳.۲. استفاده از شرایط سازگاری در کد

گاهی اوقات ممکن است نیاز باشد که تغییرات در کد به‌طور خاص به گونه‌ای انجام شوند که با نسخه‌های قدیمی سازگار باشند. برای این منظور، می‌توان از شرایط سازگاری در کد (Compatibility conditions) استفاده کرد تا تراکنش‌ها و درخواست‌ها از گره‌های قدیمی همچنان قابل پردازش باشند.

۴. اعمال تغییرات و ارتقا بدون ایجاد هارد فورک در Cosmos SDK

۴.۱. اعمال ارتقاهای بهبود عملکرد و امنیت

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

  1. پیشنهاد به‌روزرسانی یا تغییرات از طریق Governance.
  2. رای‌گیری و تصویب پیشنهاد.
  3. اعمال تغییرات با حفظ سازگاری نسخه‌ها و استفاده از versioning.
۴.۲. استفاده از آپدیت‌های شباهت‌پذیر (Backward-compatible Updates)

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

جمع‌بندی

اعمال تغییرات و ارتقا در شبکه‌های مبتنی بر Cosmos SDK بدون ایجاد هارد فورک، مستلزم رعایت اصول و فرآیندهای خاص است. استفاده از مکانیزم‌های Governance، versioning و انجام ارتقاهای تدریجی به شبکه کمک می‌کند تا تغییرات بدون ایجاد مشکلات ناشی از هارد فورک به شبکه اعمال شوند. این فرآیندها نه‌تنها از سازگاری شبکه با نسخه‌های قدیمی‌تر حفظ می‌کند، بلکه به گره‌ها و کاربران اجازه می‌دهد که به‌طور پیوسته و بدون مشکلات به نسخه‌های جدیدتر منتقل شوند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت نسخه‌بندی و مهاجرت ماژول‌ها” subtitle=”توضیحات کامل”]در بلاکچین‌های مبتنی بر Cosmos SDK، مدیریت نسخه‌بندی و مهاجرت ماژول‌ها نقش بسیار مهمی در بهبود و توسعه بلاکچین‌های سفارشی ایفا می‌کند. تغییرات و به‌روزرسانی‌های ماژول‌ها ممکن است شامل افزودن ویژگی‌های جدید، رفع اشکالات، بهبود عملکرد و سازگاری با سایر ماژول‌ها باشد. در این راستا، مدیریت نسخه‌بندی صحیح و پیاده‌سازی فرآیند مهاجرت برای اطمینان از حفظ سازگاری و عملکرد درست بلاکچین ضروری است.

۱. مفهوم نسخه‌بندی در Cosmos SDK

نسخه‌بندی (Versioning) به فرآیند مدیریت و پیگیری تغییرات در کدهای ماژول‌ها گفته می‌شود. این تغییرات ممکن است شامل اصلاحات، ارتقاها یا تغییرات اساسی در رفتار ماژول‌ها باشد. در Cosmos SDK، نسخه‌بندی به ما این امکان را می‌دهد که:

  1. تغییرات جدید را معرفی کنیم بدون اینکه سازگاری با نسخه‌های قدیمی‌تر شکسته شود.
  2. فرآیندهای مهاجرتی برای انتقال داده‌ها و ساختارهای مختلف از نسخه‌های قدیمی به جدید به‌صورت امن و موثر انجام شود.
  3. تراکنش‌ها و داده‌های قدیمی بدون اختلال در شبکه پردازش شوند.

۲. نسخه‌بندی ماژول‌ها در Cosmos SDK

برای مدیریت نسخه‌بندی ماژول‌ها در Cosmos SDK، از چندین روش و تکنیک استفاده می‌شود. این تکنیک‌ها به گره‌ها و کاربران کمک می‌کنند تا تغییرات را به‌صورت همزمان پیاده‌سازی و مدیریت کنند.

۲.۱. استفاده از سیستم نسخه‌بندی برای ماژول‌ها

Cosmos SDK به شما این امکان را می‌دهد که ماژول‌ها را بر اساس نسخه‌ها مدیریت کنید. برای هر تغییر در ساختار داده‌ها یا عملکرد، یک نسخه جدید از ماژول ایجاد می‌شود. این نسخه‌ها به‌صورت معمولا از اعداد ترتیبی مانند v0.1, v0.2 و … برای شناسایی نسخه‌های مختلف ماژول‌ها استفاده می‌کنند.

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

۲.۲. پیاده‌سازی نگهداری سازگاری برای نسخه‌های مختلف

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

۲.۳. تغییرات غیرمخرب و ارتقاهای تدریجی

در Cosmos SDK، تغییرات غیرمخرب برای پیاده‌سازی ارتقاهای جدید ضروری است. به این معنی که تغییرات باید به‌گونه‌ای طراحی شوند که با نسخه‌های قدیمی‌تر سازگار باشند، یا اینکه تغییرات به‌صورت افزایشی و تدریجی در نظر گرفته شوند. این کار باعث می‌شود که ارتقاها و تغییرات بدون اینکه بر کاربران و گره‌ها تاثیر منفی بگذارند، انجام شوند.

۳. مهاجرت داده‌ها و ساختارها

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

۳.۱. ساختار داده‌ها و پروتکل‌های سازگار با نسخه‌ها

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

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

۳.۲. اسکریپت‌های مهاجرت در Cosmos SDK

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

برای مثال، یک اسکریپت مهاجرت می‌تواند به‌صورت زیر باشد:

func Migrate(ctx sdk.Context, storeKey sdk.StoreKey) error {
    // دریافت داده‌ها از نسخه قدیمی
    oldData := getOldData(storeKey)
    
    // انجام تغییرات مورد نیاز در داده‌ها
    newData := transformData(oldData)
    
    // ذخیره داده‌های به‌روز شده در ساختار جدید
    saveNewData(storeKey, newData)
    
    return nil
}

این اسکریپت به‌طور خودکار در زمان ارتقا اجرا می‌شود تا داده‌ها از نسخه قدیمی به نسخه جدید مهاجرت کنند.

۴. مدیریت نسخه‌های ماژول‌ها در عملیات شبکه

۴.۱. مدیریت فرآیند ارتقا و استفاده از Governance

در Cosmos SDK، ارتقا ماژول‌ها می‌تواند از طریق Governance (حکمرانی) انجام شود. به این معنی که هر تغییر یا ارتقای جدید در ماژول‌ها می‌تواند از طریق فرآیند رای‌گیری در شبکه تصویب شود. این فرآیند کمک می‌کند تا از ایجاد مشکلات در هنگام ارتقا و تغییرات جلوگیری شود.

برای این کار، ابتدا پیشنهاد تغییرات در قالب یک Proposal (پیشنهاد) به شبکه ارسال می‌شود، سپس کاربران و گره‌ها در مورد آن رای می‌دهند. در صورت تصویب، ارتقا به‌طور خودکار اعمال می‌شود.

// ارسال پیشنهاد ارتقا از طریق فرآیند Governance
proposal := types.NewUpgradeProposal("Upgrade Proposal", "Update Module v2.0", newModuleVersion)
۴.۲. بررسی نسخه‌های مختلف در شبکه

در هنگام به‌روزرسانی یا ارتقا ماژول‌ها، باید نسخه‌های مختلف را در شبکه بررسی و مدیریت کنیم. این کار با استفاده از ابزارهای بررسی و تایید نسخه‌ها انجام می‌شود که کمک می‌کند تا از بروز هرگونه اختلال در شبکه جلوگیری شود.

جمع‌بندی

مدیریت نسخه‌بندی و مهاجرت ماژول‌ها در Cosmos SDK بخش مهمی از فرآیند توسعه بلاکچین‌های سفارشی است. با استفاده از تکنیک‌های versioning، migration و Governance، می‌توان ارتقاهای ماژول‌ها را بدون ایجاد اختلال در شبکه و داده‌ها انجام داد. این فرآیندها به حفظ سازگاری با نسخه‌های قدیمی‌تر و ارتقا به‌طور تدریجی و بدون مشکل کمک می‌کنند.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش ۴: آشنایی با Polkadot Substrate و نصب محیط توسعه”][cdb_course_lesson title=”فصل 1. مقدمه‌ای بر Substrate و ویژگی‌های کلیدی آن”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”Substrate چیست و چه کاربردهایی دارد؟” subtitle=”توضیحات کامل”]Substrate یک فریم‌ورک توسعه بلاکچین است که توسط تیم Parity Technologies ایجاد شده است. این فریم‌ورک به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی و قابل تغییر بسازند، بدون اینکه نیاز به ساخت از صفر باشند. Substrate به‌طور ویژه برای پشتیبانی از ساختارهای بلاکچین چندلایه طراحی شده است و از ویژگی‌های مقیاس‌پذیری بالا و انعطاف‌پذیری در طراحی برخوردار است.

درواقع، Substrate به‌عنوان یک ابزار توسعه، به‌طور مستقیم پلتفرم ساخت بلاکچین‌ها را ساده‌تر می‌کند. این فریم‌ورک شامل ماژول‌های مختلفی است که می‌تواند به‌صورت انتخابی به بلاکچین اضافه شوند. هر بلاکچینی که با استفاده از Substrate ساخته می‌شود، به‌طور پیش‌فرض از تکنولوژی WebAssembly (Wasm) پشتیبانی می‌کند که امکان اجرای کدهای نوشته‌شده به‌طور cross-platform را فراهم می‌کند.


کاربردهای Substrate

  1. ایجاد بلاکچین‌های سفارشی: Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های سفارشی بسازند و ویژگی‌های خاص مورد نظر خود را پیاده‌سازی کنند. این امکان را با استفاده از ماژول‌های از پیش ساخته‌شده فراهم می‌کند که می‌توانند برای نیازهای مختلف استفاده شوند.
  2. ساخت بلاکچین‌های مستقل یا متصل به یک اکوسیستم: Substrate به شما این امکان را می‌دهد که بلاکچین‌هایی بسازید که مستقل از شبکه‌های دیگر عمل کنند یا به‌طور مستقیم به شبکه‌های دیگر مانند Polkadot متصل شوند.
  3. پشتیبانی از سیستم‌های مقیاس‌پذیر: Substrate به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های مقیاس‌پذیر با توان پردازشی بالا بسازند. از جمله ویژگی‌های آن می‌توان به قابلیت‌های پشتیبانی از شبکه‌های متصل، مانند Polkadot و Kusama، اشاره کرد که برای بهبود مقیاس‌پذیری طراحی شده‌اند.
  4. ماژول‌های قابل تغییر و به‌روز رسانی: در Substrate، ماژول‌ها به‌راحتی قابل تغییر و به‌روزرسانی هستند، بدون اینکه بلاکچین نیاز به انجام هاردفورک داشته باشد. این ویژگی به‌طور ویژه برای توسعه‌دهندگان جذاب است زیرا می‌توانند بدون نگرانی از شکاف در سیستم، ویژگی‌های جدیدی به بلاکچین‌های خود اضافه کنند.
  5. پشتیبانی از ویژگی‌های امنیتی پیشرفته: یکی از ویژگی‌های مهم Substrate، سیستم امنیتی آن است که اجازه می‌دهد تا از الگوریتم‌های مختلف امنیتی (مثل اثبات کار یا اثبات سهام) استفاده کنید تا امنیت بلاکچین خود را تضمین کنید.

ماژول‌های موجود در Substrate

  1. Consensus Modules (ماژول‌های اجماع): Substrate امکان انتخاب الگوریتم‌های اجماع مختلفی مانند Proof of Work (PoW)، Proof of Stake (PoS) یا Nominated Proof of Stake (NPoS) را فراهم می‌کند.
  2. Runtime Modules (ماژول‌های رانتایم): این ماژول‌ها برای اجرای منطق تجاری و وظایف خاص بلاکچین طراحی شده‌اند. به‌عنوان‌مثال، ماژول‌هایی برای تراکنش‌ها، سیستم‌های پرداخت، یا ذخیره‌سازی داده‌ها وجود دارند.
  3. Networking Modules (ماژول‌های شبکه): Substrate از پروتکل‌های شبکه برای ارتباط بین گره‌ها و سایر شبکه‌ها پشتیبانی می‌کند. این پروتکل‌ها به توسعه‌دهندگان این امکان را می‌دهند که از سیستم‌های توزیع‌شده و مقیاس‌پذیر استفاده کنند.
  4. Storage Modules (ماژول‌های ذخیره‌سازی): Substrate به‌طور پیش‌فرض از ذخیره‌سازی داده‌ها به‌صورت آنلاین و آفلاین پشتیبانی می‌کند. همچنین با استفاده از ماژول‌های ذخیره‌سازی می‌توانید داده‌های غیرقابل تغییر را در بلاکچین خود ذخیره کنید.

جمع‌بندی

Substrate یک فریم‌ورک بسیار قدرتمند و انعطاف‌پذیر برای ساخت بلاکچین‌های سفارشی است که به توسعه‌دهندگان این امکان را می‌دهد تا بلاکچین‌های خود را با قابلیت‌های مختلف و ویژگی‌های امنیتی قابل تنظیم بسازند. این فریم‌ورک نه تنها برای توسعه بلاکچین‌های مستقل بلکه برای ارتباط و تعامل بین بلاکچین‌ها نیز مناسب است. با استفاده از Substrate می‌توان به‌راحتی بلاکچین‌هایی مقیاس‌پذیر و امن با ویژگی‌های پیشرفته ساخت و به‌روز رسانی کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تفاوت Substrate با Cosmos SDK و سایر فریمورک‌های بلاکچین” subtitle=”توضیحات کامل”]در دنیای بلاکچین، چندین فریم‌ورک برای ساخت بلاکچین‌های سفارشی و مقیاس‌پذیر وجود دارد. از میان معروف‌ترین این فریم‌ورک‌ها می‌توان به Substrate، Cosmos SDK و چندین فریم‌ورک دیگر اشاره کرد. هرکدام از این فریم‌ورک‌ها ویژگی‌ها و مزایای خاص خود را دارند که برای پروژه‌های خاص مورد استفاده قرار می‌گیرند. در این بخش، تفاوت‌های کلیدی بین Substrate و Cosmos SDK را بررسی خواهیم کرد.


Substrate

Substrate فریم‌ورکی برای ساخت بلاکچین‌های سفارشی است که توسط تیم Parity Technologies توسعه یافته است. این فریم‌ورک به‌طور ویژه برای توسعه بلاکچین‌هایی با قابلیت‌های مختلف طراحی شده است و ویژگی‌های زیادی را ارائه می‌دهد که از جمله آن‌ها می‌توان به پشتیبانی از سیستم‌های اجماع متنوع، مقیاس‌پذیری و انعطاف‌پذیری بالا اشاره کرد. از ویژگی‌های برجسته Substrate می‌توان به موارد زیر اشاره کرد:

  1. ساخت بلاکچین‌های سفارشی با ویژگی‌های خاص: توسعه‌دهندگان می‌توانند بلاکچین‌های خود را با ویژگی‌ها و الگوریتم‌های خاص خود طراحی کنند.
  2. پشتیبانی از WebAssembly (Wasm): Substrate از WASM برای اجرای کدهای خود استفاده می‌کند که به‌طور cross-platform قابل اجرا هستند.
  3. ماژول‌های متعدد و قابل تغییر: Substrate ماژول‌های زیادی دارد که به‌راحتی قابل تغییر و سفارشی‌سازی هستند. این ماژول‌ها برای انجام وظایف مختلف مانند اجماع، ذخیره‌سازی، و تراکنش‌ها طراحی شده‌اند.
  4. امنیت بالا: Substrate از الگوریتم‌های مختلف امنیتی، مانند اثبات سهام (PoS) و اثبات کار (PoW)، پشتیبانی می‌کند.
  5. پشتیبانی از شبکه‌های متصل: Substrate می‌تواند به‌راحتی به شبکه‌های دیگر مانند Polkadot متصل شود و از آن‌ها بهره ببرد.

Cosmos SDK

Cosmos SDK فریم‌ورکی است که توسط بنیاد Cosmos توسعه یافته و هدف آن ایجاد یک اکوسیستم بلاکچین‌های مستقل است که بتوانند به‌طور آزادانه با یکدیگر ارتباط برقرار کنند. این فریم‌ورک برای توسعه بلاکچین‌های مقیاس‌پذیر و با عملکرد بالا طراحی شده است و از ویژگی‌های زیر برخوردار است:

  1. ساخت بلاکچین‌های مستقل با قابلیت ارتباط: Cosmos SDK به شما این امکان را می‌دهد که بلاکچین‌های مستقل بسازید که می‌توانند از طریق پروتکل IBC (Inter-Blockchain Communication) با یکدیگر ارتباط برقرار کنند.
  2. ماژول‌های آماده: Cosmos SDK مجموعه‌ای از ماژول‌های آماده برای ساخت بلاکچین‌هایی با ویژگی‌های مختلف، مانند الگوریتم اجماع، سیستم‌های رای‌دهی و توکن‌ها، فراهم می‌کند.
  3. پشتیبانی از الگوریتم اجماع Tendermint: Cosmos SDK به‌طور پیش‌فرض از الگوریتم اجماع Tendermint استفاده می‌کند که ویژگی‌های سریع، مقیاس‌پذیر و امن دارد.
  4. تمرکز بر روی امنیت و مقیاس‌پذیری: Cosmos SDK روی مقیاس‌پذیری و امنیت تمرکز دارد و از سیستم‌های تقسیم کار به‌صورت مستقل پشتیبانی می‌کند.
  5. ارتباط میان بلاکچین‌ها: یکی از ویژگی‌های برجسته Cosmos، پروتکل IBC است که ارتباط میان بلاکچین‌ها را ساده می‌کند.

تفاوت‌های اصلی بین Substrate و Cosmos SDK

  1. ساختار و طراحی:
    • Substrate: تمرکز اصلی Substrate بر روی ساخت بلاکچین‌های سفارشی با ویژگی‌های قابل تغییر است. توسعه‌دهندگان می‌توانند بلاکچین‌هایی با اجزای مختلف بسازند و از انواع مختلف الگوریتم‌های اجماع استفاده کنند.
    • Cosmos SDK: این فریم‌ورک بیشتر به‌عنوان ابزاری برای ساخت بلاکچین‌های مستقل و متصل به‌یکدیگر شناخته می‌شود. Cosmos از پروتکل IBC برای ارتباط بلاکچین‌ها بهره می‌برد و بر ایجاد یک اکوسیستم از بلاکچین‌های مستقل تمرکز دارد.
  2. اجماع:
    • Substrate: از انواع الگوریتم‌های اجماع پشتیبانی می‌کند، از جمله PoW، PoS، NPoS، و دیگر الگوریتم‌های خاص.
    • Cosmos SDK: از الگوریتم اجماع Tendermint استفاده می‌کند که برای سرعت و امنیت طراحی شده است و به‌طور خاص برای بلاکچین‌های مستقل مناسب است.
  3. مدل بلاکچین:
    • Substrate: به توسعه‌دهندگان این امکان را می‌دهد که بلاکچین‌های بسیار سفارشی بسازند و ویژگی‌هایی مانند WebAssembly را برای مقیاس‌پذیری و انعطاف‌پذیری بیشتر ارائه دهد.
    • Cosmos SDK: بیشتر بر ساخت بلاکچین‌های مستقل و قابلیت ارتباط بین آن‌ها تمرکز دارد.
  4. پشتیبانی از شبکه‌های متصل:
    • Substrate: به‌طور طبیعی از شبکه‌های متصل مانند Polkadot پشتیبانی می‌کند.
    • Cosmos SDK: از پروتکل IBC برای ارتباط میان بلاکچین‌ها استفاده می‌کند.

دستورات CLI و مسیر فایل‌ها

در هر دو فریم‌ورک Substrate و Cosmos SDK، برای توسعه بلاکچین‌های سفارشی، از دستورات CLI استفاده می‌شود. برای مثال:

  1. Substrate: برای شروع یک پروژه Substrate، می‌توانید از دستور زیر استفاده کنید:
    cargo new --bin my-substrate-blockchain
    cd my-substrate-blockchain
    substrate-node-template
    

    مسیر فایل‌ها: فایل‌های مربوط به پروژه Substrate در دایرکتوری ایجاد شده قرار دارند. به‌طور معمول، این پروژه‌ها در مسیر src و Cargo.toml قرار می‌گیرند.

  2. Cosmos SDK: برای ایجاد یک بلاکچین با استفاده از Cosmos SDK، می‌توانید از دستور زیر استفاده کنید:
    cosmos-sdk init my-cosmos-chain
    cd my-cosmos-chain
    

    مسیر فایل‌ها: فایل‌های پروژه Cosmos SDK در مسیر my-cosmos-chain ایجاد می‌شوند و فایل‌های پیکربندی در دایرکتوری config قرار دارند.


جمع‌بندی

در نهایت، انتخاب بین Substrate و Cosmos SDK بستگی به نیازهای پروژه دارد. اگر هدف شما ساخت بلاکچین‌های سفارشی با ویژگی‌های خاص و مقیاس‌پذیری بالا است، Substrate انتخاب مناسبی است. اما اگر به دنبال ساخت بلاکچین‌های مستقل با قابلیت ارتباط بین آن‌ها و استفاده از الگوریتم اجماع Tendermint هستید، Cosmos SDK گزینه بهتری خواهد بود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی معماری و اجزای Substrate (Runtime، FRAME، Pallets، Off-chain Workers)” subtitle=”توضیحات کامل”]Substrate فریم‌ورکی است که برای ساخت بلاکچین‌های سفارشی توسعه داده شده است. این فریم‌ورک از معماری مدولار بهره می‌برد که به‌طور خاص برای ایجاد بلاکچین‌هایی با ویژگی‌های سفارشی طراحی شده است. اجزای اصلی معماری Substrate شامل مواردی همچون Runtime، FRAME، Pallets و Off-chain Workers است. در این بخش، به بررسی هرکدام از این اجزا خواهیم پرداخت و همچنین تنظیمات و کدهای لازم برای استفاده از آن‌ها را توضیح خواهیم داد.


Runtime

Runtime هسته اصلی بلاکچین در Substrate است. این بخش شامل تمام منطق و رفتار بلاکچین از جمله اعتبارسنجی تراکنش‌ها، اجرای قراردادهای هوشمند و تعامل با ذخیره‌سازی است. در واقع، Runtime به‌عنوان یک برنامه ویژه در شبکه بلاکچین عمل می‌کند که در هر بلاک اجرا می‌شود.

Runtime در Substrate از WebAssembly (Wasm) برای اجرا استفاده می‌کند که قابلیت انتقال و مقیاس‌پذیری بالایی را فراهم می‌آورد. کد runtime به‌طور مستقیم به‌وسیله‌ فریم‌ورک FRAME نوشته می‌شود که در ادامه به توضیح آن خواهیم پرداخت.

مسیر فایل‌های مربوط به Runtime در پروژه Substrate معمولاً در دایرکتوری runtime/ قرار دارد.

دستور CLI برای ایجاد Runtime:

cargo build --release

این دستور باعث ساخت و کامپایل کردن پروژه به‌صورت Release می‌شود.


FRAME

FRAME یک فریم‌ورک درون Substrate است که ابزارهای لازم برای ساخت بلاکچین‌ها و افزودن ماژول‌های مختلف را فراهم می‌کند. این فریم‌ورک اجزای مختلفی مانند Pallets، Runtime، و Off-chain Workers را در یک بسته منظم و قابل استفاده قرار می‌دهد. هدف اصلی FRAME ساده‌سازی فرآیند توسعه بلاکچین‌های سفارشی است.

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

دستور CLI برای استفاده از FRAME:

برای استفاده از FRAME، ابتدا نیاز دارید تا یک پروژه جدید ایجاد کنید و سپس از ماژول‌های موجود در FRAME استفاده کنید.

cargo new --bin my-frame-blockchain
cd my-frame-blockchain
substrate-node-template

مسیر فایل‌ها: کدهای مربوط به FRAME در دایرکتوری frame/ و فایل‌های پیکربندی در runtime/ قرار دارند.


Pallets

Pallets اجزای اصلی در Substrate هستند که ویژگی‌ها و عملکردهای خاص بلاکچین را پیاده‌سازی می‌کنند. هر Pallet یک بخش مستقل است که می‌تواند برای انجام یک وظیفه خاص مانند مدیریت دارایی‌ها، انجام تراکنش‌ها یا مدیریت حاکمیت استفاده شود. Pallets از ویژگی‌هایی مانند Storage، Call، و Event برای تعامل با داده‌ها و پیاده‌سازی منطق بلاکچین استفاده می‌کنند.

Pallet‌ها می‌توانند به‌راحتی توسط توسعه‌دهندگان به بلاکچین‌های جدید افزوده شوند و به‌این‌ترتیب ویژگی‌های جدیدی را به سیستم اضافه کنند.

دستور CLI برای استفاده از Pallet:

برای ایجاد یک Pallet جدید در پروژه Substrate، ابتدا باید دستور زیر را اجرا کنید:

cargo add pallet-template

مسیر فایل‌ها: پس از اضافه کردن Pallet جدید، کد آن در دایرکتوری pallets/ قرار می‌گیرد و فایل‌های پیکربندی در runtime/ تنظیم می‌شوند.


Off-chain Workers

Off-chain Workers یا “کارگران خارج از زنجیره” به اجزای خاصی اطلاق می‌شود که به شما این امکان را می‌دهند که محاسبات و فرآیندهایی را که نیاز به داده‌های خارج از زنجیره دارند، انجام دهید. این فرآیندها می‌توانند شامل درخواست به API‌ها، پردازش داده‌های خارجی، یا انجام محاسبات پیچیده‌ای باشند که انجام آن‌ها در زنجیره هزینه‌بر خواهد بود.

Off-chain Workers به‌طور خودکار اجرا نمی‌شوند و باید به‌طور دستی توسط توسعه‌دهندگان فعال شوند. این ویژگی مخصوصاً برای انجام کارهایی مانند تأسیس داده‌های اوراکل و به‌روزرسانی وضعیت‌های خارج از زنجیره به‌طور مؤثر مفید است.

دستور CLI برای استفاده از Off-chain Workers:

برای اضافه کردن Off-chain Worker به یک Pallet در پروژه، باید کد زیر را به فایل Pallet مربوطه اضافه کنید:

pub struct OffchainWorker<T: Config> {
    pub data: Option<T::OffchainData>,
}

impl<T: Config> OffchainWorker<T> {
    fn perform_offchain_work() -> Result<(), &'static str> {
        // اجرای کارهای خارج از زنجیره
        Ok(())
    }
}

مسیر فایل‌ها: کدهای مربوط به Off-chain Workers باید در داخل هر Pallet و در مسیر pallets/ قرار گیرند.


جمع‌بندی

معماری Substrate شامل اجزای مختلفی است که هرکدام وظیفه خاصی در فرآیند توسعه بلاکچین‌های سفارشی دارند. Runtime به‌عنوان هسته مرکزی بلاکچین، FRAME به‌عنوان فریم‌ورک اصلی برای توسعه، Pallets برای افزودن ویژگی‌های مختلف، و Off-chain Workers برای انجام کارهای خارج از زنجیره طراحی شده‌اند. این اجزا با استفاده از دستورات CLI و در مسیرهای خاص خود در پروژه قابل استفاده و پیکربندی هستند تا به شما کمک کنند بلاکچین‌های سفارشی خود را بسازید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی Substrate Node Template و عملکرد آن” subtitle=”توضیحات کامل”]Substrate Node Template یک پروژه پایه است که برای ساخت بلاکچین‌های سفارشی با استفاده از فریم‌ورک Substrate ارائه شده است. این تمپلیت شامل تمام اجزای مورد نیاز برای راه‌اندازی و توسعه یک بلاکچین ساده می‌باشد و به‌عنوان نقطه شروع برای پروژه‌های بلاکچین جدید استفاده می‌شود. در این بخش، به معرفی Substrate Node Template و نحوه عملکرد آن پرداخته می‌شود.


Substrate Node Template چیست؟

Substrate Node Template یک پروژه آماده است که به‌طور پیش‌فرض شامل پیکربندی‌های ابتدایی برای ایجاد یک بلاکچین می‌باشد. این تمپلیت به شما این امکان را می‌دهد که بدون نیاز به نوشتن کدهای پایه‌ای برای راه‌اندازی شبکه بلاکچین، سریعاً به توسعه ویژگی‌های سفارشی و افزودن Pallet‌های جدید بپردازید.

این تمپلیت معمولاً شامل ویژگی‌های زیر است:

  • یک Node (گره) که به‌صورت کامل برای اتصال به شبکه بلاکچین تنظیم شده است.
  • یک Runtime که منطق بلاکچین را پیاده‌سازی می‌کند.
  • Pallet‌های اولیه برای استفاده در بلاکچین.
  • ابزارهایی برای اجرای بلاکچین در حالت‌های مختلف (برای توسعه و تست).

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


عملکرد Substrate Node Template

Substrate Node Template به‌گونه‌ای طراحی شده است که شما به‌عنوان توسعه‌دهنده می‌توانید در کوتاه‌ترین زمان ممکن یک بلاکچین ساده راه‌اندازی کنید. در این بخش، عملکرد کلی آن توضیح داده می‌شود:

  1. راه‌اندازی گره‌ها: گره‌های بلاکچین را با استفاده از دستور cargo run می‌توانید راه‌اندازی کنید. این گره‌ها به‌طور خودکار به یک شبکه بلاکچین متصل شده و به تعامل با دیگر گره‌ها و انجام تراکنش‌ها می‌پردازند.
  2. Runtime: همان‌طور که قبلاً گفته شد، Runtime هسته اصلی بلاکچین است که تمام منطق‌ها و قواعد اجرای تراکنش‌ها را در خود جای می‌دهد. این Runtime از WebAssembly (Wasm) برای اجرا استفاده می‌کند.
  3. پیکربندی شبکه: تمپلیت به‌صورت پیش‌فرض با پیکربندی‌هایی برای ایجاد یک شبکه بلاکچین ساده تنظیم شده است. شما می‌توانید تنظیمات مربوط به اجماع، اعتبارسنجی‌ها و دیگر ویژگی‌ها را بر اساس نیاز خود تغییر دهید.
  4. Pallet‌های پیش‌فرض: این تمپلیت شامل Pallet‌های اولیه است که برای انجام کارهای پایه مانند مدیریت حساب‌ها، انتقال دارایی‌ها، و ذخیره‌سازی داده‌ها استفاده می‌شوند. شما می‌توانید Pallet‌های اضافی را برای افزودن ویژگی‌های خاص به بلاکچین خود اضافه کنید.

راه‌اندازی و استفاده از Substrate Node Template

برای استفاده از Substrate Node Template، ابتدا باید چند مرحله را انجام دهید. در ادامه، نحوه راه‌اندازی آن را گام‌به‌گام توضیح می‌دهیم:

  1. ایجاد پروژه جدید Substrate Node Templateابتدا باید یک پروژه جدید با استفاده از تمپلیت Substrate Node Template ایجاد کنید. دستور زیر را برای ایجاد پروژه جدید اجرا کنید:
    substrate-node-new my-blockchain
    cd my-blockchain
    

    این دستور یک پروژه جدید به نام my-blockchain ایجاد کرده و به دایرکتوری آن می‌رود.

  2. کامپایل کردن و ساخت بلاکچینبعد از ایجاد پروژه، برای کامپایل و ساخت بلاکچین، از دستور زیر استفاده کنید:
    cargo build --release
    

    این دستور پروژه را کامپایل کرده و نسخه‌ی Release آن را آماده اجرا می‌کند.

  3. اجرای بلاکچینحالا می‌توانید بلاکچین خود را اجرا کنید. از دستور زیر برای راه‌اندازی گره‌ها استفاده کنید:
    ./target/release/node-template --dev
    

    این دستور گره بلاکچین را در حالت توسعه (--dev) اجرا می‌کند که به‌طور پیش‌فرض به یک شبکه خصوصی متصل می‌شود و به شما امکان می‌دهد به‌سرعت تراکنش‌ها و ویژگی‌های مختلف را تست کنید.

  4. اتصال به گره و تعامل با بلاکچینپس از راه‌اندازی گره، شما می‌توانید از رابط‌های مختلف برای تعامل با بلاکچین استفاده کنید. برای مثال، از Polkadot-JS Apps برای مشاهده وضعیت بلاکچین و ارسال تراکنش‌ها استفاده کنید.

مسیر فایل‌های پروژه

  • runtime/: کدهای مربوط به Runtime در این دایرکتوری قرار دارند. در اینجا منطق اصلی بلاکچین پیاده‌سازی می‌شود.
  • node/: در این دایرکتوری، تنظیمات و پیکربندی‌های مربوط به گره‌ها قرار دارند.
  • pallets/: کدهای مربوط به Pallet‌های مختلف که به بلاکچین ویژگی‌های جدید اضافه می‌کنند.

جمع‌بندی

Substrate Node Template یک راهکار بسیار مناسب برای شروع پروژه‌های بلاکچین سفارشی است. با استفاده از این تمپلیت، شما می‌توانید به‌سرعت یک بلاکچین ساده را راه‌اندازی کنید و آن را گسترش دهید. این تمپلیت شامل تمام اجزای پایه‌ای مانند Runtime، گره‌ها، و Pallet‌های ابتدایی است که به شما این امکان را می‌دهد تا بلاکچین خود را بدون نیاز به نوشتن کدهای ابتدایی و پایه‌ای ایجاد کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. نصب و راه‌اندازی محیط توسعه برای Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیش‌نیازهای سخت‌افزاری و نرم‌افزاری” subtitle=”توضیحات کامل”]برای شروع توسعه با Substrate، باید یک محیط توسعه کامل نصب و پیکربندی کنید که شامل پیش‌نیازهای سخت‌افزاری و نرم‌افزاری است. در این بخش به تشریح این پیش‌نیازها و مراحل نصب و پیکربندی محیط توسعه می‌پردازیم.


پیش‌نیازهای سخت‌افزاری

برای توسعه با Substrate، سیستم شما باید حداقل ویژگی‌های سخت‌افزاری زیر را داشته باشد:

  1. پردازنده (CPU):
    • حداقل یک پردازنده دو هسته‌ای (Dual-core).
    • توصیه‌شده: پردازنده‌های چهار هسته‌ای یا بیشتر (برای بهبود عملکرد در طول فرآیند کامپایل).
  2. حافظه (RAM):
    • حداقل 8 گیگابایت RAM.
    • توصیه‌شده: 16 گیگابایت یا بیشتر برای توسعه و کامپایل‌های پیچیده‌تر.
  3. فضای دیسک:
    • حداقل 10 گیگابایت فضای خالی دیسک برای نصب ابزارهای لازم و ذخیره پروژه‌ها.
    • توصیه‌شده: 20 گیگابایت یا بیشتر به‌ویژه برای پروژه‌های بزرگ.
  4. اتصال اینترنت:
    • اتصال اینترنت پایدار برای نصب وابستگی‌ها و ابزارها از اینترنت.

پیش‌نیازهای نرم‌افزاری

برای نصب و راه‌اندازی محیط توسعه Substrate، شما به مجموعه‌ای از ابزارهای نرم‌افزاری نیاز دارید. این ابزارها به شرح زیر هستند:

  1. Rust Programming Language: Substrate به زبان Rust نوشته شده است، بنابراین نیاز به نصب Rust دارید. برای نصب آن، دستور زیر را در ترمینال خود اجرا کنید:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    

    پس از نصب، برای اطمینان از نصب صحیح Rust، دستور زیر را وارد کنید:

    rustc --version
    

    باید نسخه‌ای از Rust را مشاهده کنید (مثلاً rustc 1.58.0 یا بالاتر).

  2. Clang: برای کامپایل کدهای Substrate، باید Clang (مترجم C و C++) را نصب کنید. دستور نصب برای سیستم‌های مختلف به شرح زیر است:
    • در Ubuntu:
      sudo apt install clang libclang-dev
      
    • در macOS (با استفاده از Homebrew):
      brew install llvm
      
  3. Git: برای مدیریت نسخه‌ها و کلون کردن مخزن‌های Git، به Git نیاز دارید. دستور نصب Git به شرح زیر است:
    • در Ubuntu:
      sudo apt update
      sudo apt install git
      
    • در macOS:
      brew install git
      
  4. Node.js و Yarn: برای نصب وابستگی‌های JavaScript و تعامل با بخش‌های UI، نیاز به Node.js و Yarn دارید:
    • نصب Node.js:
      curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
      sudo apt install -y nodejs
      
    • نصب Yarn:
      npm install --global yarn
      
  5. WebAssembly (Wasm): Substrate از WebAssembly (Wasm) برای پیاده‌سازی و اجرای runtime استفاده می‌کند. برای نصب Wasm، از دستور زیر استفاده کنید:
    • در Ubuntu:
      sudo apt install wasm32-unknown-unknown
      
    • در macOS:
      brew install wasm32-wasi
      

مراحل نصب و پیکربندی محیط توسعه

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

  1. نصب Substrate: برای نصب Substrate، ابتدا باید مخزن رسمی آن را کلون کنید. دستور زیر را اجرا کنید:
    git clone https://github.com/paritytech/substrate
    cd substrate
    
  2. نصب وابستگی‌ها: پس از کلون کردن مخزن، باید وابستگی‌های لازم را نصب کنید. برای این کار از دستور زیر استفاده کنید:
    cargo install --force --locked --git https://github.com/paritytech/substrate-subkey --tag v2.0.0 subkey
    
  3. کامپایل Substrate: برای کامپایل Substrate و راه‌اندازی بلاکچین، دستور زیر را در پوشه پروژه خود اجرا کنید:
    cargo build --release
    

    این دستور کدهای Substrate را کامپایل کرده و آن‌ها را آماده اجرا می‌کند.

  4. اجرای محیط توسعه: پس از کامپایل، می‌توانید بلاکچین Substrate را در محیط توسعه راه‌اندازی کنید. از دستور زیر برای اجرای گره بلاکچین استفاده کنید:
    ./target/release/node-template --dev
    

    این دستور بلاکچین را در حالت توسعه اجرا می‌کند و به‌طور خودکار به شبکه خصوصی Substrate متصل می‌شود.


مسیر فایل‌ها و تنظیمات

  • ~/.cargo/: مسیر پیش‌فرض برای نصب Rust و وابستگی‌های آن.
  • ~/.substrate/: مسیر پیش‌فرض برای فایل‌های Substrate.
  • target/release/: در این دایرکتوری، نسخه‌های کامپایل‌شده Substrate قرار دارند.

جمع‌بندی

برای راه‌اندازی محیط توسعه Substrate، شما به مجموعه‌ای از پیش‌نیازهای سخت‌افزاری و نرم‌افزاری نیاز دارید. پس از نصب ابزارهای ضروری مانند Rust، Clang، Git، و WebAssembly، مراحل کامپایل و راه‌اندازی بلاکچین را دنبال کرده و با استفاده از Substrate Node Template می‌توانید به توسعه بلاکچین خود بپردازید. با اجرای دستورات مربوطه، محیط توسعه آماده استفاده خواهد بود و شما می‌توانید به راحتی پروژه‌های خود را آغاز کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نصب Rust و ابزارهای مرتبط” subtitle=”توضیحات کامل”]برای توسعه با Substrate، یکی از پیش‌نیازهای اصلی نصب زبان برنامه‌نویسی Rust و ابزارهای وابسته به آن است. Rust زبان اصلی برای توسعه بلاکچین با استفاده از Substrate است، بنابراین باید ابتدا Rust را به‌طور کامل روی سیستم خود نصب کنید.

در این بخش، مراحل نصب Rust و ابزارهای مرتبط با آن را به تفصیل بررسی خواهیم کرد.


مراحل نصب Rust

برای نصب Rust و ابزارهای مرتبط، ابتدا باید Rustup (ابزار رسمی برای مدیریت نصب و نسخه‌های Rust) را نصب کنید. دستور زیر را برای نصب Rustup اجرا کنید:

  1. نصب Rustup (Rust toolchain installer):دستور زیر را در ترمینال وارد کنید تا Rustup نصب شود:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    

    این دستور، Rustup را دانلود و نصب می‌کند. پس از نصب، باید ترمینال را بسته و دوباره باز کنید تا تغییرات اعمال شوند.

  2. پیکربندی محیط:پس از نصب Rustup، ممکن است لازم باشد که مسیرهای مربوط به Rust را به محیط سیستم خود اضافه کنید. برای این کار، دستور زیر را وارد کنید:
    source $HOME/.cargo/env
    
  3. بررسی نصب Rust:پس از نصب Rust، برای اطمینان از نصب صحیح آن، دستور زیر را اجرا کنید:
    rustc --version
    

    خروجی باید نسخه‌ای از Rust را نمایش دهد (مثلاً rustc 1.58.0 یا بالاتر).


نصب ابزارهای مرتبط با Rust

در کنار نصب Rust، شما به ابزارهای اضافی دیگری نیاز دارید که در فرآیند توسعه با Substrate ضروری هستند. این ابزارها عبارتند از Cargo (ابزار ساخت و مدیریت بسته‌ها)، Clang (مترجم C/C++) و Rustup Components که به شما کمک می‌کنند تا بهترین تجربه توسعه را داشته باشید.

  1. نصب Cargo:پس از نصب Rust، ابزار Cargo به‌طور خودکار نصب می‌شود. Cargo برای مدیریت بسته‌ها، کامپایل پروژه‌ها و اجرای دستورات مختلف مورد استفاده قرار می‌گیرد. برای بررسی نصب Cargo، دستور زیر را وارد کنید:
    cargo --version
    

    این دستور باید نسخه‌ای از Cargo را نمایش دهد.

  2. نصب Clang:به دلیل وابستگی‌های C/C++ که در برخی پروژه‌های Substrate استفاده می‌شود، نصب Clang برای کامپایل کردن این وابستگی‌ها ضروری است.
    • در Ubuntu:
      sudo apt install clang libclang-dev
      
    • در macOS:
      brew install llvm
      
  3. نصب WASM target (مجموعه هدف WebAssembly):Substrate برای پیاده‌سازی و اجرای runtime خود از WebAssembly (Wasm) استفاده می‌کند. برای استفاده از این ویژگی، باید مجموعه هدف wasm32-unknown-unknown را نصب کنید. دستور زیر را برای نصب آن وارد کنید:
    • در Ubuntu:
      rustup target add wasm32-unknown-unknown
      
    • در macOS:
      rustup target add wasm32-unknown-unknown
      
  4. نصب ابزارهای توسعه دیگر (اختیاری):
    • Substrate Subkey: برای کار با کلیدهای خصوصی و عمومی در Substrate، می‌توانید ابزار Subkey را نصب کنید. این ابزار به شما کمک می‌کند تا کلیدهای عمومی و خصوصی ایجاد و مدیریت کنید. برای نصب Subkey از دستور زیر استفاده کنید:
      cargo install --force --locked --git https://github.com/paritytech/substrate-subkey --tag v2.0.0 subkey
      

مسیر فایل‌ها و تنظیمات

  • ~/.cargo/: مسیر پیش‌فرض برای نصب و ذخیره ابزارهای Cargo و وابستگی‌ها.
  • ~/.rustup/: مسیر پیش‌فرض برای نصب Rustup و نگهداری ابزارهای Rust.
  • target/release/: مسیر پیش‌فرض برای فایل‌های کامپایل‌شده و تولیدی پروژه‌ها.

جمع‌بندی

با نصب Rust و ابزارهای مرتبط مانند Cargo، Clang، و WebAssembly target، محیط توسعه برای Substrate آماده خواهد شد. پس از انجام مراحل نصب، می‌توانید با استفاده از ابزارهایی مانند Subkey و Cargo، پروژه‌های خود را کامپایل و مدیریت کنید. این ابزارها از اجزای اساسی برای توسعه بلاکچین با استفاده از Substrate هستند و به شما کمک می‌کنند تا به‌صورت مؤثر و سریع پروژه‌های بلاکچینی خود را ایجاد کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیکربندی Rust برای بهینه‌سازی عملکرد (Rustup، Cargo، nightly toolchain)” subtitle=”توضیحات کامل”]برای توسعه پروژه‌های بلاکچینی با استفاده از Substrate، پیکربندی بهینه‌سازی عملکرد ابزارهای Rust امری حیاتی است. در این بخش، نحوه پیکربندی Rustup، Cargo و استفاده از nightly toolchain را برای بهینه‌سازی عملکرد مرور خواهیم کرد. این پیکربندی‌ها به شما کمک خواهند کرد تا از جدیدترین ویژگی‌ها و بهترین عملکرد در توسعه پروژه‌های Substrate بهره‌برداری کنید.


۱. پیکربندی Rustup برای مدیریت نسخه‌ها

Rustup ابزاری برای مدیریت نسخه‌های مختلف Rust و ابزارهای وابسته به آن است. با استفاده از Rustup می‌توانید نسخه‌های مختلف Rust را نصب و تغییر دهید تا همیشه از آخرین نسخه‌ها و بهینه‌ترین ابزارها استفاده کنید.

  1. نصب و تنظیم Rustup:برای نصب و تنظیم Rustup، دستور زیر را در ترمینال وارد کنید:
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
  2. تنظیم مسیرهای Rust:پس از نصب Rustup، مسیرهای مربوط به آن باید به محیط سیستم اضافه شوند. دستور زیر برای بارگذاری تنظیمات Rustup به محیط سیستم استفاده می‌شود:
    source $HOME/.cargo/env
    
  3. بررسی نسخه Rust:برای بررسی نسخه نصب‌شده Rust و اطمینان از اینکه نسخه‌های به‌روز را دارید، از دستور زیر استفاده کنید:
    rustc --version
    

    این دستور باید نسخه‌ای مانند rustc 1.58.0 یا بالاتر را نمایش دهد.

  4. استفاده از Nightly Toolchain:برای دریافت آخرین ویژگی‌ها و بهینه‌سازی‌های موجود در Rust، می‌توانید از nightly toolchain استفاده کنید. برای نصب و استفاده از این نسخه، دستور زیر را وارد کنید:
    rustup default nightly
    

    پس از این دستور، نسخه‌ی nightly به‌طور پیش‌فرض برای پروژه‌ها تنظیم خواهد شد.


۲. پیکربندی Cargo برای بهینه‌سازی کامپایل

Cargo ابزاری است که برای ساخت، مدیریت و تست بسته‌های Rust استفاده می‌شود. پیکربندی‌های مختلف در Cargo به بهینه‌سازی زمان ساخت، استفاده از کش‌ها، و مدیریت وابستگی‌ها کمک می‌کنند.

  1. فعال‌سازی ویژگی‌های بهینه‌سازی در Cargo:برای بهینه‌سازی عملکرد کامپایل، می‌توانید ویژگی‌های خاصی را در فایل Cargo.toml پروژه خود تنظیم کنید. به‌ویژه استفاده از ویژگی opt-level برای بهینه‌سازی کد در زمان کامپایل بسیار مفید است.به‌عنوان مثال، می‌توانید سطح بهینه‌سازی را برای پروژه خود به 2 تنظیم کنید:
    [profile.release]
    opt-level = 2
    

    این سطح بهینه‌سازی کد را در زمان ساخت پروژه در release mode بهبود می‌بخشد.

  2. استفاده از ویژگی‌های خاص برای Substrate:برای پروژه‌های مبتنی بر Substrate، تنظیمات خاصی برای بهینه‌سازی‌های عملکردی وجود دارند. برای مثال، استفاده از wasm-opt در هنگام ساخت وب اسمبلی (Wasm) بسیار موثر است.برای نصب و استفاده از این ابزار، دستور زیر را وارد کنید:
    cargo install wasm-opt
    

    سپس در زمان ساخت پروژه، می‌توانید از این ابزار برای بهینه‌سازی WebAssembly استفاده کنید:

    wasm-opt target/wasm32-unknown-unknown/release/your_project.wasm -O3 -o target/wasm32-unknown-unknown/release/your_project.optimized.wasm
    
  3. استفاده از کش‌ها و مدیریت وابستگی‌ها:Cargo به‌طور خودکار کش‌های پروژه را ذخیره می‌کند تا در دفعات بعدی کامپایل سریع‌تر انجام شود. اگر می‌خواهید از کش‌های معتبر استفاده کنید، می‌توانید از دستور زیر برای به‌روزرسانی آن‌ها استفاده کنید:
    cargo update
    

۳. تنظیمات خاص برای ابزارهای توسعه (Nightly، Clippy، Rustfmt)

برای بهبود کیفیت کد و بهینه‌سازی عملکرد، می‌توانید از ابزارهای توسعه‌ای همچون Clippy و Rustfmt استفاده کنید.

  1. فعال‌سازی Clippy:Clippy ابزار تحلیل استاتیک Rust است که به شما کمک می‌کند تا کد خود را بهینه کنید و از مشکلات رایج جلوگیری کنید. برای فعال‌سازی آن در محیط توسعه، دستور زیر را وارد کنید:
    rustup component add clippy --toolchain nightly
    

    سپس می‌توانید از دستور زیر برای بررسی کد با استفاده از Clippy استفاده کنید:

    cargo clippy
    
  2. تنظیم Rustfmt:Rustfmt برای فرمت‌بندی کدهای Rust استفاده می‌شود. برای نصب و تنظیم آن، دستور زیر را وارد کنید:
    rustup component add rustfmt --toolchain nightly
    

    سپس می‌توانید از دستور زیر برای فرمت‌بندی پروژه خود استفاده کنید:

    cargo fmt
    

۴. مسیر فایل‌ها و تنظیمات

  • ~/.cargo/: مسیر پیش‌فرض برای ذخیره‌سازی بسته‌ها و ابزارهای Cargo.
  • ~/.rustup/: مسیر پیش‌فرض برای مدیریت نسخه‌های Rust و ابزارهای مرتبط.
  • Cargo.toml: فایل تنظیمات پروژه که وابستگی‌ها و ویژگی‌های خاص آن را مدیریت می‌کند.
  • target/: مسیر پیش‌فرض برای خروجی‌های کامپایل شده، از جمله فایل‌های wasm.

جمع‌بندی

پیکربندی بهینه‌سازی ابزارهای Rust، شامل استفاده از nightly toolchain، Cargo با تنظیمات بهینه، و ابزارهای کمکی مانند Clippy و Rustfmt، به شما این امکان را می‌دهد تا از جدیدترین ویژگی‌ها و بهینه‌ترین عملکرد در توسعه پروژه‌های Substrate بهره‌برداری کنید. با این تنظیمات، می‌توانید سرعت کامپایل، کیفیت کد و عملکرد نهایی پروژه‌های خود را بهبود بخشید و تجربه بهتری در فرآیند توسعه بلاکچین داشته باشید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”دریافت و نصب Substrate Node Template از GitHub” subtitle=”توضیحات کامل”]برای شروع به کار با Substrate و ایجاد یک نود بلاکچین شخصی، می‌توان از Substrate Node Template استفاده کرد. این قالب یک ساختار ابتدایی برای ایجاد نودهای بلاکچین شخصی فراهم می‌آورد که می‌توانید آن را بر اساس نیازهای خود گسترش دهید. در این بخش، نحوه دریافت و نصب Substrate Node Template از GitHub را توضیح می‌دهیم.


۱. دریافت Substrate Node Template از GitHub

برای دریافت Substrate Node Template از GitHub، ابتدا باید مخزن رسمی آن را کلون کنید.

  1. کلون کردن مخزن Substrate Node Template:دستور زیر را در ترمینال وارد کنید تا مخزن Substrate Node Template را از GitHub دانلود کنید:
    git clone https://github.com/substrate-developer-hub/substrate-node-template
    

    این دستور مخزن را در دایرکتوری جاری شما دانلود می‌کند.

  2. انتقال به دایرکتوری پروژه:پس از کلون کردن مخزن، باید وارد دایرکتوری پروژه شوید. دستور زیر را وارد کنید:
    cd substrate-node-template
    

۲. نصب وابستگی‌ها

بعد از دریافت پروژه، باید وابستگی‌ها را نصب کنید تا مطمئن شوید که همه چیز برای ساخت پروژه آماده است.

  1. نصب وابستگی‌ها با استفاده از Cargo:برای نصب وابستگی‌ها، از ابزار Cargo استفاده می‌کنیم که قبلاً نصب شده است. دستور زیر را در دایرکتوری پروژه وارد کنید:
    cargo build --release
    

    این دستور تمامی وابستگی‌ها را دانلود و پروژه را کامپایل می‌کند. مدت زمان این فرایند بستگی به سرعت اینترنت و منابع سیستم شما دارد.


۳. اجرای Substrate Node

بعد از نصب وابستگی‌ها و کامپایل کردن پروژه، می‌توانید نود Substrate را اجرا کنید.

  1. اجرای نود Substrate:برای اجرای نود، دستور زیر را وارد کنید:
    ./target/release/node-template --dev
    

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

    در صورتی که همه چیز به درستی تنظیم شده باشد، خروجی مشابه زیر را خواهید دید:

    2025-03-05 15:30:12 Substrate Node Template: Starting the node ...
    2025-03-05 15:30:12 Substrate Node Template: Running in development mode
    
  2. مشاهده وضعیت نود:برای بررسی وضعیت نود و اطمینان از اینکه همه چیز به درستی کار می‌کند، از دستور زیر استفاده کنید:
    curl http://localhost:9933
    

    این دستور باید خروجی مشابه زیر را به شما بدهد که نشان‌دهنده فعال بودن نود است:

    {"jsonrpc":"2.0","result":"ok","id":1}
    

۴. پیکربندی تنظیمات نود

برای تنظیمات بیشتر و سفارشی‌سازی نود، می‌توانید تنظیمات مختلفی را در فایل‌های پیکربندی و کدهای نود اعمال کنید. به‌عنوان مثال، ممکن است بخواهید تنظیمات مربوط به consensus، network یا validators را تغییر دهید.

  1. پیکربندی فایل node-template.toml:فایل پیکربندی پروژه Substrate Node Template را می‌توان در مسیر زیر پیدا کرد:
    ./node-template/node-template.toml
    

    در این فایل می‌توانید تنظیمات مربوط به شبکه و سایر پارامترها را تغییر دهید.


۵. ساخت و اجرای نود در شبکه‌های مختلف

در صورتی که بخواهید نود خود را به شبکه‌های مختلف متصل کنید، می‌توانید از تنظیمات زیر استفاده کنید:

  1. اجرای نود به‌صورت شبکه‌ای با اتصال به شبکه موجود:اگر می‌خواهید نود خود را به یک شبکه بلاکچین فعال متصل کنید، از دستور زیر استفاده کنید:
    ./target/release/node-template --chain=kusama --bootnodes <bootnode_url> --rpc-cors all --rpc-methods all
    

    در این دستور، --chain نام شبکه مورد نظر را مشخص می‌کند (برای مثال kusama، polkadot یا هر شبکه دیگر) و --bootnodes لیستی از نودهای اولیه برای اتصال به شبکه است.


۶. مسیر فایل‌ها و تنظیمات

  • substrate-node-template/: دایرکتوری اصلی پروژه که شامل تمام کدهای مربوط به نود است.
  • ./target/release/: محل خروجی فایل‌های کامپایل‌شده، از جمله فایل اجرایی نود.
  • node-template.toml: فایل پیکربندی برای تنظیمات مربوط به نود.

جمع‌بندی

با استفاده از دستوراتی که در این بخش توضیح داده شد، شما می‌توانید Substrate Node Template را از GitHub دریافت کرده، وابستگی‌ها را نصب کرده و نود بلاکچین شخصی خود را اجرا کنید. همچنین امکان پیکربندی و اتصال نود به شبکه‌های مختلف وجود دارد که به شما کمک می‌کند تا بلاکچین خود را به‌طور کامل سفارشی‌سازی کنید و در محیط‌های توسعه یا تولید اجرا نمایید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. ساختار و اجزای Node Template در Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی ساختار فایل‌ها و فولدرهای پروژه Substrate” subtitle=”توضیحات کامل”]زمانی که شما یک پروژه Substrate راه‌اندازی می‌کنید، ساختار فایل‌ها و دایرکتوری‌های مختلفی در اختیار شما قرار می‌گیرد. درک دقیق این ساختار برای توسعه‌دهندگان Substrate بسیار مهم است، چرا که کمک می‌کند تا بتوانند به‌راحتی پروژه را مدیریت کرده و بر روی آن کار کنند.

در این بخش، ساختار اصلی پروژه Substrate و توضیح مختصری از هر بخش را بررسی خواهیم کرد.


۱. ساختار کلی پروژه

زمانی که پروژه Substrate Node Template را از GitHub کلون می‌کنید، ساختار دایرکتوری آن به شکل زیر خواهد بود:

substrate-node-template/
├── assets/
├── benchmarks/
├── cli/
├── node/
├── pallets/
├── runtime/
├── scripts/
├── target/
├── Cargo.toml
└── README.md

۲. توضیح دایرکتوری‌ها و فایل‌های اصلی پروژه

1. assets/

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

محتویات معمولی:

  • فایل‌های گرافیکی
  • فایل‌های پیکربندی استاتیک
  • مستندات پروژه
2. benchmarks/

این دایرکتوری معمولاً برای پیاده‌سازی بنچمارک‌ها (آزمون‌های عملکرد) و ارزیابی عملکرد پروژه‌ها به کار می‌رود. در صورتی که بخواهید بهینه‌سازی‌های عملکردی انجام دهید، این فولدر می‌تواند برای تست‌های عملکردی مفید باشد.

محتویات معمولی:

  • بنچمارک‌ها و تست‌های عملکردی مربوط به Substrate
3. cli/

دایرکتوری cli/ حاوی کدهایی است که برای ایجاد Command Line Interface (CLI) برای پروژه استفاده می‌شود. این بخش به شما اجازه می‌دهد تا از طریق ترمینال با نود خود ارتباط برقرار کرده و دستورات مختلف را اجرا کنید.

محتویات معمولی:

  • فایل‌های مربوط به رابط کاربری خط فرمان
  • پیاده‌سازی دستورات و گزینه‌های CLI برای مدیریت نود
4. node/

دایرکتوری node/ حاوی کدهای اصلی مربوط به اجرای نود است. این فولدر مسئول راه‌اندازی، مدیریت و تنظیمات مربوط به نود بلاکچین می‌باشد.

محتویات معمولی:

  • فایل‌های مربوط به راه‌اندازی نود
  • پیکربندی‌های شبکه و تنظیمات اولیه
  • فایل‌هایی که مسئولیت اجرای بلاکچین را بر عهده دارند
5. pallets/

دایرکتوری pallets/ حاوی Pallets است. در Substrate، Pallet واحدهای کدی هستند که عملکردهای مختلفی را برای بلاکچین ارائه می‌دهند. هر Pallet می‌تواند مسئولیت خاصی مانند انتقال دارایی‌ها، ثبت تراکنش‌ها، ایجاد بلاک‌ها و غیره را بر عهده بگیرد.

محتویات معمولی:

  • کدهای مربوط به Pallets خاص پروژه
  • هر pallet می‌تواند عملکرد خاصی مانند مدیریت تراکنش‌ها، اعمال قراردادهای هوشمند، یا هر نوع عملیاتی را پیاده‌سازی کند.
6. runtime/

دایرکتوری runtime/ حاوی کدهای مربوط به runtime بلاکچین است. این بخش به عنوان “مغز” بلاکچین عمل می‌کند و تمام منطق اجرایی بلاکچین مانند مدیریت تراکنش‌ها، اعتبارسنجی بلاک‌ها و پروتکل‌های اجماع در اینجا پیاده‌سازی می‌شود. همچنین در این فولدر، به تعریف Palletها و ساختارهای داده‌ای نیز پرداخته می‌شود.

محتویات معمولی:

  • منطق اجرایی بلاکچین
  • تنظیمات مربوط به Pallets، قراردادهای هوشمند، و سایر مولفه‌های مهم شبکه
  • پیاده‌سازی پروتکل‌های اجماع و مدیریت وضعیت زنجیره
7. scripts/

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

محتویات معمولی:

  • اسکریپت‌های پیکربندی، نصب و راه‌اندازی
  • اسکریپت‌های مدیریت یا تست
8. target/

دایرکتوری target/ یک دایرکتوری تولیدی است که بعد از اجرای دستور cargo build یا cargo run در آن قرار می‌گیرد. این دایرکتوری شامل فایل‌های کامپایل‌شده، باینری‌ها و دیگر فایل‌های مربوط به اجرای نود است.

محتویات معمولی:

  • فایل‌های باینری پروژه (معمولاً در ./target/release/ قرار می‌گیرند)
  • فایل‌های مربوط به ساخت و پیکربندی
9. Cargo.toml

این فایل مشابه فایل پیکربندی برای Cargo است که در آن اطلاعات مربوط به وابستگی‌ها، نسخه‌ها، تنظیمات ساخت و کامپایل پروژه ذخیره می‌شود.

محتویات معمولی:

  • تنظیمات وابستگی‌ها و نسخه‌ها
  • تنظیمات مربوط به پیکربندی کامپایل پروژه
10. README.md

این فایل معمولاً حاوی توضیحات اولیه در مورد پروژه است. شما می‌توانید در این فایل توضیحاتی مانند هدف پروژه، نحوه استفاده، پیش‌نیازها و دستورالعمل‌های راه‌اندازی را پیدا کنید.


جمع‌بندی

در این بخش، ساختار فایل‌ها و فولدرهای پروژه Substrate را بررسی کردیم و توضیح دادیم که هر کدام از این دایرکتوری‌ها و فایل‌ها برای چه منظوری استفاده می‌شوند. این درک به شما کمک خواهد کرد تا پروژه‌های Substrate را بهتر مدیریت کنید و توسعه‌های مورد نیاز خود را به‌راحتی انجام دهید.[/cdb_course_lesson][cdb_course_lesson title=”آشنایی با فایل‌های اصلی:”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”Cargo.toml و مدیریت وابستگی‌ها” subtitle=”توضیحات کامل”]در پروژه‌های Rust، از جمله پروژه‌های Substrate، فایل Cargo.toml یکی از اجزای اساسی برای پیکربندی پروژه است. این فایل وظیفه مدیریت وابستگی‌ها و تنظیمات مختلف مربوط به ساخت و کامپایل پروژه را بر عهده دارد. در این بخش به معرفی فایل Cargo.toml و نحوه مدیریت وابستگی‌ها در آن خواهیم پرداخت.


۱. فایل Cargo.toml چیست؟

فایل Cargo.toml یک فایل پیکربندی برای پروژه‌های Rust است که به‌وسیله آن می‌توان تنظیمات مختلف پروژه را انجام داد. این فایل شامل اطلاعات مهمی مانند:

  • نام پروژه
  • نسخه پروژه
  • وابستگی‌های خارجی (dependencies)
  • مقادیر پیکربندی مربوط به کامپایل
  • ویژگی‌های خاص پروژه

این فایل در هر پروژه Rust به‌طور خودکار ایجاد می‌شود و برای انجام هرگونه تغییر در نحوه مدیریت وابستگی‌ها، تنظیمات کامپایل و ساخت، باید این فایل را ویرایش کنید.


۲. ساختار و محتویات فایل Cargo.toml

فایل Cargo.toml به‌طور کلی از بخش‌های مختلفی تشکیل شده است که در ادامه به هر یک پرداخته می‌شود:

1. بخش [package]

این بخش حاوی اطلاعات اصلی مربوط به پروژه مانند نام، نسخه، و سایر مشخصات عمومی پروژه است. به‌عنوان مثال:

[package]
name = "substrate-node-template"
version = "0.1.0"
authors = ["Your Name <youremail@example.com>"]
edition = "2018"
  • name: نام پروژه را مشخص می‌کند.
  • version: نسخه فعلی پروژه را مشخص می‌کند.
  • authors: نویسندگان پروژه.
  • edition: نسخه‌ای از Rust که پروژه از آن استفاده می‌کند. معمولاً از “2018” استفاده می‌شود.
2. بخش [dependencies]

این بخش برای تعریف وابستگی‌های پروژه استفاده می‌شود. هر بسته‌ای که پروژه نیاز به استفاده از آن داشته باشد، باید در این قسمت تعریف شود. برای مثال:

[dependencies]
frame-support = { version = "3.0", default-features = false }
substrate-sdk = { git = "https://github.com/paritytech/substrate.git", branch = "master" }
  • در اینجا، frame-support یک وابستگی است که از نسخه 3.0 استفاده می‌کند و ویژگی‌های پیش‌فرض آن غیرفعال شده‌اند.
  • substrate-sdk به‌طور مستقیم از یک مخزن گیت هاب نصب می‌شود.
3. بخش [dev-dependencies]

این بخش مشابه به بخش [dependencies] است اما برای وابستگی‌هایی که فقط در زمان تست و توسعه به پروژه اضافه می‌شوند، استفاده می‌شود. برای مثال:

[dev-dependencies]
serde = "1.0"
4. بخش [build-dependencies]

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

[build-dependencies]
build-utils = "0.1"
5. بخش [features]

در این بخش می‌توانید ویژگی‌های خاصی را برای پروژه تعریف کنید. این ویژگی‌ها به شما این امکان را می‌دهند که ویژگی‌هایی را در هنگام ساخت پروژه فعال یا غیرفعال کنید. به‌عنوان مثال:

[features]
default = ["full"]
full = ["serde", "std"]

این ویژگی‌ها به پروژه کمک می‌کنند تا بر اساس نیازهای خاص، ویژگی‌های مختلف را در زمان کامپایل فعال کند.

6. بخش [workspace]

اگر چندین پروژه مختلف در یک فضای کاری داشته باشید، می‌توانید از این بخش برای مشخص کردن آن‌ها استفاده کنید. برای مثال:

[workspace]
members = [
  "node-template",
  "substrate-node-template"
]

۳. مدیریت وابستگی‌ها با Cargo.toml

در Rust، مدیریت وابستگی‌ها با استفاده از Cargo.toml به‌شدت ساده است. این فایل به شما اجازه می‌دهد که بسته‌ها را به راحتی اضافه کنید و برای هر بسته تنظیمات خاصی مانند نسخه، ویژگی‌ها، یا منبع (مثل گیت هاب) را تعریف کنید.

1. وابستگی‌ها از مخزن Crates.io

Crates.io مخزن رسمی بسته‌های Rust است که بیشتر بسته‌ها از این منبع نصب می‌شوند. برای اضافه کردن یک وابستگی از Crates.io، تنها کافیست نام بسته و نسخه آن را مشخص کنید:

[dependencies]
serde = "1.0"
2. وابستگی‌ها از گیت هاب

در صورتی که بخواهید یک وابستگی را از گیت هاب یا دیگر منابع آنلاین نصب کنید، می‌توانید از مشخصات git یا path استفاده کنید:

[dependencies]
substrate-sdk = { git = "https://github.com/paritytech/substrate.git", branch = "master" }
3. استفاده از ویژگی‌های وابستگی‌ها

در صورتی که وابستگی شما ویژگی‌های مختلفی داشته باشد، می‌توانید از ویژگی‌ها برای فعال‌سازی یا غیرفعال کردن بخش‌هایی از آن استفاده کنید:

[dependencies]
serde = { version = "1.0", features = ["derive"] }

این کد باعث می‌شود تا تنها ویژگی derive از serde فعال شود.


۴. نصب و به‌روز رسانی وابستگی‌ها

برای نصب وابستگی‌ها و به‌روزرسانی آن‌ها، از دستور زیر استفاده می‌کنید:

cargo build

این دستور تمامی وابستگی‌ها را از Cargo.toml خوانده و آن‌ها را دانلود و نصب می‌کند.

برای به‌روزرسانی وابستگی‌ها به آخرین نسخه‌های مجاز، از دستور زیر استفاده می‌کنید:

cargo update

این دستور باعث می‌شود که تمامی وابستگی‌ها به نسخه‌های جدیدتری که در فایل Cargo.toml مجاز هستند، به‌روزرسانی شوند.


جمع‌بندی

در این بخش، با مفهوم و ساختار فایل Cargo.toml آشنا شدیم. این فایل به‌عنوان قلب پروژه‌های Rust و Substrate، نقش مهمی در مدیریت وابستگی‌ها و تنظیمات کامپایل پروژه ایفا می‌کند. همچنین با نحوه اضافه کردن، به‌روزرسانی و مدیریت وابستگی‌ها در پروژه‌های Rust آشنا شدیم. این اطلاعات به شما کمک خواهد کرد تا پروژه‌های خود را به‌خوبی پیکربندی کرده و به راحتی وابستگی‌ها را مدیریت کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”runtime/src/lib.rs و تعریف Palletها” subtitle=”توضیحات کامل”]در پروژه‌های Substrate، فایل lib.rs یکی از مهم‌ترین فایل‌ها است که در آن ساختار runtime و تنظیمات مختلف مربوط به آن تعریف می‌شود. در این بخش به معرفی این فایل و نحوه تعریف Palletها خواهیم پرداخت.


۱. فایل runtime/src/lib.rs چیست؟

فایل lib.rs در مسیر runtime/src یکی از اجزای اصلی در پروژه‌های Substrate است که ساختار و عملکرد runtime را مشخص می‌کند. در این فایل، شما به‌طور کلی تمامی اجزای اصلی runtime را تعریف می‌کنید، از جمله Palletها، اطلاعات بلاکچین و توابع داخلی که برای تعامل با این Palletها و مدیریت داده‌ها استفاده می‌شوند.

در پروژه‌های Substrate، هر فایل lib.rs معمولاً مسئول تعریف تمامی Palletها و کارکردهای آن‌ها در runtime است. این فایل توسط Frame که به‌عنوان فریمورک اصلی Substrate عمل می‌کند، ساخته می‌شود و به‌طور ویژه به ساختارهای Pallet متکی است.


۲. ساختار فایل runtime/src/lib.rs

در ابتدا، برای استفاده از فریمورک Frame و Palletها باید وابستگی‌ها و ماژول‌های موردنیاز را در فایل lib.rs وارد کنید. این فایل معمولاً شامل بخش‌های زیر است:

1. وارد کردن وابستگی‌ها و ماژول‌ها

در ابتدا، باید Palletهای مختلف را به فایل lib.rs وارد کنید. به‌عنوان مثال، در اینجا از Palletهای پایه Substrate مانند frame_system، pallet_timestamp و pallet_balances استفاده شده است:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet_balances;
pub use frame_system;
pub use pallet_timestamp;
  • frame_system: این ماژول مسئول مدیریت سیستم بلاکچین، از جمله مدیریت بلاک‌ها و وضعیت شبکه است.
  • pallet_balances: این Pallet برای مدیریت حساب‌ها و تراکنش‌های کاربران استفاده می‌شود.
  • pallet_timestamp: این Pallet برای ذخیره‌سازی و مدیریت زمان در بلاکچین استفاده می‌شود.
2. تعریف ساختار Runtime

در این بخش، ساختار کلی runtime باید تعریف شود. این ساختار شامل Palletهایی است که باید در runtime وجود داشته باشند:

#[frame_support::pallet]
pub mod pallet_balances {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{self as system, pallet_prelude::*};

    #[frame_support::pallet]
    pub mod pallet {
        use super::*;
        
        #[pallet::call]
        impl<T: Config> Pallet<T> {
            // توابع در اینجا تعریف می‌شوند.
        }
    }
}

در اینجا، برای تعریف Pallet از ویژگی #[frame_support::pallet] استفاده شده است.

3. تنظیمات و پیکربندی Palletها

برای هر Pallet باید تنظیمات خاص آن Pallet مانند منابع ذخیره‌سازی، توابع متداول و نحوه مدیریت آن‌ها را تعریف کنید. این کار معمولاً در داخل ماژول Pallet انجام می‌شود:

#[pallet::config]
pub trait Config: frame_system::Config {}

در اینجا، Config برای تعریف ویژگی‌های پیکربندی موردنیاز برای Pallet استفاده می‌شود. این ویژگی‌ها شامل انواع ذخیره‌سازی، منابع شبکه، و بسیاری از تنظیمات دیگر است.

4. توابع Palletها

توابع موجود در Pallet برای انجام عملیات مختلف مانند انتقال ارز، ذخیره‌سازی اطلاعات یا انجام محاسبات خاص به کار می‌روند. این توابع تحت ویژگی #[pallet::call] تعریف می‌شوند:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::call]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, value: BalanceOf<T>) -> DispatchResult {
        let who = ensure_signed(origin)?;
        pallet_balances::Pallet::<T>::transfer(&who, &dest, value)?;
        Ok(())
    }
}

در اینجا، تابع transfer برای انجام تراکنش‌های انتقال ارز بین حساب‌ها تعریف شده است.


۳. تعریف Palletها در Substrate

Palletها اجزای اصلی در Substrate هستند که به‌وسیله آن‌ها می‌توان عملیات مختلفی مانند ارسال تراکنش، مدیریت زمان، و کنترل منابع انجام داد. در Substrate، هر Pallet معمولاً شامل اجزای زیر است:

1. ذخیره‌سازی

در هر Pallet، شما می‌توانید از انواع مختلف ذخیره‌سازی برای نگهداری اطلاعات استفاده کنید. این اطلاعات می‌تواند شامل موجودی حساب‌ها، وضعیت تراکنش‌ها، و هرگونه داده دیگری باشد. برای نمونه، ذخیره‌سازی موجودی حساب‌ها در Pallet balances به شکل زیر است:

#[pallet::call]
pub struct Pallet<T: Config> {
    pub balance: StorageValue<_, BalanceOf<T>>,
}
2. توابع و عملیات

توابعی که در هر Pallet تعریف می‌شوند، عملیات مختلف را بر روی داده‌ها و اطلاعات ذخیره‌شده انجام می‌دهند. به‌عنوان مثال، در Pallet balances تابعی برای انتقال ارز به کار می‌رود:

#[pallet::call]
pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, value: BalanceOf<T>) -> DispatchResult {
    // انتقال ارز از حساب مبدا به مقصد
}
3. رویدادها (Events)

رویدادها در Pallet‌ها برای ارسال اطلاعیه‌ها و نتایج به شبکه و گره‌ها استفاده می‌شوند. برای مثال، در Pallet balances می‌توان از رویدادهای مربوط به تراکنش‌های موفق و یا ناموفق استفاده کرد:

#[pallet::event]
pub enum Event<T: Config> {
    Transferred(T::AccountId, T::AccountId, BalanceOf<T>),
}

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

4. متغیرهای وضعیت (Storage Items)

Pallet‌ها برای ذخیره‌سازی اطلاعات مختلف از متغیرهای وضعیت استفاده می‌کنند. به‌عنوان مثال، برای ذخیره موجودی هر حساب، از یک متغیر وضعیت استفاده می‌شود:

#[pallet::storage]
pub(super) type Balances<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf<T>>;

این متغیر وضعیت موجودی هر حساب را در یک نقشه ذخیره می‌کند.


۴. نصب Palletها و استفاده از آن‌ها در lib.rs

در ابتدا، برای استفاده از Palletها باید آن‌ها را در فایل lib.rs وارد کنید. به‌طور مثال، برای وارد کردن Pallet balances، کد زیر را در lib.rs خواهید داشت:

pub use pallet_balances;

سپس، شما می‌توانید از این Pallet در کدهای مختلف runtime خود استفاده کنید. برای مثال، در یک تابع می‌توانید تراکنش‌هایی را با استفاده از Pallet balances انجام دهید.


جمع‌بندی

در این بخش، با فایل runtime/src/lib.rs و نحوه تعریف و استفاده از Pallet‌ها در پروژه‌های Substrate آشنا شدیم. این فایل به‌عنوان مرکزی‌ترین بخش از runtime، مسئول مدیریت Pallet‌ها و انجام عملیات مختلف بر روی آن‌ها است. همچنین، یاد گرفتیم که چگونه می‌توانیم با استفاده از Pallet‌ها ذخیره‌سازی، توابع، رویدادها و متغیرهای وضعیت را مدیریت کرده و به‌طور مؤثر از آن‌ها برای پیاده‌سازی بلاکچین‌های کاربردی استفاده کنیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”node/src/chain_spec.rs و تنظیمات شبکه” subtitle=”توضیحات کامل”]فایل chain_spec.rs یکی از فایل‌های حیاتی در پروژه‌های Substrate است که برای پیکربندی و تنظیمات شبکه بلاکچین استفاده می‌شود. در این بخش به معرفی این فایل و نحوه تنظیم شبکه در Substrate خواهیم پرداخت.


۱. فایل node/src/chain_spec.rs چیست؟

فایل chain_spec.rs در مسیر node/src در پروژه‌های Substrate، برای پیکربندی جزئیات و تنظیمات مربوط به شبکه بلاکچین استفاده می‌شود. این فایل اطلاعاتی مانند شناسه شبکه (chain ID)، نام شبکه، تنظیمات مختلف مانند الگوریتم اجماع، و تنظیمات دیگر را برای بلاکچین تعریف می‌کند. این فایل به‌طور خاص برای راه‌اندازی شبکه بلاکچین در یک گره یا نود استفاده می‌شود.

در پروژه‌های Substrate، معمولاً از این فایل برای پیکربندی پارامترهای مختلف شبکه مانند پارامترهای اجماع، آدرس‌های جبران اعتبار (genesis accounts)، و تنظیمات مختلف دیگر که در زمان شروع شبکه اعمال می‌شوند، استفاده می‌شود.


۲. ساختار فایل node/src/chain_spec.rs

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

1. تنظیمات شبکه

در ابتدای فایل، معمولاً یک ساختار داده برای پیکربندی شبکه تعریف می‌شود. این ساختار شامل تنظیمات مختلف مانند نام شبکه، شناسه شبکه، و تنظیمات اولیه است:

use frame_support::{construct_runtime, parameter_types};
use pallet_balances::BalancesConfig;
use sp_core::H256;
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, generic};
use sp_std::prelude::*;
use pallet_timestamp::Call as TimestampCall;

#[derive(Clone, Default, PartialEq, Eq, Encode, Decode)]
pub struct ChainSpec {
    pub id: String,
    pub name: String,
    pub network: String,
    pub bootnodes: Vec<String>,
}

در اینجا، ساختار ChainSpec تعریف شده است که اطلاعات مربوط به شناسه، نام، شبکه و لیست نودهای راه‌اندازی (bootnodes) را ذخیره می‌کند.

2. تنظیمات Genesis Block

یکی از بخش‌های مهم در فایل chain_spec.rs تنظیمات بلوک اولیه یا Genesis Block است. این بلوک اولین بلوک شبکه است که قبل از هر تراکنش دیگری در بلاکچین قرار می‌گیرد. در این بخش معمولاً حساب‌های اولیه، موجودی‌های پیش‌فرض و سایر داده‌های مرتبط با راه‌اندازی بلاکچین تنظیم می‌شود.

fn genesis_config() -> ChainSpec {
    ChainSpec {
        id: "my_chain".to_string(),
        name: "My Substrate Blockchain".to_string(),
        network: "my_network".to_string(),
        bootnodes: vec!["/ip4/127.0.0.1/tcp/30333/p2p/12D3KooWJf9c5LkEnj7sdaQajYAh7v6cUp5QyBGaQgFDoHseMsFB5q9pkVpmdYp3T4yD3qKp43FFz37EYdyfwfqF".to_string()],
    }
}

در اینجا، genesis_config مشخص می‌کند که شناسه شبکه، نام شبکه، شبکه و نودهای راه‌اندازی شبکه چگونه تنظیم می‌شوند.

3. تنظیمات الگوریتم اجماع

در این قسمت، می‌توان تنظیمات الگوریتم اجماع شبکه را پیکربندی کرد. به‌طور معمول در Substrate، از الگوریتم‌های اجماعی مانند Aura و Grandpa استفاده می‌شود. در این بخش می‌توان جزئیات مربوط به اجماع را مشخص کرد.

parameter_types! {
    pub const BlockHashCount: u64 = 2400;
}

pub struct CustomRuntime;
impl frame_system::Config for CustomRuntime {
    type BaseCallFilter = ();
    type BlockWeights = frame_system::limits::BlockWeights::default();
    type BlockLength = frame_system::limits::BlockLength::default();
    type DbWeight = pallet_transaction_payment::weights::SubstrateWeight<Runtime>;
    type Origin = Origin;
    type Index = u32;
    type Call = Call;
    type Event = Event;
    type PalletInfo = PalletInfo;
    type AccountData = pallet_balances::AccountData<Balance>;
    type OnNewAccount = ();
    type OnKilledAccount = ();
    type SystemWeightInfo = weights::SystemWeightInfo<Runtime>;
}

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

4. حساب‌های Genesis

در بخش بعدی، شما می‌توانید حساب‌های اولیه را که به‌طور پیش‌فرض در بلاکچین وجود دارند، تنظیم کنید. این حساب‌ها معمولاً به‌عنوان اعتبار برای شروع شبکه عمل می‌کنند.

pub fn initial_authorities() -> Vec<(AccountId, AuraId)> {
    vec![
        (ALICE.into(), AURA.into()),
        (BOB.into(), AURA.into())
    ]
}

در اینجا، initial_authorities لیستی از حساب‌های اولیه شبکه را تنظیم می‌کند که می‌توانند اعتبار و مجوزهای مختلفی داشته باشند.


۳. نحوه استفاده از chain_spec.rs

برای استفاده از فایل chain_spec.rs، شما باید در ابتدا این فایل را در تنظیمات گره خود وارد کنید و از آن برای پیکربندی پارامترهای شبکه استفاده نمایید.

به‌عنوان مثال، پس از تنظیم chain_spec.rs و راه‌اندازی گره، می‌توانید با استفاده از این فایل تنظیمات شبکه خود را در گره Substrate اعمال کنید.

use node_template_runtime::{self, opaque::Block, Runtime};
use sc_service::{Configuration, ChainSpec};

pub fn new_chain_spec() -> Result<ChainSpec, String> {
    Ok(ChainSpec::from_genesis(
        "My Substrate Blockchain",
        "my_chain",
        Vec::new(),
        genesis_config,
        vec![],
        None,
    ))
}

در اینجا، با استفاده از تابع from_genesis، شما می‌توانید شبکه خود را با تنظیمات اولیه پیکربندی کنید.


۴. راه‌اندازی شبکه با chain_spec.rs

پس از تکمیل پیکربندی‌های chain_spec.rs و تنظیم پارامترهای مختلف، می‌توانید گره خود را راه‌اندازی کنید. برای انجام این کار، باید از ابزارهای موجود در Substrate مانند substrate CLI استفاده کنید.

substrate --chain ./path/to/chain_spec.json --dev

در این دستور، با استفاده از فایل chain_spec.json که شامل تنظیمات و مشخصات شبکه است، گره را راه‌اندازی می‌کنید.


جمع‌بندی

فایل chain_spec.rs در پروژه‌های Substrate برای پیکربندی شبکه بلاکچین از جمله تنظیمات اجماع، حساب‌های اولیه، و نودهای راه‌اندازی مورد استفاده قرار می‌گیرد. این فایل به شما این امکان را می‌دهد که شبکه خود را با تنظیمات خاص راه‌اندازی کرده و آن را به دلخواه خود شخصی‌سازی کنید. در این بخش، یاد گرفتیم که چگونه می‌توانیم با استفاده از chain_spec.rs شبکه بلاکچین خود را تنظیم کرده و آن را با استفاده از ابزارهای مختلف راه‌اندازی کنیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه کامپایل و اجرای Node Template” subtitle=”توضیحات کامل”]برای کامپایل و اجرای پروژه Substrate Node Template، باید چندین مرحله را دنبال کنید. این مراحل شامل کامپایل پروژه، ایجاد فایل‌های باینری و سپس اجرای نود با استفاده از ابزارهایی است که در Substrate فراهم شده است. در این بخش، ما مراحل گام‌به‌گام را برای شما توضیح خواهیم داد.


۱. کامپایل پروژه Substrate Node Template

پس از دریافت و پیکربندی پروژه Substrate Node Template، شما نیاز به کامپایل پروژه دارید. برای این کار، باید از ابزار cargo استفاده کنید که به‌صورت پیش‌فرض در Rust نصب شده است.

1.1. اجرای دستور کامپایل

در ابتدا وارد مسیر اصلی پروژه که شامل فایل Cargo.toml است شوید. سپس دستور زیر را برای کامپایل پروژه وارد کنید:

cargo build --release

در این دستور:

  • cargo build برای کامپایل پروژه است.
  • --release باعث می‌شود که کامپایل در حالت بهینه‌سازی شده (Release Mode) انجام شود. این حالت عملکرد بهتری در اجرای برنامه ایجاد می‌کند.
1.2. محل ذخیره فایل‌های باینری

پس از موفقیت‌آمیز بودن کامپایل، فایل‌های باینری کامپایل شده در مسیر target/release/ ذخیره می‌شوند. این فایل‌ها شامل برنامه‌های اجرایی برای اجرای گره (Node) خواهند بود.

برای مثال، پس از کامپایل موفق، می‌توانید فایل‌های اجرایی مانند substrate را در مسیر زیر مشاهده کنید:

target/release/substrate

۲. اجرای Node Template

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

2.1. اجرای نود در حالت توسعه (Development Mode)

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

./target/release/substrate --dev

در این دستور:

  • --dev باعث می‌شود که شبکه در حالت توسعه (Development Mode) اجرا شود که شامل یک گره محلی است و همه پارامترها به‌صورت پیش‌فرض تنظیم می‌شوند.
2.2. اجرای نود با استفاده از فایل Chain Spec سفارشی

اگر شما یک فایل پیکربندی شبکه (Chain Spec) سفارشی ایجاد کرده‌اید، می‌توانید از آن برای راه‌اندازی گره استفاده کنید. به‌عنوان مثال، اگر فایل پیکربندی شما در مسیر ./path/to/chain_spec.json باشد، می‌توانید دستور زیر را وارد کنید:

./target/release/substrate --chain ./path/to/chain_spec.json

در اینجا، شما می‌توانید از فایل chain_spec.json برای پیکربندی خاص شبکه خود استفاده کنید.

2.3. اجرای نود با نودهای راه‌اندازی (Bootnodes)

اگر بخواهید نود خود را با نودهای راه‌اندازی خاصی (bootnodes) راه‌اندازی کنید، می‌توانید این نودها را در دستور وارد کنید. برای مثال:

./target/release/substrate --chain ./path/to/chain_spec.json --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/12D3KooWJf9c5LkEnj7sdaQajYAh7v6cUp5QyBGaQgFDoHseMsFB5q9pkVpmdYp3T4yD3qKp43FFz37EYdyfwfqF

در اینجا، --bootnodes به شما اجازه می‌دهد که نودهای راه‌اندازی خود را تعیین کنید.


۳. بررسی وضعیت گره

پس از راه‌اندازی گره، می‌توانید از ابزارهای مختلف برای بررسی وضعیت گره استفاده کنید.

3.1. مشاهده لاگ‌های گره

برای مشاهده لاگ‌های مربوط به گره، کافی است دستور زیر را وارد کنید:

tail -f ~/.local/share/substrate/chains/dev/db/rocksdb/LOG

این دستور لاگ‌های اجرایی گره را در زمان واقعی به شما نمایش می‌دهد.

3.2. اتصال به گره

برای اتصال به گره و انجام تراکنش‌ها یا درخواست‌های مختلف، می‌توانید از ابزار Polkadot-JS Apps استفاده کنید که رابط گرافیکی برای تعامل با بلاکچین است. آدرس دسترسی به این رابط معمولاً http://localhost:8000 خواهد بود.


جمع‌بندی

برای کامپایل و اجرای پروژه Substrate Node Template، ابتدا باید پروژه را با استفاده از دستور cargo build --release کامپایل کنید. پس از کامپایل موفق، می‌توانید از فایل‌های باینری موجود در مسیر target/release/ برای اجرای گره استفاده کنید. اجرای گره با دستور substrate --dev در حالت توسعه و یا با استفاده از فایل پیکربندی سفارشی قابل انجام است. همچنین، می‌توانید وضعیت گره را با استفاده از لاگ‌ها و ابزارهای گرافیکی مانند Polkadot-JS Apps بررسی کنید.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. اجرای اولین بلاکچین با Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”راه‌اندازی یک نود محلی و بررسی لاگ‌ها” subtitle=”توضیحات کامل”]برای راه‌اندازی یک نود محلی در Substrate و بررسی لاگ‌های آن، باید گام‌های خاصی را دنبال کنید. در این بخش، نحوه راه‌اندازی نود محلی و استفاده از لاگ‌ها برای نظارت بر وضعیت گره تشریح خواهد شد.


۱. راه‌اندازی نود محلی در حالت توسعه (Development Mode)

برای راه‌اندازی یک نود محلی در حالت توسعه، کافی است از فایل باینری که قبلاً کامپایل کرده‌ایم استفاده کنیم. حالت توسعه (Development Mode) برای تست و اجرای سریع شبکه بلاکچین‌های مبتنی بر Substrate بسیار مناسب است.

1.1. اجرای نود در حالت توسعه

برای اجرای نود در حالت توسعه، دستور زیر را وارد کنید:

./target/release/substrate --dev

در این دستور:

  • ./target/release/substrate مسیر فایل باینری گره است که پس از کامپایل در مسیر target/release/ ذخیره شده است.
  • --dev به گره اعلام می‌کند که در حالت توسعه اجرا شود.

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

1.2. راه‌اندازی نود با پیکربندی سفارشی (اختیاری)

اگر قصد دارید نود خود را با یک فایل پیکربندی سفارشی (Chain Spec) راه‌اندازی کنید، می‌توانید دستور زیر را وارد کنید:

./target/release/substrate --chain ./path/to/chain_spec.json

در اینجا، --chain فایل پیکربندی شبکه (chain spec) را مشخص می‌کند. شما می‌توانید این فایل را برای تنظیمات خاص شبکه خود مانند نام بلاکچین، پارامترهای اجماع و موارد دیگر ایجاد کنید.


۲. بررسی وضعیت نود از طریق لاگ‌ها

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

2.1. مشاهده لاگ‌های گره در حین اجرا

برای مشاهده لاگ‌های گره در حین اجرا، می‌توانید از دستور زیر برای مشاهده لاگ‌ها استفاده کنید:

tail -f ~/.local/share/substrate/chains/dev/db/rocksdb/LOG

در این دستور:

  • tail -f به شما امکان می‌دهد که به‌صورت زنده (real-time) لاگ‌ها را مشاهده کنید.
  • ~/.local/share/substrate/chains/dev/db/rocksdb/LOG مسیر پیش‌فرض فایل‌های لاگ گره در حالت توسعه است. در صورتی که از تنظیمات متفاوتی استفاده کرده باشید، این مسیر ممکن است متفاوت باشد.

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

2.2. بررسی لاگ‌ها در حالت “جلوگیری از ثبت”

اگر تمایل دارید که فقط قسمت‌های خاصی از لاگ‌ها را مشاهده کنید، می‌توانید از فیلترهای مختلف استفاده کنید. به‌عنوان مثال، برای مشاهده فقط خطوطی که شامل خطا هستند، از دستور زیر استفاده کنید:

grep "error" ~/.local/share/substrate/chains/dev/db/rocksdb/LOG

در این دستور:

  • grep "error" برای جستجوی کلمه “error” در لاگ‌ها استفاده می‌شود. این به شما کمک می‌کند که فقط خطاهای موجود در لاگ‌ها را مشاهده کنید.
2.3. استفاده از دستور substrate برای مشاهده وضعیت گره

برای بررسی وضعیت گره، می‌توانید از دستور زیر استفاده کنید که به شما اطلاعات مفیدی در خصوص وضعیت گره و شبکه می‌دهد:

./target/release/substrate --help

این دستور به شما کمک می‌کند تا از گزینه‌ها و پارامترهای مختلف برای تعامل با نود استفاده کنید. دستور --help تمامی گزینه‌های قابل استفاده و تنظیمات گره را نمایش می‌دهد.


جمع‌بندی

برای راه‌اندازی یک نود محلی در Substrate، ابتدا باید گره را در حالت توسعه با استفاده از دستور ./target/release/substrate --dev اجرا کنید. سپس می‌توانید با استفاده از دستوراتی همچون tail -f لاگ‌های نود را به‌صورت زنده مشاهده کرده و وضعیت گره خود را بررسی کنید. این فرآیند به شما امکان می‌دهد که عملکرد گره خود را نظارت کنید و در صورت نیاز به اشکال‌زدایی، به اطلاعات مفیدی دسترسی داشته باشید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعامل با بلاکچین از طریق Substrate UI” subtitle=”توضیحات کامل”]برای تعامل با بلاکچین‌های مبتنی بر Substrate، می‌توان از رابط کاربری (UI) استفاده کرد که دسترسی آسان‌تری به داده‌ها، تراکنش‌ها و سایر اجزای شبکه فراهم می‌آورد. این رابط کاربری معمولاً شامل داشبوردهایی برای مشاهده وضعیت شبکه، بلاک‌ها، تراکنش‌ها و بسیاری از اطلاعات دیگر است. در این بخش، نحوه تعامل با بلاکچین‌های ساخته شده با استفاده از Substrate از طریق UI را بررسی خواهیم کرد.


۱. استفاده از Substrate Front-End Template

برای راه‌اندازی یک رابط کاربری برای تعامل با بلاکچین ساخته شده با Substrate، می‌توان از Substrate Front-End Template استفاده کرد که یک پروژه React است. این پروژه به‌طور پیش‌فرض برای تعامل با بلاکچین‌های Substrate پیکربندی شده است.

1.1. دریافت Substrate Front-End Template

برای دریافت Substrate Front-End Template، ابتدا باید به مخزن GitHub آن بروید و آن را کلون کنید:

git clone https://github.com/substrate-developer-hub/substrate-front-end-template
cd substrate-front-end-template

پس از کلون کردن پروژه، باید وابستگی‌ها را با استفاده از دستور زیر نصب کنید:

npm install

این دستور تمامی بسته‌ها و وابستگی‌های مورد نیاز را برای پروژه نصب می‌کند.

1.2. راه‌اندازی رابط کاربری

برای راه‌اندازی رابط کاربری و اجرای آن در محیط محلی، دستور زیر را وارد کنید:

npm start

این دستور سرور محلی React را راه‌اندازی می‌کند و رابط کاربری را در مرورگر شما در آدرس http://localhost:3000 نمایش می‌دهد. حالا شما می‌توانید از طریق این رابط با بلاکچین خود تعامل کنید.


۲. اتصال به بلاکچین از طریق Substrate UI

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

2.1. تنظیم URL گره در Substrate Front-End Template

برای تنظیم URL گره، ابتدا باید فایل src/config.js را ویرایش کنید. در این فایل، پارامترهایی برای تنظیمات بلاکچین و گره‌ها وجود دارد.

در فایل src/config.js، قسمت زیر را پیدا کنید:

export const WS_URL = 'wss://your-node-url';

در اینجا باید your-node-url را با URL گره بلاکچین خود جایگزین کنید. برای مثال، اگر گره شما به صورت محلی اجرا می‌شود، URL به این شکل خواهد بود:

export const WS_URL = 'ws://127.0.0.1:9944';

این تنظیمات به رابط کاربری این امکان را می‌دهند که به گره بلاکچین متصل شود و با آن ارتباط برقرار کند.

2.2. بررسی وضعیت بلاکچین در رابط کاربری

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

  • آخرین بلاک: شما می‌توانید آخرین بلاک‌ها را مشاهده کنید.
  • تراکنش‌ها: تراکنش‌های انجام‌شده در شبکه.
  • موجودی حساب‌ها: موجودی‌ حساب‌های مختلف در شبکه.
  • پیشنهادات جدید: اطلاعات مربوط به تراکنش‌ها و پیشنهادات جدید.

۳. تعامل با بلاکچین از طریق Substrate UI

برای انجام عملیات مختلف مانند ارسال تراکنش‌ها، مشاهده بلاک‌ها و تعامل با قراردادهای هوشمند، می‌توانید از UI استفاده کنید.

3.1. ارسال تراکنش‌ها از طریق UI

یکی از ویژگی‌های مهم رابط کاربری Substrate، امکان ارسال تراکنش‌ها به شبکه است. برای این کار، می‌توانید از فرم‌های تعاملی موجود در رابط کاربری استفاده کنید:

  • وارد کردن آدرس فرستنده و گیرنده
  • تعیین مقدار موجودی برای انتقال
  • امضای تراکنش با کلید خصوصی شما

پس از تکمیل فرم، شما می‌توانید با فشار دادن دکمه ارسال، تراکنش خود را به شبکه ارسال کنید. رابط کاربری با استفاده از وب‌سوکت‌ها (WebSockets) به گره متصل است و تراکنش به‌طور آنی ارسال می‌شود.

3.2. مشاهده بلاک‌ها و تراکنش‌ها

در قسمت “Explorer” یا مشابه آن در رابط کاربری، می‌توانید بلاک‌ها و تراکنش‌های شبکه را مشاهده کنید. این اطلاعات به شما کمک می‌کنند تا وضعیت شبکه را دنبال کنید و تراکنش‌ها و بلاک‌ها را بررسی کنید.


جمع‌بندی

با استفاده از Substrate Front-End Template، شما می‌توانید به راحتی یک رابط کاربری برای تعامل با بلاکچین‌های مبتنی بر Substrate راه‌اندازی کنید. این رابط کاربری امکان اتصال به گره، مشاهده وضعیت شبکه، ارسال تراکنش‌ها و تعامل با بلاکچین را فراهم می‌آورد. در این بخش، نحوه راه‌اندازی و استفاده از این رابط کاربری را توضیح دادیم. شما می‌توانید با تنظیم URL گره و استفاده از ابزارهای UI، به‌طور مؤثر با بلاکچین Substrate خود تعامل داشته باشید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اجرای تراکنش‌های آزمایشی در شبکه” subtitle=”توضیحات کامل”]اجرای تراکنش‌های آزمایشی یکی از مراحل مهم در فرآیند توسعه و آزمایش بلاکچین‌های مبتنی بر Substrate است. این تراکنش‌ها به شما این امکان را می‌دهند تا عملکرد و ویژگی‌های شبکه خود را قبل از اجرای آن در محیط واقعی بررسی کنید. در این بخش، نحوه اجرای تراکنش‌های آزمایشی در شبکه Substrate را بررسی خواهیم کرد.


۱. استفاده از شبکه محلی (Local Network)

برای آزمایش تراکنش‌ها به صورت محلی، باید ابتدا یک نود محلی Substrate راه‌اندازی کنید. این نود به شما این امکان را می‌دهد که بدون نیاز به شبکه عمومی، تراکنش‌ها را آزمایش کرده و عملکرد شبکه خود را بررسی کنید.

1.1. راه‌اندازی نود محلی

برای راه‌اندازی نود محلی Substrate از طریق substrate-node-template، ابتدا باید این دستور را در ترمینال خود اجرا کنید:

cargo run -- --dev

این دستور یک نود محلی را در حالت توسعه (development) راه‌اندازی می‌کند که به‌طور خودکار یک بلاکچین جدید ایجاد می‌کند و آن را به شبکه متصل می‌سازد. این نود محلی به شما این امکان را می‌دهد که تراکنش‌های آزمایشی را ارسال کنید.


۲. استفاده از Substrate Front-End Template

پس از راه‌اندازی نود محلی، می‌توانید از Substrate Front-End Template برای ارسال تراکنش‌ها به شبکه محلی استفاده کنید. این رابط کاربری به شما این امکان را می‌دهد که تراکنش‌ها را به‌سادگی ارسال کرده و وضعیت آنها را بررسی کنید.

2.1. تنظیم URL گره در Substrate Front-End Template

برای اتصال به گره محلی، فایل src/config.js را ویرایش کرده و URL گره را به آدرس محلی تغییر دهید:

export const WS_URL = 'ws://127.0.0.1:9944';

پس از تغییر این تنظیم، رابط کاربری را با استفاده از دستور زیر راه‌اندازی کنید:

npm start

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


۳. ارسال تراکنش آزمایشی

برای ارسال تراکنش آزمایشی، مراحل زیر را دنبال کنید:

3.1. ورود به رابط کاربری

پس از راه‌اندازی Substrate Front-End Template، مرورگر خود را باز کرده و به آدرس http://localhost:3000 بروید.

3.2. ورود به کیف پول

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

3.3. ارسال تراکنش

در بخش “Transfer” یا “Send Transaction”، شما می‌توانید آدرس فرستنده و گیرنده را وارد کرده و مقدار تراکنش را تعیین کنید. برای ارسال تراکنش:

  • آدرس فرستنده: آدرس کیف پول خود را وارد کنید.
  • آدرس گیرنده: آدرس مقصدی که می‌خواهید توکن‌ها را به آن ارسال کنید.
  • مقدار: مقدار توکن‌هایی که قصد دارید ارسال کنید.

پس از وارد کردن این اطلاعات، با فشار دادن دکمه ارسال، تراکنش به شبکه محلی ارسال می‌شود.


۴. بررسی وضعیت تراکنش

پس از ارسال تراکنش، شما می‌توانید وضعیت آن را در رابط کاربری بررسی کنید. در این بخش، جزئیات تراکنش‌هایی که در شبکه انجام شده‌اند، از جمله شناسه تراکنش (TX Hash) و وضعیت تأیید تراکنش قابل مشاهده است.

4.1. مشاهده تاریخچه تراکنش‌ها

در رابط کاربری، بخش‌هایی برای مشاهده تاریخچه تراکنش‌ها و بلاک‌ها وجود دارد. شما می‌توانید اطلاعات مربوط به تراکنش‌های انجام‌شده را مشاهده کرده و جزئیات هر تراکنش را بررسی کنید.


۵. استفاده از استراتژی‌های توسعه

در محیط‌های توسعه، معمولاً برای تست بهتر و بهینه‌سازی شبکه، از استراتژی‌های مختلفی استفاده می‌شود که عبارتند از:

  • استفاده از فریم‌ورک‌های تست: برای انجام تست‌های خودکار و دقیق از بلاکچین، می‌توانید از فریم‌ورک‌های تست مانند Substrate’s pallet framework استفاده کنید.
  • ساخت بلاک‌ها به صورت دستی: با استفاده از ابزارهایی مانند polkadot.js، شما می‌توانید بلاک‌ها را به صورت دستی ایجاد کرده و سپس آنها را به شبکه ارسال کنید.

جمع‌بندی

اجرای تراکنش‌های آزمایشی در شبکه Substrate یکی از گام‌های کلیدی در فرآیند توسعه بلاکچین است. با راه‌اندازی یک نود محلی و استفاده از رابط کاربری Substrate Front-End Template، می‌توانید به راحتی تراکنش‌ها را ارسال کرده و وضعیت آنها را بررسی کنید. این فرآیند به شما این امکان را می‌دهد که پیش از انتشار بلاکچین در شبکه اصلی، عملکرد آن را به‌طور کامل ارزیابی کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از Subkey برای ایجاد کلیدهای جدید” subtitle=”توضیحات کامل”]Subkey یکی از ابزارهای مفید در اکوسیستم Substrate است که به شما این امکان را می‌دهد تا کلیدهای عمومی و خصوصی را به‌سادگی ایجاد کنید. این ابزار به‌ویژه برای مدیریت کیف پول‌ها و کلیدها در فرآیند توسعه و آزمایش بلاکچین Substrate کاربرد دارد. در این بخش، نحوه استفاده از subkey برای ایجاد کلیدهای جدید و نحوه مدیریت آنها را بررسی خواهیم کرد.


۱. نصب Subkey

برای استفاده از subkey، ابتدا باید این ابزار را نصب کنید. به طور معمول، subkey همراه با پکیج substrate ارائه می‌شود، اما در صورت نیاز می‌توانید آن را به طور جداگانه از طریق cargo نصب کنید.

1.1. نصب از طریق Cargo

برای نصب subkey با استفاده از cargo، دستور زیر را در ترمینال وارد کنید:

cargo install --force subkey

این دستور باعث نصب آخرین نسخه‌ی subkey در سیستم شما می‌شود.


۲. ایجاد کلیدهای جدید با استفاده از Subkey

بعد از نصب ابزار subkey، می‌توانید از آن برای ایجاد کلیدهای جدید (عمومی و خصوصی) استفاده کنید.

2.1. ایجاد یک جفت کلید جدید

برای ایجاد یک جفت کلید جدید (کلید عمومی و خصوصی)، دستور زیر را وارد کنید:

subkey generate

این دستور یک جفت کلید جدید به‌طور تصادفی ایجاد کرده و آن را در قالب‌های مختلف (کلید عمومی، کلید خصوصی، و آدرس کیف پول) نمایش می‌دهد. نمونه خروجی به شکل زیر خواهد بود:

Secret seed: 0x... (private key)
Public key (ss58): 5... (public key)
Account ID (ss58): 5...
  • Secret seed: کلید خصوصی یا همان Seed phrase که برای بازسازی کلیدها استفاده می‌شود.
  • Public key (ss58): کلید عمومی که برای شناسایی حساب در شبکه استفاده می‌شود.
  • Account ID (ss58): آدرس حساب که قابل استفاده در بلاکچین است.
2.2. ذخیره‌سازی کلیدهای خصوصی

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


۳. ایجاد و استفاده از آدرس‌های مختلف

با استفاده از subkey، می‌توانید آدرس‌های مختلف برای حساب‌های مختلف ایجاد کنید و از آن‌ها در شبکه بلاکچین Substrate استفاده کنید.

3.1. ایجاد آدرس‌های مختلف

برای ایجاد آدرس‌های مختلف از همان جفت کلید، می‌توانید از دستور زیر استفاده کنید که در آن مشخص می‌کنید که آدرس در کدام شبکه استفاده شود:

subkey public-key 0x... --address-type 42

در این دستور، 0x... کلید عمومی است که به‌وسیله دستور قبلی تولید کرده‌اید و --address-type نوع آدرس را مشخص می‌کند. در اینجا، 42 برای شبکه‌های خاصی مانند Polkadot یا Kusama استفاده می‌شود.

3.2. تبدیل کلید عمومی به آدرس

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

subkey inspect --address-type 42 0x...

در این دستور، 0x... باید کلید عمومی شما باشد که آن را به آدرس تبدیل می‌کند. آدرس ایجاد شده به‌صورت SS58 نمایش داده می‌شود.


۴. مشاهده اطلاعات مربوط به کلیدها

برای مشاهده اطلاعات مربوط به یک جفت کلید، از دستور زیر استفاده کنید:

subkey inspect 0x...

این دستور اطلاعاتی همچون آدرس‌ها و جزئیات مربوط به کلید عمومی و خصوصی را نمایش می‌دهد.


۵. استفاده از کلیدها در تراکنش‌ها

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


جمع‌بندی

استفاده از subkey یکی از روش‌های ساده و موثر برای مدیریت و ایجاد جفت کلیدهای عمومی و خصوصی در بلاکچین‌های مبتنی بر Substrate است. با استفاده از این ابزار، شما می‌توانید به راحتی کلیدهای جدید ایجاد کنید، آن‌ها را به آدرس‌های مختلف تبدیل کنید و از آن‌ها برای تراکنش‌ها و توسعه بلاکچین‌های Substrate استفاده کنید. این ابزار برای توسعه‌دهندگان و آزمایش‌کنندگان بلاکچین بسیار مفید است و به‌راحتی می‌توان از آن برای مدیریت کیف پول‌ها و انجام تراکنش‌ها استفاده کرد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. مدیریت و تنظیمات نود در Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”راه‌اندازی Full Node و Archive Node” subtitle=”توضیحات کامل”]در این بخش به بررسی نحوه راه‌اندازی یک Full Node و Archive Node در بلاکچین Substrate پرداخته خواهد شد. این دو نوع نود برای اهداف مختلف در شبکه‌های بلاکچین طراحی شده‌اند و تفاوت‌های خاصی در عملکرد و مصرف منابع دارند.


۱. تفاوت‌های بین Full Node و Archive Node

قبل از شروع به راه‌اندازی این نودها، باید با تفاوت‌های اصلی آن‌ها آشنا شوید:

  • Full Node:
    • یک Full Node اطلاعات کاملی از بلاکچین را ذخیره می‌کند، اما اطلاعات بلاک‌های قدیمی‌تر را به‌طور پیش‌فرض فشرده یا خلاصه‌شده ذخیره می‌کند.
    • برای اعتبارسنجی و تایید تراکنش‌ها به‌طور کامل عمل می‌کند.
    • مصرف منابع کمتر از Archive Node دارد.
  • Archive Node:
    • Archive Node تمامی بلاک‌های بلاکچین را از ابتدا تا کنون به‌طور کامل ذخیره می‌کند.
    • اطلاعات هر بلاک (به‌ویژه داده‌های دقیق تراکنش‌ها) را به‌صورت کامل و بدون فشرده‌سازی نگهداری می‌کند.
    • به‌دلیل ذخیره‌سازی تمامی داده‌ها، مصرف منابع بسیار بیشتری نسبت به Full Node دارد.

۲. راه‌اندازی Full Node

برای راه‌اندازی یک Full Node در شبکه Substrate، کافی است که از فایل‌های تنظیمات پیش‌فرض استفاده کرده و نود خود را با دستورات زیر راه‌اندازی کنید.

2.1. دانلود و کامپایل Substrate Node

برای راه‌اندازی یک Full Node، ابتدا باید پکیج Substrate را دانلود و کامپایل کنید.

  1. ابتدا محیط کاری را تنظیم کنید:
    mkdir substrate-node
    cd substrate-node
    
  2. سپس، کد منبع Substrate را از GitHub دریافت کنید:
    git clone https://github.com/paritytech/substrate.git
    cd substrate
    
  3. برای کامپایل Substrate:
    cargo build --release
    

2.2. اجرای Full Node

برای اجرای یک Full Node، از دستور زیر استفاده کنید:

./target/release/node-template --chain=local --validator --name FullNode
  • --chain=local: مشخص می‌کند که از شبکه محلی استفاده می‌شود.
  • --validator: نود به‌عنوان یک نود اعتبارسنج عمل می‌کند.
  • --name FullNode: به نود یک نام اختصاص می‌دهد.

با این دستور، Full Node شما به شبکه متصل می‌شود و اطلاعات بلاک‌ها را ذخیره می‌کند.


۳. راه‌اندازی Archive Node

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

3.1. اجرای Archive Node

برای اجرای یک Archive Node، باید از دستور زیر استفاده کنید که باعث می‌شود تمامی بلاک‌ها ذخیره شوند:

./target/release/node-template --chain=local --validator --name ArchiveNode --pruning=archive
  • --pruning=archive: این گزینه مشخص می‌کند که بلاک‌ها به‌صورت کامل ذخیره شوند و هیچ‌گونه فشرده‌سازی یا خلاصه‌سازی در داده‌ها اعمال نشود.
  • --validator: نود به‌عنوان اعتبارسنج عمل می‌کند.
  • --name ArchiveNode: به نود یک نام اختصاص می‌دهد.

این تنظیمات باعث می‌شود نود شما به‌عنوان یک Archive Node عمل کرده و تمامی داده‌های بلاک‌ها را ذخیره کند.


۴. پیکربندی ذخیره‌سازی داده‌ها

برای بهینه‌سازی عملکرد و ذخیره‌سازی داده‌ها، شما می‌توانید از پیکربندی‌های مختلف استفاده کنید. به‌ویژه در Archive Node، به‌دلیل ذخیره‌سازی تمامی بلاک‌ها، مصرف دیسک بالا خواهد بود.

4.1. تنظیمات pruning

در Substrate، سه حالت ذخیره‌سازی برای داده‌ها وجود دارد:

  • pruning=archive: تمامی داده‌ها ذخیره می‌شوند (برای Archive Node).
  • pruning=blockbody: فقط داده‌های مربوط به بدنه بلاک‌ها ذخیره می‌شود.
  • pruning=state: فقط وضعیت آخرین بلاک‌ها ذخیره می‌شود.

در Full Node معمولاً از حالت pruning=blockbody یا pruning=state استفاده می‌شود.

4.2. تنظیمات فایل node-template.toml

برای تنظیمات دقیق‌تر ذخیره‌سازی و عملکرد نودها، می‌توانید فایل node-template.toml را ویرایش کنید.

مسیر فایل: ./node-template/config/node-template.toml

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


۵. بررسی عملکرد نودها

برای بررسی وضعیت نود و لاگ‌های آن، از دستور زیر استفاده کنید:

tail -f ~/.local/share/substrate-node-template/node/ FullNode/logs/*.log

این دستور لاگ‌های مربوط به نود Full Node را نمایش می‌دهد و به شما کمک می‌کند که وضعیت نود را در زمان اجرا پیگیری کنید.


۶. اتصال به شبکه‌های عمومی

برای اتصال به شبکه‌های عمومی (مثل Polkadot یا Kusama)، کافی است که آدرس شبکه را در دستور اجرا مشخص کنید.

مثال:

./target/release/node-template --chain=polkadot --validator --name FullNode

در اینجا، به جای local از polkadot استفاده شده است تا نود به شبکه Polkadot متصل شود.


جمع‌بندی

در این بخش، نحوه راه‌اندازی Full Node و Archive Node در Substrate بررسی شد. نودهای Full و Archive هرکدام ویژگی‌ها و مزایای خاص خود را دارند و بسته به نیاز شما می‌توانید از هرکدام استفاده کنید. Full Node برای اعتبارسنجی تراکنش‌ها و عملیات بلاکچین کافی است، در حالی که Archive Node برای ذخیره‌سازی تاریخچه کامل بلاک‌ها و اطلاعات دقیق‌تری از شبکه مفید است. تنظیمات ذخیره‌سازی و فشرده‌سازی در هر دو نوع نود به شما این امکان را می‌دهد که منابع سیستم را بهینه کنید و عملکرد نود را متناسب با نیازهای خود تنظیم نمایید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”اتصال به شبکه‌های آزمایشی Substrate” subtitle=”توضیحات کامل”]برای اتصال به شبکه‌های آزمایشی Substrate، شما نیاز به نصب و پیکربندی یک نود محلی دارید که بتواند به یکی از شبکه‌های آزمایشی Substrate متصل شود. در این بخش، تمام مراحل و دستورات لازم برای اتصال به شبکه‌های آزمایشی Substrate را توضیح خواهیم داد. همچنین، مسیر فایل‌ها و پیکربندی‌ها را نیز معرفی خواهیم کرد.

مراحل اتصال به شبکه‌های آزمایشی Substrate:
  1. نصب Substrate Node Template: ابتدا باید اطمینان حاصل کنید که Substrate Node Template به درستی روی سیستم شما نصب شده است. برای نصب این قالب، دستور زیر را اجرا کنید:
    git clone https://github.com/substrate-developer-hub/substrate-node-template
    cd substrate-node-template
    cargo build --release
    

    مسیر پروژه به صورت پیش‌فرض در دایرکتوری substrate-node-template قرار خواهد گرفت. حالا با استفاده از دستور بالا پروژه را دانلود کرده و کامپایل می‌کنید.

  2. پیکربندی فایل Chain Spec: برای اتصال به شبکه آزمایشی، باید فایل chain_spec.rs که تنظیمات شبکه را شامل می‌شود، پیکربندی کنید. این فایل معمولاً در مسیر node/src/chain_spec.rs قرار دارد. در این فایل، باید شبکه‌ای که قصد دارید به آن متصل شوید، مانند شبکه آزمایشی Kusama یا Polkadot را مشخص کنید.برای تغییر شبکه، به دنبال بخش زیر در فایل chain_spec.rs بگردید:
    pub fn development_config() -> ChainSpec {
        ChainSpec::from_genesis(
            "Development",
            "dev",
            ChainType::Development,
            move || {
                testnet_genesis(
                    // تنظیمات شبکه
                )
            },
            vec![],
            None,
            None,
            None,
        )
    }
    

    این بخش را برای شبکه آزمایشی خود به‌روز کنید. به‌عنوان مثال، برای اتصال به شبکه آزمایشی Kusama یا Polkadot، باید اطلاعات مربوط به شبکه آزمایشی را در این فایل وارد کنید.

  3. اجرای نود و اتصال به شبکه آزمایشی: پس از پیکربندی فایل chain_spec.rs، می‌توانید نود خود را برای اتصال به شبکه آزمایشی اجرا کنید. برای این کار، از دستور زیر استفاده کنید:
    ./target/release/node-template --chain <chain_spec> --validator
    

    در این دستور، <chain_spec> باید به مسیر فایل پیکربندی که مشخص کرده‌اید اشاره کند. این دستور نود را در حالت اعتبارسنجی (validator) اجرا می‌کند و به شبکه آزمایشی متصل می‌شود.

  4. مشاهده وضعیت شبکه: برای مشاهده وضعیت شبکه و لاگ‌های مربوط به نود، می‌توانید از دستور زیر استفاده کنید:
    tail -f target/debug/node-template/node-template.log
    

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

  5. استفاده از کیف پول برای ارسال تراکنش‌ها: حالا که نود شما به شبکه آزمایشی متصل است، می‌توانید از کیف پول‌هایی مانند Polkadot.js برای ارسال تراکنش‌ها و تعامل با شبکه استفاده کنید. برای ارسال تراکنش‌ها و بررسی وضعیت بلاک‌ها، می‌توانید به وب‌سایت Polkadot.js مراجعه کنید و به نود خود متصل شوید.

جمع‌بندی

در این بخش، مراحل نصب، پیکربندی و راه‌اندازی نود Substrate برای اتصال به شبکه‌های آزمایشی Substrate را بررسی کردیم. شما اکنون قادر خواهید بود نود خود را به یکی از شبکه‌های آزمایشی Substrate متصل کرده و با استفاده از ابزارهایی مانند Polkadot.js به شبکه دسترسی پیدا کنید و تراکنش‌ها را ارسال کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تنظیمات Chain Spec برای سفارشی‌سازی بلاکچین” subtitle=”توضیحات کامل”]ChainSpecدر Substrate، یک ساختار مهم است که تنظیمات اصلی بلاکچین شما را شامل می‌شود. این تنظیمات شامل اطلاعاتی درباره شبکه، نسل بلاک‌ها، تنظیمات اعتبارسنج‌ها، سیستم‌های حاکمیتی و بسیاری دیگر از پیکربندی‌های مهم است. شما می‌توانید با ویرایش ChainSpec، بلاکچین خود را سفارشی‌سازی کرده و پارامترهای مختلف را متناسب با نیازهای پروژه‌تان تنظیم کنید.

در این بخش، نحوه تنظیم و پیکربندی ChainSpec را به‌طور کامل بررسی خواهیم کرد و نحوه سفارشی‌سازی بلاکچین را از طریق تنظیمات آن توضیح خواهیم داد.

مراحل پیکربندی ChainSpec برای سفارشی‌سازی بلاکچین:
  1. مسیر فایل ChainSpec: فایل پیکربندی ChainSpec معمولاً در مسیر زیر در پروژه شما قرار دارد:
    node/src/chain_spec.rs
    

    این فایل شامل تنظیمات مختلف بلاکچین، مانند نام شبکه، نوع بلاکچین (توسعه، آزمایشی یا اصلی)، و اطلاعات ضروری برای اجرای بلاکچین است.

  2. تعریف شبکه در ChainSpec: یکی از اولین قسمت‌های پیکربندی در فایل chain_spec.rs، تعریف شبکه بلاکچین است. به‌طور پیش‌فرض، تنظیمات شبکه برای یک بلاکچین در حالت توسعه (development) و یا حالت آزمایشی (testnet) ارائه می‌شود. شما می‌توانید شبکه دلخواه خود را با ایجاد یک ChainSpec سفارشی بسازید.برای مثال، برای ساخت یک بلاکچین جدید با نام “MyChain” به‌صورت زیر عمل می‌کنیم:
    pub fn my_custom_chain_config() -> ChainSpec {
        ChainSpec::from_genesis(
            "MyChain",              // نام شبکه
            "mychain",              // شناسه شبکه
            ChainType::Live,        // نوع بلاکچین (حالت اصلی)
            move || {
                genesis_config(
                    // اطلاعات و تنظیمات ضروری برای بلاکچین
                )
            },
            vec![],                 // لیست اعتبارسنج‌ها
            None,                   // تنظیمات شبکه
            None,                   // پروتکل‌ها
            None,                   // اعتبارسنج‌ها و پیکربندی‌های اضافی
        )
    }
    

    در اینجا my_custom_chain_config یک بلاکچین جدید با نام “MyChain” و نوع ChainType::Live ایجاد می‌کند که برای یک شبکه اصلی استفاده خواهد شد.

  3. تعریف تنظیمات Genesis: تنظیمات Genesis برای تعیین وضعیت اولیه بلاکچین بسیار مهم است. در این مرحله شما می‌توانید حساب‌های اولیه، اعتبارسنج‌ها، و تراکنش‌های آغازین را تعریف کنید.در ادامه یک مثال از تعریف پیکربندی Genesis آورده شده است:
    fn genesis_config() -> GenesisConfig {
        GenesisConfig {
            frame_system: frame_system::GenesisConfig {
                code: wasm_binary_unwrap(),
                changes_trie_config: Some(ChangesTrieConfig::default()),
            },
            pallet_balances: pallet_balances::GenesisConfig {
                balances: vec![(ALICE, 100_000_000_000), (BOB, 50_000_000_000)],
            },
            pallet_staking: pallet_staking::GenesisConfig {
                validators: vec![(ALICE, 1_000_000_000), (BOB, 500_000_000)],
                ..Default::default()
            },
            // پیکربندی سایر پالت‌ها
            ..Default::default()
        }
    }
    

    در اینجا، برای پالت pallet_balances، دو حساب (ALICE و BOB) با مقادیر موجودی مختلف تعریف شده است. همچنین برای پالت pallet_staking، اعتبارسنج‌های اولیه (ALICE و BOB) با مقادیر استیکینگ تعیین شده‌اند.

  4. سفارشی‌سازی تنظیمات دیگر بلاکچین: شما می‌توانید تنظیمات دیگری را نیز برای بلاکچین خود سفارشی کنید. به‌عنوان مثال، می‌توانید پارامترهای زیر را تغییر دهید:
    • تعداد بلوک‌ها و تنظیمات مربوط به تایم‌لاین بلاکچین: در frame_system، شما می‌توانید زمان بین بلاک‌ها، زمان تایید تراکنش‌ها و دیگر تنظیمات مربوط به عملکرد بلاکچین را سفارشی کنید.
    • تنظیمات حاکمیتی: پالت‌های حاکمیتی مانند pallet_democracy، pallet_collective و دیگر پالت‌های حاکمیتی را می‌توان برای تعیین قوانین حاکمیتی شبکه سفارشی کرد.
    • مدیریت حساب‌ها و انتقال دارایی‌ها: پالت‌هایی مانند pallet_balances و pallet_assets برای تعریف حساب‌های مختلف و دارایی‌ها در بلاکچین استفاده می‌شوند.
  5. تنظیمات شبکه (Genesis): شما همچنین می‌توانید تنظیمات مرتبط با شبکه، مانند آدرس‌های اولیه و پروتکل‌های مخصوص شبکه را تعریف کنید. به‌عنوان مثال، اگر شما قصد دارید از یک سیستم مجوزدهی یا رمزنگاری خاص استفاده کنید، می‌توانید تنظیمات مربوط به آن را در این بخش انجام دهید.
  6. ایجاد ChainSpec از فایل Genesis: پس از انجام تغییرات در فایل chain_spec.rs و اطمینان از درست بودن تنظیمات، باید از آن برای راه‌اندازی بلاکچین استفاده کنید. شما می‌توانید از این ChainSpec برای راه‌اندازی نود خود با دستور زیر استفاده کنید:
    ./target/release/node-template --chain my_custom_chain_config.json --validator
    

    در این دستور، my_custom_chain_config.json باید مسیری باشد که فایل تنظیمات ChainSpec شما ذخیره شده است.

جمع‌بندی

در این بخش نحوه تنظیم و سفارشی‌سازی ChainSpec برای بلاکچین‌های مبتنی بر Substrate توضیح داده شد. این تنظیمات امکان تغییر و سفارشی‌سازی پارامترهای مختلف بلاکچین، از جمله تنظیمات Genesis، اعتبارسنج‌ها، شبکه و سیستم‌های حاکمیتی را فراهم می‌کنند. با پیکربندی مناسب این تنظیمات می‌توانید بلاکچینی متناسب با نیازهای خاص پروژه خود راه‌اندازی کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی نحوه ایجاد یک Genesis Block” subtitle=”توضیحات کامل”]در بلاکچین‌های مبتنی بر Substrate، بلاک Genesis به‌عنوان اولین بلاک از بلاکچین شناخته می‌شود که در آغاز راه‌اندازی شبکه تولید می‌شود. این بلاک معمولاً شامل اطلاعات پایه‌ای است که وضعیت اولیه بلاکچین را تعریف می‌کند، از جمله اطلاعات درباره حساب‌ها، اعتبارسنج‌ها، موجودی‌ها و دیگر تنظیمات اولیه شبکه. فرآیند ایجاد یک Genesis Block در Substrate به‌طور کامل قابل تنظیم است و در فایل‌های پیکربندی مشخصی مانند chain_spec.rs انجام می‌شود.

در این بخش، نحوه ایجاد و پیکربندی یک Genesis Block در بلاکچین‌های مبتنی بر Substrate به‌طور کامل توضیح داده می‌شود.

مراحل ایجاد Genesis Block در Substrate
  1. آشنایی با مفهوم Genesis Block: Genesis Block به‌عنوان اولین بلاک، وضعیت شبکه در ابتدای ایجاد بلاکچین را نشان می‌دهد. این بلاک اطلاعات اولیه‌ای شامل تنظیمات بلاکچین (مثل نام شبکه، هویت اعتبارسنج‌ها، تنظیمات staking و غیره) را در خود جای می‌دهد.
  2. پیکربندی ChainSpec و تعیین Genesis Block: برای ایجاد یک Genesis Block، ابتدا باید در فایل chain_spec.rs یک پیکربندی برای ChainSpec تعریف کنید. این پیکربندی شامل تمام تنظیمات مربوط به بلاکچین است و شامل مقادیر اولیه Genesis Block می‌شود.مسیر فایل chain_spec.rs در پروژه شما به‌طور معمول به شکل زیر است:
    node/src/chain_spec.rs
    

    برای ایجاد Genesis Block، شما باید GenesisConfig را تعریف کنید که در آن تمام پارامترهای لازم برای بلاک اول تنظیم می‌شوند.

  3. تعریف Genesis Block:به‌عنوان مثال، برای ایجاد یک Genesis Block که شامل حساب‌ها، اعتبارسنج‌ها و تنظیمات اولیه باشد، می‌توانید از کد زیر استفاده کنید:
    fn genesis_config() -> GenesisConfig {
        GenesisConfig {
            frame_system: frame_system::GenesisConfig {
                code: wasm_binary_unwrap(), // کد WebAssembly برای بلاکچین
                changes_trie_config: Some(ChangesTrieConfig::default()), // تنظیمات مربوط به درخت تغییرات
            },
            pallet_balances: pallet_balances::GenesisConfig {
                balances: vec![(ALICE, 100_000_000_000), (BOB, 50_000_000_000)], // حساب‌ها و موجودی‌ها
            },
            pallet_staking: pallet_staking::GenesisConfig {
                validators: vec![(ALICE, 1_000_000_000), (BOB, 500_000_000)], // اعتبارسنج‌ها و استیکینگ اولیه
                ..Default::default()
            },
            // سایر پالت‌ها و تنظیمات دلخواه
            ..Default::default()
        }
    }
    

    در این مثال:

    • frame_system::GenesisConfig: تنظیمات مربوط به سیستم بلاکچین، شامل کد بلاکچین (با استفاده از wasm_binary_unwrap()).
    • pallet_balances::GenesisConfig: اطلاعات مربوط به حساب‌های اولیه، مانند Alice و Bob با موجودی‌های مشخص.
    • pallet_staking::GenesisConfig: اعتبارسنج‌ها و مقدار استیکینگ اولیه که در بلاک Genesis تنظیم می‌شود.
  4. تنظیمات مربوط به اعتبارسنج‌ها و استیکینگ: در بلاک Genesis، معمولاً شما اعتبارسنج‌ها را مشخص می‌کنید. این اعتبارسنج‌ها در فرآیند اعتبارسنجی بلاک‌ها و تولید بلاک‌های جدید نقش دارند. به‌طور معمول، این اعتبارسنج‌ها باید مقداری از توکن‌های بلاکچین را در استیکینگ قفل کنند.برای مثال:
    pallet_staking: pallet_staking::GenesisConfig {
        validators: vec![(ALICE, 1_000_000_000), (BOB, 500_000_000)], // اعتبارسنج‌ها
        // تنظیمات دیگر پالت استیکینگ
        ..Default::default()
    },
    

    در اینجا ALICE و BOB به‌عنوان اعتبارسنج‌های اولیه معرفی شده‌اند و مقادیر استیکینگ برای آن‌ها تعیین شده است.

  5. تنظیمات سیستم و درخت تغییرات (Changes Trie): ChangesTrieConfig به شما این امکان را می‌دهد که تغییرات اعمال‌شده در شبکه را ذخیره کرده و بهینه‌سازی‌هایی برای حفظ وضعیت شبکه انجام دهید. این بخش می‌تواند بسته به نیاز شما تنظیم شود.
    frame_system: frame_system::GenesisConfig {
        code: wasm_binary_unwrap(),
        changes_trie_config: Some(ChangesTrieConfig::default()), // پیکربندی درخت تغییرات
    }
    
  6. استفاده از ChainSpec و راه‌اندازی نود: پس از انجام تنظیمات Genesis، شما می‌توانید از این پیکربندی برای راه‌اندازی بلاکچین استفاده کنید. برای راه‌اندازی بلاکچین با استفاده از ChainSpec سفارشی خود، دستور زیر را اجرا کنید:
    ./target/release/node-template --chain my_custom_chain_config.json --validator
    

    در اینجا:

    • my_custom_chain_config.json: مسیری به فایل ChainSpec سفارشی شما است که شامل تنظیمات Genesis بلاک است.
    • --validator: این گزینه بلاکچین شما را به‌عنوان یک اعتبارسنج راه‌اندازی می‌کند.
  7. بررسی و اعتبارسنجی Genesis Block: پس از راه‌اندازی نود، شما می‌توانید با استفاده از ابزارهایی مانند Polkadot-JS یا Substrate UI به شبکه متصل شده و Genesis Block و پارامترهای آن را بررسی کنید. این ابزارها اطلاعات مربوط به وضعیت شبکه و بلاک‌های تولیدشده را نمایش می‌دهند.

جمع‌بندی

ایجاد Genesis Block در بلاکچین‌های مبتنی بر Substrate برای تنظیم وضعیت اولیه شبکه حیاتی است. در این بخش، نحوه پیکربندی Genesis Block و تنظیمات مختلف مانند حساب‌های اولیه، اعتبارسنج‌ها و سیستم استیکینگ توضیح داده شد. با پیکربندی صحیح این پارامترها، می‌توانید بلاکچین خود را مطابق با نیازهای پروژه خود راه‌اندازی کنید و از آن برای تولید بلاک‌های بعدی استفاده کنید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”بخش ۵: توسعه ماژول‌های سفارشی در Substrate (Pallets)”][cdb_course_lesson title=”فصل 1. مقدمه‌ای بر FRAME و Palletها در Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف FRAME و نقش آن در توسعه بلاکچین‌های ماژولار” subtitle=”توضیحات کامل”]FRAME (Framework for Runtime Aggregation of Modular Entities) یک چارچوب توسعه برای ساخت بلاکچین‌های ماژولار در Substrate است. این فریمورک به توسعه‌دهندگان امکان می‌دهد ماژول‌های قابل‌استفاده مجدد را برای ایجاد ویژگی‌های سفارشی در بلاکچین خود طراحی کنند. با استفاده از FRAME، می‌توان ماژول‌های از پیش‌ساخته‌شده (Pallets) را برای مدیریت حساب‌ها، توکن‌ها، گورننس و سایر عملکردهای کلیدی به‌کار گرفت یا ماژول‌های کاملاً سفارشی توسعه داد.

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


اجزای اصلی FRAME

FRAME شامل چندین بخش کلیدی است که در توسعه بلاکچین‌های ماژولار استفاده می‌شود:

  1. Pallets: هر Pallet در FRAME یک ماژول مستقل است که قابلیت خاصی را به بلاکچین اضافه می‌کند.
  2. Runtime: مجموعه‌ای از Palletها که منطق اصلی یک بلاکچین را تعیین می‌کنند.
  3. Storage: یک مدل ذخیره‌سازی کلیدی/مقداری که از طریق Rust Macros مدیریت می‌شود.
  4. Extrinsics: عملیات‌هایی که کاربران یا سایر ماژول‌ها می‌توانند روی بلاکچین اجرا کنند.
  5. Events: ثبت تغییرات در شبکه و اعلان‌ها برای سایر ماژول‌ها.

ایجاد یک Runtime سفارشی با FRAME

برای راه‌اندازی یک Runtime سفارشی، باید یک پروژه جدید Substrate ایجاد کرده و پیکربندی‌های موردنیاز را در فایل‌های Cargo.toml و lib.rs انجام داد.

۱. نصب Substrate Node Template

ابتدا قالب پایه‌ای نود Substrate را دریافت کنید:

git clone https://github.com/substrate-developer-hub/substrate-node-template
cd substrate-node-template
۲. تنظیمات Cargo.toml برای اضافه کردن Pallet سفارشی

فایل runtime/Cargo.toml را باز کرده و Pallet موردنظر را اضافه کنید:

[dependencies.pallet-template]
default-features = false
git = "https://github.com/substrate-developer-hub/substrate-node-template"
branch = "main"
۳. اضافه کردن Pallet به Runtime

فایل runtime/src/lib.rs را ویرایش کرده و Pallet را به Runtime اضافه کنید:

impl pallet_template::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
}

توسعه یک Pallet سفارشی در FRAME

۱. ایجاد ساختار اولیه یک Pallet

در مسیر pallets/template/src/lib.rs یک Pallet سفارشی ایجاد کنید:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
    use frame_support::{pallet_prelude::*, dispatch::DispatchResult};
    use frame_system::pallet_prelude::*;

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::pallet]
    #[pallet::generate_store(pub(super) trait Store)]
    pub struct Pallet<T>(_);

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::weight(10_000)]
        pub fn say_hello(origin: OriginFor<T>) -> DispatchResult {
            let _who = ensure_signed(origin)?;
            log::info!("Hello from our custom pallet!");
            Ok(())
        }
    }
}
۲. ثبت Pallet در فایل runtime/src/lib.rs

برای فعال کردن Pallet جدید، آن را در runtime/src/lib.rs ثبت کنید:

impl pallet_template::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
}

اجرای بلاکچین سفارشی و تست Pallet

۱. بیلد و اجرای نود سفارشی

برای کامپایل و اجرای نود، از دستورات زیر استفاده کنید:

cd substrate-node-template
cargo build --release
./target/release/node-template --dev --tmp
۲. تست عملکرد Pallet سفارشی در محیط Substrate

پس از اجرای نود، برای بررسی عملکرد Pallet می‌توانید از subxt یا Polkadot.js API استفاده کنید.


جمع‌بندی

FRAME چارچوبی قدرتمند برای توسعه بلاکچین‌های ماژولار در Substrate است. این فریمورک به توسعه‌دهندگان اجازه می‌دهد تا با استفاده از Palletهای آماده یا ایجاد Palletهای سفارشی، ویژگی‌های موردنیاز خود را به بلاکچین اضافه کنند.

در این بخش، نحوه ایجاد یک Runtime سفارشی، افزودن Palletهای جدید، و اجرای نود سفارشی بررسی شد. با این روش، می‌توان یک بلاکچین کاملاً سفارشی‌سازی‌شده بر اساس Substrate ایجاد کرد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ساختار Palletها و نحوه تعامل آن‌ها با Runtime” subtitle=”توضیحات کامل”]Palletها (ماژول‌ها) در Substrate FRAME اجزای کلیدی برای تعریف قابلیت‌های یک بلاکچین ماژولار هستند. هر Pallet می‌تواند وظایفی مانند مدیریت حساب‌ها، پردازش تراکنش‌ها، اجرای قوانین گورننس و سایر عملیات بلاکچینی را انجام دهد. این ماژول‌ها در نهایت در Runtime ترکیب شده و منطق کلی بلاکچین را تشکیل می‌دهند.


ساختار اصلی یک Pallet در FRAME

هر Pallet در Substrate معمولاً شامل بخش‌های زیر است:

  1. Config: تعریف ویژگی‌های قابل تنظیم Pallet
  2. Storage: مدیریت داده‌های ذخیره‌شده در بلاکچین
  3. Events: رویدادهایی که برای اطلاع‌رسانی به سایر Palletها یا کاربران منتشر می‌شوند
  4. Errors: خطاهایی که هنگام اجرای عملیات ممکن است رخ دهند
  5. Extrinsics (Calls): توابعی که کاربران یا سایر Palletها می‌توانند آن‌ها را اجرا کنند
  6. Hooks: توابعی که در زمان‌های خاص (مثلاً ابتدای هر بلاک) اجرا می‌شوند

ایجاد یک Pallet سفارشی در Substrate

۱. ایجاد یک Pallet جدید

برای اضافه کردن یک Pallet سفارشی، یک فایل جدید در مسیر pallets/my_pallet/src/lib.rs ایجاد کنید و ساختار آن را مطابق زیر تعریف کنید:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{pallet_prelude::*, dispatch::DispatchResult};
    use frame_system::pallet_prelude::*;

    #[pallet::config]
    pub trait Config: frame_system::Config {
        type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::storage]
    pub type ValueStore<T> = StorageValue<_, u32, ValueQuery>;

    #[pallet::event]
    #[pallet::generate_deposit(pub(super) fn deposit_event)]
    pub enum Event<T: Config> {
        ValueSet(u32),
    }

    #[pallet::error]
    pub enum Error<T> {
        ValueTooHigh,
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::weight(10_000)]
        pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            ensure!(value <= 100, Error::<T>::ValueTooHigh);

            ValueStore::<T>::put(value);

            Self::deposit_event(Event::ValueSet(value));

            Ok(())
        }
    }
}

نحوه تعامل Pallet با Runtime

برای اینکه Pallet بتواند بخشی از Runtime باشد، باید در فایل runtime/src/lib.rs ثبت شود.

۱. اضافه کردن Pallet جدید به Cargo.toml

در runtime/Cargo.toml این بخش را اضافه کنید:

[dependencies.pallet-my-pallet]
default-features = false
path = "../pallets/my_pallet"
۲. اضافه کردن Pallet به Runtime

در runtime/src/lib.rs، Pallet جدید را به Runtime متصل کنید:

impl pallet_my_pallet::Config for Runtime {
    type RuntimeEvent = RuntimeEvent;
}

بررسی نحوه تعامل Palletها

Palletها از طریق رویدادها (Events)، توابع فراخوانی (Calls) و داده‌های ذخیره‌شده (Storage) با سایر بخش‌های Runtime ارتباط برقرار می‌کنند. به عنوان مثال، اگر یک Pallet جدید بخواهد از اطلاعات یک Pallet دیگر استفاده کند، می‌تواند مستقیماً به داده‌های ذخیره‌شده آن دسترسی پیدا کند.

نمونه‌ای از تعامل دو Pallet

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

دسترسی به اطلاعات ذخیره‌شده یک Pallet در Pallet دیگر:
use pallet_accounting::ValueStore;

pub fn get_user_balance<T: Config>(account: &T::AccountId) -> u32 {
    ValueStore::<T>::get()
}
ارسال یک تراکنش از یک Pallet به Pallet دیگر:
impl<T: Config> Pallet<T> {
    pub fn transfer_funds(
        from: &T::AccountId, 
        to: &T::AccountId, 
        amount: u32
    ) -> DispatchResult {
        let balance = pallet_accounting::ValueStore::<T>::get();
        
        ensure!(balance >= amount, pallet_accounting::Error::<T>::InsufficientBalance);

        pallet_accounting::ValueStore::<T>::set(balance - amount);
        
        Ok(())
    }
}

جمع‌بندی

Palletها اجزای اصلی Runtime در Substrate هستند که به‌صورت ماژولار توسعه می‌یابند. نحوه تعامل آن‌ها با Runtime از طریق ذخیره داده‌ها، انتشار رویدادها و فراخوانی توابع انجام می‌شود.

در این بخش، ابتدا ساختار Palletها را بررسی کردیم، سپس نحوه افزودن یک Pallet سفارشی به Runtime را آموزش دادیم و در نهایت نحوه ارتباط Palletها با یکدیگر را توضیح دادیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی نقش Metadata در Substrate” subtitle=”توضیحات کامل”]Metadata در Substrate یکی از بخش‌های کلیدی Runtime است که اطلاعات جامعی درباره پالت‌ها (Pallets)، کال‌ها (Calls)، ذخیره‌سازی (Storage)، رویدادها (Events) و سایر بخش‌های بلاکچین را فراهم می‌کند. این Metadata به‌عنوان یک واسط استاندارد به کلاینت‌ها، APIها و ابزارهای خارجی اجازه می‌دهد که ساختار و قابلیت‌های بلاکچین را بدون نیاز به کد منبع، درک و با آن تعامل کنند.


چرا Metadata در Substrate اهمیت دارد؟

  1. شناخت دقیق ساختار Runtime: کلاینت‌ها و APIها می‌توانند بفهمند که چه Palletهایی در بلاکچین وجود دارند و چه قابلیت‌هایی ارائه می‌دهند.
  2. امکان تعامل با بلاکچین بدون نیاز به کد منبع: ابزارهایی مانند Polkadot.js یا کلاینت‌های سفارشی می‌توانند فقط با استفاده از Metadata به RPCها و Extrinsicها دسترسی داشته باشند.
  3. به‌روزرسانی ساده کلاینت‌ها: اگر Runtime تغییر کند، کلاینت‌ها نیازی به تغییر دستی کد خود ندارند، بلکه از طریق Metadata جدید می‌توانند با نسخه جدید سازگار شوند.
  4. بررسی سازگاری نسخه‌ها: هنگام انجام ارتقاها، می‌توان Metadata جدید را با Metadata قبلی مقایسه کرد تا تغییرات را تحلیل کرد.
  5. ساخت APIهای داینامیک: توسعه‌دهندگان می‌توانند از Metadata برای تولید خودکار SDKها و APIها برای ارتباط با بلاکچین استفاده کنند.

ساختار Metadata در Substrate

Metadata شامل ساختاری سلسله‌مراتبی است که اطلاعات هر Pallet و اجزای آن را نمایش می‌دهد. این ساختار شامل موارد زیر است:

  1. Pallets: لیستی از تمامی پالت‌های موجود در بلاکچین
  2. Storage: اطلاعات مربوط به ذخیره‌سازی داده‌ها در هر Pallet
  3. Calls: توابع قابل اجرا (Extrinsics) در هر Pallet
  4. Events: رویدادهایی که در حین اجرای بلاکچین رخ می‌دهند
  5. Constants: مقادیر ثابت مرتبط با هر Pallet
  6. Errors: لیستی از خطاهای هر Pallet
  7. Runtime Version: نسخه Runtime که این Metadata را تولید کرده است.

نحوه مشاهده Metadata در Substrate

۱. استفاده از Substrate Node Template

برای استخراج Metadata از یک نود Substrate، می‌توان از RPC زیر استفاده کرد:

curl -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"state_getMetadata","params":[]}' http://localhost:9933

این درخواست یک JSON برمی‌گرداند که شامل کل Metadata بلاکچین است.

۲. استفاده از Polkadot.js

می‌توان با مراجعه به Polkadot.js و اتصال به یک نود Substrate، Metadata را مشاهده کرد.

۳. نمایش Metadata با Rust

اگر بخواهید Metadata را مستقیماً از کد Rust دریافت کنید، می‌توانید از کد زیر استفاده کنید:

use substrate_api_client::rpc::json_req;
use reqwest::blocking::Client;

fn main() {
    let client = Client::new();
    let response = client.post("http://localhost:9933")
        .body(json_req("state_getMetadata", vec![]))
        .send()
        .unwrap()
        .text()
        .unwrap();
        
    println!("Metadata: {}", response);
}

مثال: بررسی Metadata یک Pallet

به عنوان مثال، Metadata مربوط به یک Pallet ممکن است به‌صورت زیر باشد:

{
  "pallets": [
    {
      "name": "Balances",
      "storage": {
        "type": "map",
        "entries": [
          {
            "name": "Account",
            "key": "AccountId",
            "value": "BalanceInfo"
          }
        ]
      },
      "calls": [
        {
          "name": "transfer",
          "args": [
            { "name": "dest", "type": "AccountId" },
            { "name": "value", "type": "Balance" }
          ]
        }
      ],
      "events": [
        {
          "name": "Transfer",
          "args": ["AccountId", "AccountId", "Balance"]
        }
      ]
    }
  ]
}

در این مثال:

  • Pallet Balances یک Storage دارد که حساب‌ها و موجودی آن‌ها را ذخیره می‌کند.
  • این Pallet دارای یک Call به نام transfer است که برای انتقال توکن‌ها استفاده می‌شود.
  • یک Event به نام Transfer وجود دارد که وقتی انتقال موفق انجام شد، منتشر می‌شود.

نحوه استفاده از Metadata در توسعه نرم‌افزارهای مبتنی بر Substrate

۱. ایجاد UI داینامیک برای تعامل با بلاکچین

یکی از کاربردهای اصلی Metadata این است که به وب‌سایت‌ها و کیف پول‌های دیجیتال اجازه می‌دهد فرم‌های ورودی داینامیک بسازند.

مثلاً اگر Metadata نشان دهد که یک Pallet دارای تابع transfer با دو پارامتر AccountId و Balance است، رابط کاربری می‌تواند دو فیلد ورودی را به‌طور خودکار نمایش دهد.

۲. تولید SDK برای تعامل با Substrate

با استفاده از Metadata، می‌توان کتابخانه‌های برنامه‌نویسی برای تعامل با Substrate تولید کرد. ابزارهایی مانند Polkadot.js API دقیقاً از این روش استفاده می‌کنند.

۳. بررسی و مقایسه تغییرات Runtime

در صورتی که یک به‌روزرسانی در Runtime انجام شود، می‌توان Metadata قبل و بعد از تغییر را مقایسه کرد و فهمید که چه چیزی تغییر کرده است.

مثلاً:

  • اضافه شدن یک Call جدید: یعنی بلاکچین قابلیت جدیدی دارد.
  • حذف شدن یک Storage Key: یعنی ممکن است داده‌هایی که قبلاً ذخیره می‌شدند، دیگر در دسترس نباشند.
  • تغییر در نوع یک پارامتر: یعنی ممکن است کلاینت‌های قدیمی دیگر نتوانند به درستی با بلاکچین تعامل کنند.

برای مقایسه Metadata قبل و بعد از تغییر می‌توان از ابزارهایی مانند Substrate Metadata Diff Tool استفاده کرد.


جمع‌بندی

Metadata در Substrate یک مکانیزم استاندارد برای ارائه اطلاعات دقیق درباره Runtime است. این داده‌ها نقش مهمی در تعامل ابزارهای خارجی، رابط‌های کاربری و SDKها با بلاکچین دارند.

در این بخش، ابتدا ساختار Metadata را بررسی کردیم، سپس نحوه دریافت Metadata از طریق RPC و تجزیه و تحلیل آن را توضیح دادیم. همچنین، نمونه‌هایی از کاربرد Metadata در توسعه نرم‌افزارهای بلاکچینی ارائه شد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 2. ایجاد یک Pallet سفارشی در Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ایجاد یک پروژه جدید با استفاده از Substrate Node Template” subtitle=”توضیحات کامل”]Substrate Node Template یک نقطه شروع مناسب برای توسعه‌دهندگانی است که می‌خواهند یک بلاکچین سفارشی با Substrate بسازند. این قالب شامل یک Runtime اولیه، پالت‌های استاندارد و تنظیمات پیش‌فرض است که می‌توان آن را سفارشی‌سازی کرد.


پیش‌نیازها

قبل از ایجاد پروژه، ابتدا باید پیش‌نیازهای زیر را روی سیستم خود نصب کنید:

۱. نصب Rust و ابزارهای موردنیاز

برای اجرای Substrate، باید Rust و وابستگی‌های آن نصب شوند. برای این کار، از دستورات زیر استفاده کنید:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
rustup update nightly
rustup update stable
rustup target add wasm32-unknown-unknown --toolchain nightly
۲. نصب وابستگی‌های سیستمی

بسته‌های موردنیاز برای ساخت و اجرای Substrate را نصب کنید:

در اوبونتو و دبیان:

sudo apt update && sudo apt install -y cmake pkg-config libssl-dev git clang libclang-dev curl

در مک (MacOS):

brew install cmake pkg-config openssl git llvm
۳. نصب Cargo Substrate

Cargo Substrate یک ابزار کمکی برای مدیریت پروژه‌های Substrate است. برای نصب آن از دستور زیر استفاده کنید:

cargo install cargo-substrate

ایجاد یک پروژه جدید

۱. کلون کردن Substrate Node Template

برای ایجاد یک پروژه جدید، ابتدا باید قالب آماده Substrate Node Template را کلون کنید:

git clone https://github.com/substrate-developer-hub/substrate-node-template.git my-substrate-node
cd my-substrate-node
۲. بررسی و به‌روزرسانی وابستگی‌ها

ابتدا بررسی کنید که نسخه‌های مورد نیاز شما به‌روز هستند:

rustup show
cargo --version

همچنین، می‌توانید Cargo.lock را پاک کرده و وابستگی‌ها را دوباره نصب کنید:

rm Cargo.lock
cargo update
۳. کامپایل و اجرای نود Substrate

برای ساخت و اجرای نود از دستورات زیر استفاده کنید:

cargo build --release
./target/release/node-template --dev
۴. اجرای نود در حالت توسعه

برای اجرای نود در حالت توسعه (با پایگاه داده موقت):

./target/release/node-template --dev

ساختار فایل‌ها و پوشه‌ها در Substrate Node Template

بعد از کلون کردن پروژه، فایل‌ها و دایرکتوری‌های زیر در دسترس خواهند بود:

  • /bin/node-template → کد اصلی نود
  • /runtime/ → کد Runtime بلاکچین
  • /pallets/ → پالت‌های (Pallets) از پیش تعریف شده
  • /node/ → کد نود و تنظیمات شبکه
  • /Cargo.toml → فایل تنظیمات Cargo

مثال ویرایش Cargo.toml برای اضافه کردن یک پالت جدید:

[dependencies]
pallet-example = { version = "3.0.0", default-features = false, features = ["std"] }

اتصال به نود Substrate با Polkadot.js

بعد از اجرای نود، می‌توان از طریق Polkadot.js به آن متصل شد:

  1. به Polkadot.js Apps بروید.
  2. گزینه “Local Node” را انتخاب کنید.
  3. ارتباط برقرار کرده و داده‌های زنجیره را مشاهده کنید.

جمع‌بندی

در این بخش، مراحل ایجاد یک پروژه جدید با استفاده از Substrate Node Template به‌طور کامل توضیح داده شد. ابتدا وابستگی‌های موردنیاز نصب شدند، سپس پروژه کلون و تنظیمات اولیه آن انجام شد. همچنین نحوه کامپایل و اجرای نود Substrate و ساختار فایل‌های پروژه بررسی گردید. در پایان، نحوه اتصال به نود با استفاده از Polkadot.js ارائه شد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”افزودن یک Pallet سفارشی به پروژه Substrate” subtitle=”توضیحات کامل”]در این بخش، نحوه افزودن یک Pallet سفارشی به پروژه Substrate را بررسی می‌کنیم. Palletها بخش‌های ماژولاری هستند که منطق خاصی را به Runtime اضافه می‌کنند. این فرآیند شامل مراحل زیر است:

  1. ایجاد یک Pallet جدید
  2. ثبت Pallet در Runtime
  3. کامپایل و اجرای پروژه برای تست عملکرد Pallet جدید

۱. ایجاد یک Pallet جدید در Substrate

برای ایجاد یک Pallet سفارشی، ابتدا وارد پروژه Substrate شوید:

cd substrate-node-template

سپس به مسیر pallets/ بروید و یک پوشه جدید برای Pallet خود ایجاد کنید:

mkdir -p pallets/custom-pallet/src

اکنون یک فایل lib.rs در مسیر pallets/custom-pallet/src/ ایجاد کنید و محتوای اولیه زیر را در آن قرار دهید:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{pallet_prelude::*, traits::Hooks};
    use frame_system::pallet_prelude::*;

    #[pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {}
}

۲. ثبت Pallet در Runtime

اکنون باید این Pallet سفارشی را در Runtime ثبت کنیم.

فایل runtime/Cargo.toml را باز کرده و خط زیر را به [dependencies] اضافه کنید:

custom-pallet = { path = "../pallets/custom-pallet" }

سپس، فایل runtime/src/lib.rs را باز کرده و پکیج Pallet جدید را ایمپورت کنید:

pub use custom_pallet;

سپس، درون ماکروی construct_runtime!، Pallet جدید را اضافه کنید:

construct_runtime!(
    pub enum Runtime where
        Block = Block,
        NodeBlock = opaque::Block,
        UncheckedExtrinsic = UncheckedExtrinsic
    {
        ...
        CustomPallet: custom_pallet,
    }
);

۳. کامپایل و اجرای پروژه

اکنون پروژه را کامپایل و اجرا کنید تا از عملکرد صحیح Pallet جدید اطمینان حاصل شود:

cargo build --release

در صورت موفقیت، نود Substrate را اجرا کنید:

./target/release/node-template --dev

سپس می‌توانید از Polkadot.js Apps برای بررسی اینکه Pallet جدید در Runtime ثبت شده است استفاده کنید.


جمع‌بندی

در این بخش یاد گرفتیم که چگونه یک Pallet سفارشی به پروژه Substrate اضافه کنیم. این فرآیند شامل ایجاد یک Pallet جدید، ثبت آن در Runtime و اجرای نود برای بررسی عملکرد آن بود. این روش به توسعه‌دهندگان کمک می‌کند تا بلاکچین‌های سفارشی خود را با قابلیت‌های منحصر‌به‌فرد توسعه دهند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ساختار فایل‌های یک Pallet و معرفی فایل‌های کلیدی” subtitle=”توضیحات کامل”]Palletها در Substrate به‌عنوان ماژول‌های مستقل طراحی می‌شوند که قابلیت‌های خاصی را به Runtime اضافه می‌کنند. هر Pallet شامل چندین فایل کلیدی است که هر یک مسئول بخشی از عملکرد Pallet هستند. در این بخش، ساختار فایل‌های یک Pallet را بررسی کرده و نقش هر فایل را توضیح می‌دهیم.


۱. ساختار پوشه Pallet

هر Pallet معمولاً در پوشه pallets/ قرار دارد و شامل فایل‌های زیر است:

pallets/
  ├── my_pallet/
  │   ├── src/
  │   │   ├── lib.rs
  │   │   ├── types.rs
  │   │   ├── weights.rs
  │   │   ├── benchmarking.rs (اختیاری)
  │   │   ├── tests.rs (اختیاری)
  │   ├── Cargo.toml

هر یک از این فایل‌ها عملکرد خاصی دارند که در ادامه توضیح داده می‌شود.


۲. معرفی فایل‌های کلیدی

۱. فایل lib.rs

مهم‌ترین فایل Pallet است که منطق اصلی Pallet در آن تعریف می‌شود. این فایل شامل بخش‌های زیر است:

  • تعریف Pallet
  • تعریف Storage (متغیرهای ذخیره‌سازی)
  • تعریف Events (رویدادها)
  • تعریف Errors (خطاها)
  • تعریف Callables (توابع قابل فراخوانی)

مثال ساده از ساختار lib.rs:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{pallet_prelude::*, traits::Hooks};
    use frame_system::pallet_prelude::*;

    #[pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::storage]
    #[pallet::getter(fn some_value)]
    pub type SomeValue<T> = StorageValue<_, u32>;

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::weight(10_000)]
        pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _sender = ensure_signed(origin)?;
            SomeValue::<T>::put(value);
            Ok(())
        }
    }
}

۲. فایل types.rs

این فایل برای تعریف انواع سفارشی در Pallet استفاده می‌شود. اگر Pallet دارای ساختار داده‌های پیچیده باشد، بهتر است این ساختارها در فایل types.rs جداگانه تعریف شوند.

مثال:

pub struct MyStruct {
    pub id: u32,
    pub name: Vec<u8>,
}

۳. فایل weights.rs

این فایل برای تعریف وزن (Weight) تراکنش‌ها استفاده می‌شود. وزن نشان‌دهنده میزان محاسبات موردنیاز برای اجرای یک تابع است.

مثال:

pub struct WeightInfo;
impl pallet::WeightInfo for WeightInfo {
    fn set_value() -> Weight {
        10_000
    }
}

۴. فایل benchmarking.rs (اختیاری)

این فایل برای تست و بهینه‌سازی عملکرد Pallet استفاده می‌شود. در پروژه‌های پیشرفته، این فایل برای تنظیم وزن تراکنش‌ها به‌صورت دقیق ضروری است.


۵. فایل tests.rs (اختیاری)

این فایل شامل تست‌های واحد (Unit Tests) برای بررسی عملکرد صحیح Pallet است.

مثال:

#[test]
fn test_set_value() {
    new_test_ext().execute_with(|| {
        assert_ok!(MyPallet::set_value(Origin::signed(1), 100));
        assert_eq!(SomeValue::get(), Some(100));
    });
}

۶. فایل Cargo.toml

این فایل وابستگی‌های Pallet را مشخص می‌کند.

مثال:

[package]
name = "pallet-my_pallet"
version = "1.0.0"
edition = "2021"

[dependencies]
frame-support = { version = "4.0.0", default-features = false }
frame-system = { version = "4.0.0", default-features = false }

جمع‌بندی

در این بخش، ساختار فایل‌های یک Pallet در Substrate را بررسی کردیم. مهم‌ترین فایل lib.rs است که منطق اصلی Pallet در آن قرار دارد. سایر فایل‌ها مانند types.rs، weights.rs، benchmarking.rs و tests.rs نیز برای مدیریت بهتر، بهینه‌سازی عملکرد و تست کردن Pallet استفاده می‌شوند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 3. مدیریت State Storage در Palletها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی Storage در Substrate و نحوه ذخیره داده‌ها” subtitle=”توضیحات کامل”]Storage در Substrate یکی از مهم‌ترین بخش‌های Runtime است که برای ذخیره‌سازی دائمی داده‌ها در بلاکچین استفاده می‌شود. در این بخش، با نحوه ذخیره داده‌ها در Palletهای Substrate آشنا می‌شویم و انواع ساختارهای Storage را بررسی می‌کنیم.


۱. معرفی Storage در Substrate

در Substrate، داده‌ها در Key-Value Database ذخیره می‌شوند که از RocksDB به‌عنوان پایگاه داده سطح پایین استفاده می‌کند. اما توسعه‌دهندگان مستقیماً با این دیتابیس کار نمی‌کنند، بلکه از Storage API که در FRAME ارائه شده استفاده می‌کنند.

Storage در Palletها معمولاً با استفاده از StorageValue، StorageMap و StorageDoubleMap پیاده‌سازی می‌شود.


۲. انواع Storage در Substrate

۱. StorageValue (ذخیره مقدار ساده)

StorageValue برای ذخیره یک مقدار منفرد استفاده می‌شود.

مثال:

#[pallet::storage]
#[pallet::getter(fn some_value)]
pub type SomeValue<T> = StorageValue<_, u32, ValueQuery>;

در این مثال:

  • مقدار SomeValue یک مقدار u32 را در Storage نگه می‌دارد.
  • می‌توان مقدار آن را با SomeValue::<T>::put(value) تغییر داد.

مثال استفاده در تابع:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
        let _sender = ensure_signed(origin)?;
        SomeValue::<T>::put(value);
        Ok(())
    }
}

۲. StorageMap (ذخیره داده با کلید)

StorageMap برای ذخیره داده‌ها در قالب کلید-مقدار (Key-Value) استفاده می‌شود.

مثال:

#[pallet::storage]
#[pallet::getter(fn user_balance)]
pub type UserBalance<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, u128, ValueQuery>;

در این مثال:

  • مقدار UserBalance یک u128 را برای هر حساب کاربری (AccountId) ذخیره می‌کند.
  • از Blake2_128Concat به‌عنوان هش برای کلیدها استفاده شده است.

مثال استفاده در تابع:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn set_balance(origin: OriginFor<T>, who: T::AccountId, balance: u128) -> DispatchResult {
        let _sender = ensure_signed(origin)?;
        UserBalance::<T>::insert(who, balance);
        Ok(())
    }
}

۳. StorageDoubleMap (ذخیره داده با دو کلید)

StorageDoubleMap برای ذخیره داده‌هایی که دارای دو کلید هستند، استفاده می‌شود.

مثال:

#[pallet::storage]
#[pallet::getter(fn user_item_balance)]
pub type UserItemBalance<T: Config> = StorageDoubleMap<
    _,
    Blake2_128Concat,
    T::AccountId,
    Blake2_128Concat,
    u32, // Item ID
    u128, // Balance
    ValueQuery
>;

در این مثال:

  • مقدار UserItemBalance یک مقدار u128 را بر اساس AccountId و Item ID ذخیره می‌کند.

مثال استفاده در تابع:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn set_item_balance(
        origin: OriginFor<T>,
        who: T::AccountId,
        item_id: u32,
        balance: u128
    ) -> DispatchResult {
        let _sender = ensure_signed(origin)?;
        UserItemBalance::<T>::insert(who, item_id, balance);
        Ok(())
    }
}

۳. حذف داده‌ها از Storage

برای پاک کردن مقدار از Storage می‌توان از remove استفاده کرد.

مثال برای StorageValue:

SomeValue::<T>::kill();

مثال برای StorageMap:

UserBalance::<T>::remove(&who);

مثال برای StorageDoubleMap:

UserItemBalance::<T>::remove(&who, item_id);

۴. خواندن داده‌ها از Storage

برای دریافت مقدار ذخیره‌شده از get() استفاده می‌شود.

مثال برای StorageValue:

let value = SomeValue::<T>::get();

مثال برای StorageMap:

let balance = UserBalance::<T>::get(&who);

مثال برای StorageDoubleMap:

let balance = UserItemBalance::<T>::get(&who, item_id);

جمع‌بندی

در این بخش، با Storage در Substrate آشنا شدیم و انواع StorageValue، StorageMap و StorageDoubleMap را بررسی کردیم. همچنین نحوه افزودن، خواندن و حذف داده‌ها از Storage را توضیح دادیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف Storage Map و Storage Value در Pallet” subtitle=”توضیحات کامل”]در Substrate، داده‌های بلاکچین در Storage ذخیره می‌شوند که در سطح Pallet قابل مدیریت هستند. دو نوع اصلی Storage در Palletها شامل StorageValue و StorageMap هستند که هرکدام کاربرد خاص خود را دارند.


۱. StorageValue در Pallet

StorageValue برای ذخیره یک مقدار واحد استفاده می‌شود. این مقدار می‌تواند هر نوع داده‌ای باشد، مانند اعداد، رشته‌ها، ساختارها و غیره.

تعریف StorageValue
#[pallet::storage]
#[pallet::getter(fn some_value)]
pub type SomeValue<T> = StorageValue<_, u32, ValueQuery>;
توضیح کد:
  • SomeValue<T> یک مقدار منفرد از نوع u32 را در Storage ذخیره می‌کند.
  • از ValueQuery برای مقدار پیش‌فرض استفاده شده است.
  • مقدار ذخیره‌شده با استفاده از SomeValue::<T>::put(value) تغییر می‌یابد.
مثال استفاده از StorageValue در تابع
#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
        let _sender = ensure_signed(origin)?;
        SomeValue::<T>::put(value);
        Ok(())
    }
}
دریافت مقدار ذخیره‌شده در StorageValue
let value = SomeValue::<T>::get();
حذف مقدار ذخیره‌شده از StorageValue
SomeValue::<T>::kill();

۲. StorageMap در Pallet

StorageMap برای ذخیره داده‌ها به صورت کلید-مقدار استفاده می‌شود. این ساختار مشابه یک HashMap است که مقدارها را بر اساس یک کلید ذخیره می‌کند.

تعریف StorageMap
#[pallet::storage]
#[pallet::getter(fn user_balance)]
pub type UserBalance<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, u128, ValueQuery>;
توضیح کد:
  • UserBalance<T> مقدار u128 را برای هر حساب کاربری (AccountId) ذخیره می‌کند.
  • از Blake2_128Concat به‌عنوان هش کلید استفاده شده است.
  • مقدار پیش‌فرض با ValueQuery تعیین شده است.
مثال استفاده از StorageMap در تابع
#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn set_balance(origin: OriginFor<T>, who: T::AccountId, balance: u128) -> DispatchResult {
        let _sender = ensure_signed(origin)?;
        UserBalance::<T>::insert(who, balance);
        Ok(())
    }
}
دریافت مقدار ذخیره‌شده در StorageMap
let balance = UserBalance::<T>::get(&who);
حذف مقدار ذخیره‌شده از StorageMap
UserBalance::<T>::remove(&who);

جمع‌بندی

  • StorageValue برای ذخیره یک مقدار واحد در Storage استفاده می‌شود.
  • StorageMap برای ذخیره مقدارهای مختلف بر اساس کلید مشخص استفاده می‌شود.
  • هر دو نوع Storage از طریق put، get، insert و remove مدیریت می‌شوند.
  • در Palletهای Substrate، این ساختارها باعث بهینه‌سازی و مدیریت بهتر داده‌های بلاکچین می‌شوند.

[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بهینه‌سازی ذخیره‌سازی با استفاده از Storage Migration” subtitle=”توضیحات کامل”]در Substrate، ذخیره‌سازی داده‌ها بخش حیاتی از هر Pallet است. با رشد و تغییرات پروژه، گاهی نیاز به تغییر ساختار ذخیره‌سازی (Storage) و مهاجرت آن به ساختار جدیدتر و بهینه‌تر وجود دارد. این فرآیند تحت عنوان Storage Migration شناخته می‌شود. در این بخش، به تشریح نحوه انجام این کار به همراه مثال‌های عملی خواهیم پرداخت.

مقدمه

در هنگام توسعه بلاکچین با استفاده از Substrate، گاهی اوقات نیاز به تغییر در ساختار ذخیره‌سازی برای بهینه‌سازی یا به‌روزرسانی اطلاعات داریم. این تغییرات می‌توانند شامل تغییر در نحوه ذخیره‌سازی داده‌ها، اضافه کردن یا حذف کردن اطلاعات، یا تغییر نوع داده‌ها باشند. برای انجام چنین تغییراتی باید از Storage Migration استفاده کرد تا تغییرات به درستی اعمال شوند و از سازگاری با داده‌های قبلی محافظت گردد.

مراحل انجام Storage Migration

برای انجام Storage Migration در Substrate، شما باید مراحل زیر را دنبال کنید:

1. تعریف تغییرات جدید در ساختار Storage

اولین قدم برای انجام مهاجرت ذخیره‌سازی، تعریف تغییرات جدید در ساختار Storage است. این تغییرات می‌توانند شامل اضافه کردن، حذف یا تغییر نوع داده‌ها باشند. فرض کنید شما نیاز دارید یک Storage Map جدید به نام UserBalances ایجاد کنید که موجودی کاربران را ذخیره کند.

#[pallet::storage]
#[pallet::getter(fn user_balances)]
pub type UserBalances<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, u64, OptionQuery>;

2. تعریف Migration Function

برای انجام مهاجرت، شما باید یک تابع مهاجرت (Migration function) ایجاد کنید که مسئول تغییر ساختار داده‌ها باشد. در اینجا ما باید اطلاعات موجود در Storage قبلی را به فرمت جدید منتقل کنیم.

یک مثال از یک تابع مهاجرت که مقادیر موجود در یک Storage Value قدیمی را به یک Storage Map جدید انتقال می‌دهد، به شکل زیر است:

fn migrate_storage() -> DispatchResult {
    // شبیه‌سازی دریافت داده‌های قبلی
    let old_balance = Some(100u64);
    
    // اگر داده موجود است، آن را به ساختار جدید منتقل کن
    if let Some(balance) = old_balance {
        let account_id: T::AccountId = T::AccountId::default(); // در اینجا باید AccountId درست را تنظیم کنید
        UserBalances::<T>::insert(account_id, balance);
    }

    Ok(())
}

3. استفاده از Storage Migration در Pallet

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

برای این منظور، در داخل Pallet خود، باید یک hook برای فراخوانی مهاجرت تعریف کنید. این تابع در هنگام راه‌اندازی بلاکچین یا هر زمانی که لازم است اجرا می‌شود.

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::weight(10_000)]
    pub fn execute_migration(origin: OriginFor<T>) -> DispatchResult {
        let _who = ensure_signed(origin)?;
        
        // فراخوانی تابع مهاجرت
        migrate_storage()?;

        Ok(())
    }
}

4. ایجاد و اجرای Migration در Network

پس از اینکه تابع مهاجرت آماده شد، می‌توانید آن را در شبکه خود اجرا کنید. برای تست این تغییرات، یک شبکه آزمایشی (Test Network) راه‌اندازی کنید و بررسی کنید که آیا مهاجرت به درستی انجام شده است یا خیر.

اجرای این دستور در CLI برای راه‌اندازی شبکه آزمایشی:

# راه‌اندازی یک شبکه آزمایشی برای Substrate
cargo run --release -- --dev

پس از راه‌اندازی شبکه، شما می‌توانید درخواست مهاجرت را از طریق extrinsic اجرا کنید.

5. بررسی صحت مهاجرت

پس از انجام مهاجرت، باید از طریق debug و ابزارهای بررسی وضعیت شبکه، اطمینان حاصل کنید که داده‌ها به درستی منتقل شده‌اند. می‌توانید از دستورات زیر برای مشاهده وضعیت داده‌های جدید استفاده کنید.

# مشاهده داده‌ها از طریق پلتفرم پشتیبانی‌شده
substrate-cli query storage pallet_name user_balances [AccountId]

جمع بندی

در این بخش، نحوه انجام Storage Migration در Substrate را بررسی کردیم. این فرآیند شامل تعریف تغییرات جدید در ساختار Storage، نوشتن تابع مهاجرت برای انتقال داده‌ها، و در نهایت، اجرای آن در شبکه است. با انجام صحیح این مراحل، می‌توانیم داده‌های قدیمی را به ساختار جدید منتقل کرده و از آن به صورت بهینه‌تر استفاده کنیم.[/cdb_course_lesson][cdb_course_lesson title=”فصل 4. تعریف و مدیریت Extrinsicها در Pallet سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی Extrinsicها و نحوه ارسال تراکنش‌ها در Substrate” subtitle=”توضیحات کامل”]Extrinsic ها در Substrate، به تراکنش‌هایی اطلاق می‌شود که از خارج از بلاکچین به سمت آن ارسال می‌شوند تا در Runtime اجرا شوند. به عبارت دیگر، Extrinsicها راهی برای ارسال داده به شبکه بلاکچین از طرف کاربران یا اپلیکیشن‌های خارجی هستند. در Substrate، این تراکنش‌ها شامل درخواست‌هایی هستند که معمولاً به منظور تغییر وضعیت (state) بلاکچین ارسال می‌شوند.

انواع Extrinsicها در Substrate

Extrinsicها در Substrate به چهار دسته کلی تقسیم می‌شوند:

  1. Signed Extrinsics: این‌ها تراکنش‌هایی هستند که توسط یک کاربر با امضای دیجیتال معتبر ارسال می‌شوند. این نوع Extrinsicها بیشتر برای اعمال تغییرات در وضعیت بلاکچین استفاده می‌شوند که به تأیید هویت کاربر نیاز دارند.
  2. Unsigned Extrinsics: این نوع Extrinsicها هیچ‌گونه امضای دیجیتال ندارند و معمولاً برای تراکنش‌هایی استفاده می‌شوند که نیازی به احراز هویت ندارند.
  3. Inherent Extrinsics: این‌ها به طور پیش‌فرض توسط شبکه به بلاک‌ها اضافه می‌شوند. این تراکنش‌ها معمولاً برای درخواست‌هایی که نیاز به تایید کاربر ندارند، مورد استفاده قرار می‌گیرند.
  4. System Extrinsics: این‌ها به درخواست‌های مربوط به خود سیستم بلاکچین اشاره دارند و معمولاً شامل درخواست‌هایی برای مدیریت پروتکل بلاکچین هستند.

نحوه ارسال تراکنش‌ها (Extrinsicها) در Substrate

برای ارسال یک Extrinsic در Substrate، ابتدا باید یک Pallet را تعریف کنید که به درخواست‌ها و تراکنش‌ها پاسخ دهد. این تراکنش‌ها می‌توانند شامل تغییرات در وضعیت (state) شبکه باشند. در ادامه به نحوه ارسال یک Signed Extrinsic خواهیم پرداخت.

مراحل ارسال Signed Extrinsic

  1. ایجاد یک پالت جدید: برای ارسال یک تراکنش، ابتدا باید یک Pallet ایجاد کنید که مسئول مدیریت تغییرات و تراکنش‌ها باشد. این Pallet باید تابعی برای مدیریت ارسال تراکنش‌ها داشته باشد.برای ایجاد یک Pallet جدید، از دستور زیر استفاده می‌کنیم:
    substrate-pallet-template new pallet_name
    

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

  2. تعریف تابع ارسال تراکنش (Extrinsic): در داخل Pallet خود، باید یک تابع ارسال تراکنش (مثلاً ارسال مبلغ) تعریف کنید. برای این کار، از متدهایی مانند dispatchable استفاده می‌شود که تراکنش‌ها را از کاربر دریافت کرده و آن‌ها را پردازش می‌کند.در داخل فایل lib.rs پالت خود، کد زیر را اضافه کنید:
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[weight = 10_000]
        pub fn transfer(origin: OriginFor<T>, value: u64) -> DispatchResult {
            let sender = ensure_signed(origin)?;
    
            // ارسال تراکنش و تغییر وضعیت
            T::Currency::transfer(&sender, &T::PalletId::get(), value)?;
    
            Ok(())
        }
    }
    
  3. ارسال تراکنش: بعد از اینکه تابع transfer را در Pallet تعریف کردید، می‌توانید آن را از طریق یک Extrinsic ارسال کنید. برای ارسال این تراکنش به شبکه، از API مربوط به ارسال Signed Extrinsics استفاده می‌شود.برای این کار از CLI زیر استفاده می‌کنیم:
    substrate --chain=local --keyfile=~/.substrate/keys.json --exec 'transfer(100)' --sign
    

    این دستور، تراکنش transfer را ارسال کرده و مبلغ 100 واحد را از حساب کاربر به حساب مقصد ارسال می‌کند.

  4. بررسی وضعیت تراکنش: بعد از ارسال تراکنش، می‌توانید وضعیت آن را با استفاده از دستور زیر بررسی کنید:
    substrate-cli query --block 0
    

    این دستور وضعیت تراکنش‌ها را در بلاک 0 نمایش می‌دهد.

تنظیمات مورد نیاز

برای ارسال Extrinsicها و تراکنش‌ها در Substrate، شما نیاز به یک شبکه فعال و همچنین تنظیمات مورد نیاز در فایل‌های پیکربندی دارید. این تنظیمات شامل اطلاعات مربوط به کلید خصوصی و عمومی کاربران، آدرس‌های بلاکچین، و تنظیمات دیگر می‌باشد.

مسیرهای فایل برای تنظیمات و کدها:

  • پوشه Pallet: pallets/my_pallet/src/lib.rs
  • فایل پیکربندی CLI: ~/.substrate/keys.json

جمع‌بندی

در این بخش، به بررسی نحوه ارسال Extrinsicها در Substrate پرداختیم. ابتدا با معرفی انواع مختلف Extrinsicها و تفاوت‌های آن‌ها آشنا شدیم. سپس با ایجاد یک Pallet جدید و تعریف تابع ارسال تراکنش، نحوه ارسال یک تراکنش از طریق Signed Extrinsics را مورد بررسی قرار دادیم. در نهایت، با تنظیمات و فایل‌های مربوطه آشنا شدیم و نحوه ارسال و بررسی وضعیت تراکنش‌ها را توضیح دادیم.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”تعریف توابع قابل‌اجرا (Call Functions) در یک Pallet” subtitle=”توضیحات کامل”]توابع قابل‌اجرا در یک Pallet، مسئول اجرای تراکنش‌های مختلف در Substrate هستند. این توابع بخش مهمی از عملیات Pallet‌ها را تشکیل می‌دهند و به کاربران این امکان را می‌دهند که با بلاکچین تعامل داشته باشند. در Substrate، تراکنش‌ها به صورت Extrinsic تعریف می‌شوند و توسط توابع قابل‌اجرا در Pallet‌ها پردازش می‌شوند.

ساختار یک تابع قابل‌اجرا در Pallet

یک تابع قابل‌اجرا در Pallet معمولاً به یکی از انواع عملیات‌ها مانند تغییر وضعیت در ذخیره‌سازی (Storage)، ارسال تراکنش، یا انجام محاسبات نیاز دارد. ساختار این توابع به صورت زیر است:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn example_function(origin: OriginFor<T>, param: u32) -> DispatchResult {
        let who = ensure_signed(origin)?;
        
        // انجام عملیات
        Ok(())
    }
}

در اینجا:

  • #[pallet::call]: این علامت‌گذاری نشان می‌دهد که این تابع جزء توابع قابل‌اجرا است.
  • origin: ورودی که نشان می‌دهد این تراکنش توسط چه کسی ارسال شده است.
  • param: ورودی که اطلاعات اضافی که به تابع ارسال می‌شود را نشان می‌دهد.
  • DispatchResult: نوع نتیجه‌ای که تابع بازمی‌گرداند. این نتیجه می‌تواند موفقیت یا خطا را مشخص کند.
ارسال تراکنش به یک تابع قابل‌اجرا

برای ارسال یک تراکنش به تابع قابل‌اجرا در Substrate، ابتدا باید از طریق ابزار CLI یا از داخل یک فضای کد مانند runtime آن را ارسال کنید. این کار می‌تواند از طریق یک تراکنش Extrinsic انجام شود.

به عنوان مثال، در صورتی که بخواهید تراکنشی به تابع example_function ارسال کنید، می‌توانید از کد زیر استفاده کنید:

# ارسال تراکنش از طریق CLI
substrate --chain=local-testnet --exec "extrinsics pallet_example.example_function 1234" --signer Alice

در اینجا:

  • --chain=local-testnet: انتخاب زنجیره محلی برای ارسال تراکنش.
  • --exec: دستور اجرای تراکنش.
  • extrinsics pallet_example.example_function 1234: ارسال پارامتر 1234 به تابع example_function.
  • --signer Alice: استفاده از کلید خصوصی Alice برای امضای تراکنش.
تنظیمات و پیکربندی‌های مرتبط با توابع قابل‌اجرا

برای اطمینان از اینکه تابع شما به درستی اجرا می‌شود، نیاز است که تنظیمات مربوط به آن را در فایل‌های زیر پیکربندی کنید:

  1. Cargo.toml: در این فایل باید نسخه‌های وابستگی‌های لازم را مشخص کنید.
    [dependencies]
    substrate-frame-support = { version = "3.0", default-features = false }
    
  2. lib.rs: در فایل lib.rs باید نحوه پیکربندی و ثبت تابع در Pallet را تعریف کنید.
    pub use pallet_example::Call;
    
  3. Runtime: در فایل runtime باید مطمئن شوید که pallet شما به درستی به زنجیره اضافه شده است. برای این کار باید از کد زیر استفاده کنید:
    pub struct Runtime;
    
    impl pallet_example::Config for Runtime {
        type Event = Event;
    }
    

جمع‌بندی

توابع قابل‌اجرا در Substrate اجزای کلیدی هستند که به شما این امکان را می‌دهند تا با بلاکچین تعامل کنید و تراکنش‌ها را اجرا کنید. از طریق تعریف و پیکربندی این توابع می‌توانید عملکردهای مختلف را در بلاکچین پیاده‌سازی کنید. با استفاده از ابزار CLI و پیکربندی مناسب در فایل‌های مختلف، می‌توانید توابع خود را به درستی پیاده‌سازی و اجرا کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت خطاها و وضعیت تراکنش‌ها در Pallet” subtitle=”توضیحات کامل”]مدیریت خطاها و وضعیت تراکنش‌ها در Pallet‌ها از اهمیت بالایی برخوردار است، زیرا این امکان را می‌دهد تا توسعه‌دهندگان اطمینان حاصل کنند که تراکنش‌ها به‌درستی پردازش شده و وضعیت بلاکچین در صورت بروز خطا تغییر نمی‌کند. Substrate از یک سیستم قوی برای مدیریت خطاها و وضعیت تراکنش‌ها استفاده می‌کند که به شما این امکان را می‌دهد که شرایط مختلف را کنترل کرده و از بروز مشکلات جلوگیری کنید.

انواع وضعیت تراکنش‌ها

وضعیت تراکنش‌ها در Substrate معمولاً به یکی از سه حالت زیر قرار می‌گیرد:

  1. Success: تراکنش با موفقیت پردازش شده است.
  2. Error: تراکنش با خطا مواجه شده است.
  3. Pending: تراکنش در حال انتظار برای پردازش است.

این وضعیت‌ها توسط تابع DispatchResult در Substrate مدیریت می‌شوند. هر تراکنش در واقع یک DispatchResult برمی‌گرداند که نتیجه پردازش تراکنش را تعیین می‌کند.

مدیریت خطاها در توابع قابل‌اجرا

در Substrate برای مدیریت خطاها از ویژگی‌های DispatchResult استفاده می‌شود که به شما این امکان را می‌دهد که خطاها را به طور مؤثری شبیه‌سازی و مدیریت کنید. برای این منظور، از ماکروهای مختلفی مانند ensure! و ensure_signed! می‌توانید استفاده کنید.

مثال: مدیریت خطا با استفاده از ensure!
#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, amount: u32) -> DispatchResult {
        let sender = ensure_signed(origin)?;
        
        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);
        
        // انجام عملیات انتقال
        <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        
        Ok(())
    }
}

در اینجا:

  • ensure_signed!: بررسی می‌کند که آیا تراکنش توسط یک امضاکننده معتبر ارسال شده است.
  • ensure!(condition, Error::<T>::ErrorName): بررسی می‌کند که شرط مشخص‌شده صحیح باشد. اگر خطا باشد، خطای مشخص‌شده با نام ErrorName برمی‌گردد.
  • Error::<T>::InsufficientBalance: خطای مربوط به موجودی ناکافی را بررسی می‌کند و در صورت وقوع آن، پیغام خطا ارسال می‌شود.
انواع خطاها در Pallet

برای تعریف خطاها در یک Pallet، معمولاً از یک enum استفاده می‌شود که خطاهای مختلف را شبیه‌سازی می‌کند. این خطاها سپس به وسیله توابع قابل‌اجرا برگردانده می‌شوند.

#[pallet::error]
pub enum Error<T> {
    InsufficientBalance,
    NotAuthorized,
    OtherError,
}

در اینجا:

  • InsufficientBalance: خطای موجودی ناکافی.
  • NotAuthorized: خطای عدم دسترسی.
  • OtherError: سایر خطاها.

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

پیکربندی و تنظیمات

برای اینکه توابع شما به درستی وضعیت و خطاها را مدیریت کنند، باید برخی پیکربندی‌ها را در فایل‌های مختلف انجام دهید:

  1. Cargo.toml: در این فایل باید وابستگی‌ها و نسخه‌های مربوطه را مشخص کنید. در اینجا به وابستگی‌های اساسی Substrate اشاره می‌کنیم:
    [dependencies]
    substrate-frame-support = { version = "3.0", default-features = false }
    
  2. lib.rs: در این فایل باید توابع و خطاها را تعریف کنید.
    pub use pallet_example::{Call, Error};
    
  3. Runtime: در فایل runtime باید مطمئن شوید که pallet شما به درستی به زنجیره اضافه شده است.
    pub struct Runtime;
    
    impl pallet_example::Config for Runtime {
        type Event = Event;
    }
    
ارسال تراکنش و بررسی وضعیت آن

برای ارسال تراکنش و بررسی وضعیت آن، می‌توانید از ابزار CLI استفاده کنید. در اینجا مثالی برای ارسال یک تراکنش و بررسی وضعیت آن آمده است:

# ارسال تراکنش با ابزار CLI
substrate --chain=local-testnet --exec "extrinsics pallet_example.transfer 1234" --signer Alice

در اینجا:

  • --exec: دستور ارسال تراکنش.
  • extrinsics pallet_example.transfer 1234: ارسال تراکنش انتقال با مقدار 1234.
  • --signer Alice: استفاده از کلید خصوصی Alice برای امضای تراکنش.
جمع‌بندی

مدیریت خطاها و وضعیت تراکنش‌ها در Pallet‌های Substrate بخش مهمی از توسعه بلاکچین است. با استفاده از DispatchResult، توابع قابل‌اجرا می‌توانند تراکنش‌ها را با موفقیت یا خطا پردازش کنند. همچنین با استفاده از ماکروهای مختلف مانند ensure! می‌توان شرایط خاصی را بررسی و خطاها را به‌طور مؤثری مدیریت کرد. با تنظیمات صحیح در فایل‌های مربوطه و استفاده از ابزار CLI برای ارسال تراکنش‌ها، می‌توان به‌طور کامل مدیریت وضعیت تراکنش‌ها را در سیستم بلاکچین انجام داد.[/cdb_course_lesson][cdb_course_lesson title=”فصل 5. رویدادها (Events) و خطاها (Errors) در Palletها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی Events و نحوه تعریف آن‌ها در Pallet” subtitle=”توضیحات کامل”]Event ها در Substrate، ابزار قدرتمندی هستند که برای گزارش وضعیت و تغییرات در سیستم استفاده می‌شوند. این رویدادها به‌عنوان پیام‌هایی در نظر گرفته می‌شوند که در صورت وقوع یک عملیات خاص یا تغییر در وضعیت، در سیستم منتشر می‌شوند. این رویدادها معمولاً برای مطلع کردن کلاینت‌ها یا سایر قسمت‌های سیستم از تغییرات بلاکچین به‌کار می‌روند و به‌صورت عمومی در دسترس قرار می‌گیرند.

در این بخش، به بررسی نحوه تعریف و استفاده از Event‌ها در یک Pallet پرداخته خواهد شد.

ساختار Event‌ها در Substrate

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

در Substrate، Event‌ها در قالب enum‌ها (مجموعه‌ای از مقادیر ثابت) تعریف می‌شوند. این enum‌ها معمولاً به‌صورت زیر ظاهر می‌شوند:

#[pallet::event]
pub enum Event<T> where T: frame_system::Config {
    /// ارسال موفقیت‌آمیز تراکنش انتقال
    Transferred(T::AccountId, T::AccountId, u32),
    /// خطای موجودی ناکافی
    InsufficientBalance(T::AccountId, u32),
}

در اینجا:

  • Transferred(T::AccountId, T::AccountId, u32): یک رویداد که نشان‌دهنده انتقال موفقیت‌آمیز مقدار u32 از حسابی به حساب دیگر است.
  • InsufficientBalance(T::AccountId, u32): یک رویداد که نشان‌دهنده این است که حساب فرستنده موجودی کافی برای انجام تراکنش ندارد.
نحوه انتشار Event‌ها در توابع قابل‌اجرا

پس از تعریف Event‌ها، باید از آن‌ها در توابع قابل‌اجرا استفاده کنید تا به محض وقوع شرایط خاص، آن‌ها را منتشر کنید. در Substrate از ماکرو Self::deposit_event() برای انتشار رویدادها استفاده می‌شود. این ماکرو، رویدادها را به‌صورت اتوماتیک به سیستم ارسال می‌کند.

برای مثال، در تابعی که تراکنش‌های انتقال را انجام می‌دهد، می‌توان از رویدادهای Transferred و InsufficientBalance استفاده کرد:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, amount: u32) -> DispatchResult {
        let sender = ensure_signed(origin)?;
        
        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // انجام عملیات انتقال
        <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        
        // انتشار رویداد موفقیت‌آمیز
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));
        
        Ok(())
    }
}

در این مثال:

  • Self::deposit_event(Event::<T>::Transferred(sender, dest, amount)): این خط رویداد Transferred را منتشر می‌کند که شامل اطلاعات حساب فرستنده، حساب گیرنده و مقدار منتقل‌شده است.
  • ensure!(balance >= amount, Error::<T>::InsufficientBalance): در صورتی که موجودی کافی نباشد، رویداد InsufficientBalance منتشر می‌شود.
پیکربندی و تنظیمات

برای اینکه بتوانید از Event‌ها در Pallet خود استفاده کنید، لازم است که پیکربندی‌هایی در فایل‌های مختلف انجام دهید:

  1. Cargo.toml: در این فایل باید وابستگی‌ها و نسخه‌های مربوطه را مشخص کنید:
    [dependencies]
    substrate-frame-support = { version = "3.0", default-features = false }
    
  2. lib.rs: در این فایل باید توابع و رویدادها را تعریف کنید.
    pub use pallet_example::{Call, Event, Error};
    
  3. Runtime: در فایل runtime باید مطمئن شوید که pallet شما به درستی به زنجیره اضافه شده است:
    pub struct Runtime;
    
    impl pallet_example::Config for Runtime {
        type Event = Event;
    }
    
ارسال و مشاهده رویدادها

برای ارسال و مشاهده رویدادها در یک بلاکچین Substrate، از ابزارهای مختلف CLI و RPC می‌توان استفاده کرد. این ابزارها به شما امکان مشاهده رویدادهای منتشرشده در بلاکچین را می‌دهند. به‌عنوان مثال، می‌توانید از دستور زیر برای مشاهده رویدادهای یک بلاک خاص استفاده کنید:

# مشاهده رویدادها در بلاکچین با استفاده از ابزار CLI
substrate --chain=local-testnet --exec "system_events" --signer Alice

در اینجا:

  • system_events: دستور برای مشاهده تمام رویدادهای سیستم در بلاکچین.
  • --signer Alice: استفاده از کلید خصوصی Alice برای امضای تراکنش‌ها.
جمع‌بندی

Event‌ها در Substrate ابزاری قدرتمند برای گزارش تغییرات و وضعیت‌ها در بلاکچین هستند. با استفاده از رویدادها می‌توان اطلاعاتی در مورد تراکنش‌ها، وضعیت‌ها و خطاها به بیرون از سیستم ارسال کرد تا کلاینت‌ها از وضعیت بلاکچین مطلع شوند. برای تعریف و استفاده از Event‌ها در Pallet‌ها، ابتدا باید آن‌ها را در قالب enum‌ها تعریف کرده و سپس در توابع قابل‌اجرا از ماکرو Self::deposit_event() برای انتشار آن‌ها استفاده کنید. این فرآیند، علاوه بر تسهیل در مدیریت وضعیت‌ها، به کاربران و سیستم‌های دیگر کمک می‌کند تا به‌روزترین اطلاعات را از بلاکچین دریافت کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”ارسال و دریافت Eventها در شبکه” subtitle=”توضیحات کامل”]Event ها در Substrate، برای ارسال اطلاعات به خارج از بلاکچین و اطلاع‌رسانی در مورد تغییرات در سیستم طراحی شده‌اند. این رویدادها برای گزارش وضعیت‌ها و تغییرات در بلاکچین به کار می‌روند و می‌توانند توسط کلاینت‌ها و یا سیستم‌های دیگر مصرف شوند. ارسال و دریافت Event‌ها در شبکه Substrate فرایندهای مهمی هستند که به شبکه کمک می‌کنند تا اطلاعات مهم مانند تراکنش‌ها، وضعیت‌ها و خطاها را به‌طور شفاف و امن به سایر بخش‌ها ارسال کند.

در این بخش، به نحوه ارسال Event‌ها از Pallet‌ها و دریافت آن‌ها در شبکه پرداخته خواهد شد.

نحوه ارسال Event‌ها در شبکه

برای ارسال Event‌ها در Substrate، شما باید از ماکرو Self::deposit_event() که توسط Pallet در نظر گرفته شده است، استفاده کنید. این ماکرو به شما این امکان را می‌دهد که رویدادهای دلخواه خود را به شبکه ارسال کنید تا در تاریخچه بلاکچین ذخیره شوند و در دسترس باشند.

در واقع، وقتی رویدادها در Substrate به ثبت می‌رسند، آن‌ها در بلاک‌هایی که تراکنش‌های آن‌ها در سیستم ثبت می‌شود، ذخیره می‌شوند. این به این معناست که این رویدادها به‌صورت دائمی در بلاکچین قرار خواهند گرفت و می‌توانند توسط سایر کلاینت‌ها یا سیستم‌ها مشاهده شوند.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, amount: u32) -> DispatchResult {
        let sender = ensure_signed(origin)?;

        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // انجام عملیات انتقال
        <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        
        // انتشار رویداد موفقیت‌آمیز
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد:

  • Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));: با این دستور، رویداد Transferred به شبکه ارسال می‌شود که حاوی اطلاعات انتقال مانند آدرس فرستنده، آدرس گیرنده و مقدار انتقالی است.
  • این رویداد در بلاکچین ذخیره می‌شود و به‌طور دائم قابل دسترسی است.
نحوه دریافت Event‌ها در شبکه

دریافت Event‌ها در شبکه به این معناست که شما می‌توانید از این رویدادها برای گرفتن اطلاعات مربوط به تغییرات در بلاکچین استفاده کنید. کلاینت‌ها و سیستم‌های دیگر می‌توانند از API‌های RPC برای دریافت اطلاعات از شبکه استفاده کنند.

در Substrate، برای دریافت رویدادها می‌توان از ابزار RPC استفاده کرد. این ابزار به شما این امکان را می‌دهد که از طریق یک کلاینت با شبکه تعامل کرده و رویدادهای منتشرشده را مشاهده کنید. برای دریافت Event‌ها از شبکه، می‌توانید از متدهایی مانند system_events در RPC استفاده کنید.

نحوه استفاده از RPC برای دریافت Event‌ها

برای مشاهده Event‌های ارسال‌شده در شبکه، از متد system_events در RPC استفاده می‌شود. به کمک این متد، می‌توانید رویدادهایی را که در بلاکچین اتفاق افتاده‌اند، مشاهده کنید.

مثال دستور برای مشاهده رویدادها از طریق CLI:

# مشاهده رویدادهای سیستم در بلاکچین با استفاده از RPC
substrate --chain=local-testnet --exec "system_events" --signer Alice

در اینجا:

  • system_events: این متد برای نمایش تمام رویدادهایی است که در شبکه ارسال شده‌اند.
  • --signer Alice: استفاده از کلید خصوصی Alice برای امضای درخواست‌ها.

پس از اجرای این دستور، اطلاعات مربوط به رویدادها (مثل رویدادهای انتقال یا تغییرات موجودی) نمایش داده می‌شود.

ذخیره‌سازی و مشاهده Event‌ها

رویدادهای ارسال‌شده در Substrate به‌طور دائمی در شبکه ذخیره می‌شوند. این اطلاعات در ساختار block بلاکچین ذخیره می‌شود و از طریق هر کلاینت که به شبکه متصل است، قابل دسترسی هستند.

همچنین، ابزارهای Explorer مانند Polkadot.js و Substrate Front-End Template می‌توانند برای مشاهده و پیگیری Event‌ها در شبکه‌های مختلف Substrate استفاده شوند. این ابزارها به شما امکان می‌دهند تا رویدادهای مختلف را بر اساس بلاک‌ها، اکشن‌ها یا شرایط خاص فیلتر کنید.

جمع‌بندی

ارسال و دریافت Event‌ها در شبکه Substrate به‌طور مؤثر اطلاعات حیاتی را در مورد وضعیت‌های مختلف بلاکچین در دسترس قرار می‌دهد. این رویدادها می‌توانند به کاربران و سیستم‌ها در تحلیل و نظارت بر تغییرات بلاکچین کمک کنند. با استفاده از ماکرو Self::deposit_event()، رویدادها به شبکه ارسال می‌شوند و با استفاده از RPC، کلاینت‌ها می‌توانند این رویدادها را دریافت کرده و پردازش کنند. این فرآیندها، یکی از اجزای اساسی برای تعامل با بلاکچین‌های ساخته‌شده بر روی Substrate محسوب می‌شوند و به‌طور گسترده برای اطلاع‌رسانی به‌کار می‌روند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت خطاها و تعریف Error Handling سفارشی” subtitle=”توضیحات کامل”]در بلاکچین‌ها و به‌ویژه در ساختار Substrate، مدیریت خطاها یکی از مهم‌ترین جنبه‌های توسعه است. از آنجایی که هر تراکنش و عملیات در بلاکچین باید شفاف و امن باشد، ضروری است که خطاها به‌طور صحیح مدیریت شوند و این خطاها به‌صورت دقیق و مفهومی گزارش داده شوند. در این بخش به نحوه مدیریت خطاها و تعریف Error Handling سفارشی در Pallet‌های Substrate پرداخته می‌شود.

ساختار خطاها در Substrate

در Substrate، Error Handling به‌وسیله‌ی Enum ها و ماکروها انجام می‌شود. این Enum ها خطاهایی که ممکن است در حین اجرای تابع‌های یک Pallet رخ دهند را مشخص می‌کنند. هر خطا در Substrate باید به‌طور دقیق تعریف شود تا بتوان آن را در صورت وقوع گزارش کرد و از آن برای اطلاع‌رسانی به کاربران استفاده کرد.

در Substrate، Pallet‌ها به کمک ماکروهایی مانند #[error] می‌توانند خطاهای خود را تعریف کنند و در صورت بروز خطا، آن‌ها را گزارش دهند.

تعریف خطاهای سفارشی در Pallet

برای تعریف Error Handling سفارشی، ابتدا باید یک Enum تعریف کنیم که انواع مختلف خطاها را در خود جای دهد. سپس از این خطاها در توابع Pallet خود استفاده خواهیم کرد.

مثال:

#[pallet::error]
pub enum Error<T> {
    InsufficientBalance,
    InvalidRecipient,
    TransferFailed,
}

در این مثال، ما یک Enum به نام Error تعریف کرده‌ایم که سه نوع خطای مختلف را شامل می‌شود:

  • InsufficientBalance: به این معنا که موجودی فرستنده کافی نیست.
  • InvalidRecipient: به این معنا که گیرنده نامعتبر است.
  • TransferFailed: زمانی که عملیات انتقال به دلایلی شکست می‌خورد.
استفاده از خطاها در توابع Pallet

پس از تعریف خطاها، می‌توان از آن‌ها در توابع مختلف Pallet برای بررسی شرایط خاص و جلوگیری از بروز اشتباهات استفاده کرد. با استفاده از ماکروهایی مانند ensure! و Result می‌توانیم به‌طور مؤثری خطاها را مدیریت کنیم.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, amount: u32) -> DispatchResult {
        let sender = ensure_signed(origin)?;

        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // بررسی گیرنده
        ensure!(dest != sender, Error::<T>::InvalidRecipient);

        // انجام انتقال
        let success = <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        ensure!(success, Error::<T>::TransferFailed);

        // انتشار رویداد انتقال
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد:

  • ensure!(balance >= amount, Error::<T>::InsufficientBalance);: اگر موجودی کافی نباشد، خطای InsufficientBalance فعال می‌شود.
  • ensure!(dest != sender, Error::<T>::InvalidRecipient);: اگر گیرنده و فرستنده یکسان باشند، خطای InvalidRecipient فعال می‌شود.
  • ensure!(success, Error::<T>::TransferFailed);: اگر عملیات انتقال با شکست مواجه شود، خطای TransferFailed فعال می‌شود.
نوع‌نمایی خطاها (Error Type)

در کدهای بالا، وقتی که یک خطا رخ می‌دهد، به‌طور خودکار نوع خطا بر اساس Enum تعریف‌شده به بازگشت DispatchResult ارسال می‌شود. DispatchResult در حقیقت می‌تواند یکی از دو مقدار Ok(()) یا Err باشد.

ما در مثال‌های بالا از ensure! استفاده کرده‌ایم که به‌صورت خودکار در صورت بروز خطا، نوع خطا را بازمی‌گرداند. این دستورات باعث می‌شوند که خطاها به‌درستی مدیریت شده و به‌صورت امن در بلاکچین ثبت شوند.

ثبت خطاها در بلاکچین

زمانی که یک خطا در یک تراکنش رخ می‌دهد، این خطا در بلاکچین ثبت می‌شود و در ادامه می‌توان از طریق RPC و Explorer‌های مختلف مانند Polkadot.js آن را مشاهده کرد. این امکان باعث می‌شود که تمامی خطاها به‌طور دائمی در بلاکچین ذخیره شوند و قابل بازیابی و بررسی باشند.

جمع‌بندی

مدیریت خطاها در Substrate با استفاده از Enum و ماکروهای مناسب به‌راحتی انجام می‌شود. تعریف خطاهای سفارشی به توسعه‌دهندگان این امکان را می‌دهد که شرایط خاص خود را بررسی کرده و خطاها را به‌طور دقیق مدیریت کنند. با استفاده از دستورات ensure!، می‌توان از بروز خطاها جلوگیری کرده و در صورت وقوع خطا، به‌سرعت و به‌طور دقیق آن‌ها را گزارش کرد. این ویژگی، به افزایش اطمینان و امنیت شبکه کمک می‌کند و توسعه‌دهندگان را قادر می‌سازد تا سیستم‌های قابل‌اعتمادتری بسازند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 6. مدیریت سطح دسترسی و امضاها در Palletها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”کنترل دسترسی به توابع Pallet با استفاده از Origin” subtitle=”توضیحات کامل”]Origin در Substrate، به‌عنوان یک ابزار مهم برای کنترل دسترسی به توابع مختلف Pallet استفاده می‌شود. Origin به‌طور کلی به یک شیء اشاره دارد که حاوی اطلاعات مربوط به منبع فراخوانی یک تراکنش یا تابع است. این ابزار به توسعه‌دهندگان این امکان را می‌دهد که به‌طور مؤثری تعیین کنند کدام کاربران یا حساب‌ها مجاز به فراخوانی توابع خاص در یک Pallet باشند. در این بخش، نحوه کنترل دسترسی به توابع Pallet با استفاده از Origin را بررسی می‌کنیم.

مفهوم Origin

در Substrate، Origin نمایانگر منبع فراخوانی تراکنش است. این می‌تواند یکی از موارد زیر باشد:

  • Signed: نمایانگر یک حساب که تراکنش را امضا کرده است.
  • None: نمایانگر تراکنشی است که از هیچ حساب کاربری صادر نمی‌شود (برای مثال در هنگام فراخوانی از طرف قراردادهای هوشمند یا سایر اجزای سیستم).
  • Root: نمایانگر فراخوانی‌های ویژه‌ای است که تنها توسط کاربر یا حساب “Root” انجام می‌شود، که می‌تواند به‌صورت کامل به شبکه دسترسی داشته باشد.
استفاده از Origin برای کنترل دسترسی

یکی از مهم‌ترین ویژگی‌های Origin در Substrate این است که می‌توانیم دسترسی به توابع مختلف را محدود کنیم. با استفاده از Origin می‌توانیم تعیین کنیم که فقط کاربران خاص یا حساب‌های ویژه (مثل Root یا Signed) مجاز به فراخوانی یک تابع خاص باشند.

برای کنترل دسترسی به توابع Pallet، می‌توانیم از ویژگی‌های ensure_signed()، ensure_root() و سایر ابزارهای Origin استفاده کنیم.

مثال: استفاده از ensure_signed برای کنترل دسترسی

در این مثال، تابعی را تعریف می‌کنیم که تنها برای حساب‌هایی که تراکنش خود را امضا کرده‌اند (یعنی کاربران Signed) قابل دسترسی است.

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(origin: OriginFor<T>, dest: T::AccountId, amount: u32) -> DispatchResult {
        // بررسی اینکه آیا فراخوانی توسط یک حساب امضا شده است
        let sender = ensure_signed(origin)?;

        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // انتقال وجوه
        let success = <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        ensure!(success, Error::<T>::TransferFailed);

        // ثبت رویداد
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد:

  • ensure_signed(origin)?: این دستور بررسی می‌کند که آیا تراکنش از طرف یک حساب امضا شده (Signed) انجام شده است یا خیر. اگر این‌طور نباشد، خطای مربوطه به‌صورت خودکار ایجاد می‌شود.
مثال: استفاده از ensure_root برای دسترسی فقط به Root

در این مثال، تابعی را ایجاد می‌کنیم که فقط توسط حساب Root (که در Substrate معمولاً حسابی با بالاترین سطح دسترسی است) قابل فراخوانی است.

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn emergency_shutdown(origin: OriginFor<T>) -> DispatchResult {
        // بررسی اینکه آیا فراخوانی از طرف Root است
        ensure_root(origin)?;

        // انجام عملیات Shutdown
        // کد مربوط به عملیات قطع شبکه یا اقدامات ویژه
        Ok(())
    }
}

در این کد:

  • ensure_root(origin)?: این دستور فقط به حساب‌هایی که دارای دسترسی Root هستند اجازه می‌دهد تا تابع emergency_shutdown را فراخوانی کنند. در صورتی که منبع فراخوانی غیر از Root باشد، خطا صادر می‌شود.
استفاده از Origin برای محدودیت‌های پیچیده‌تر

علاوه بر دستورات ساده ensure_signed() و ensure_root()، در Substrate می‌توان از Origin برای ایجاد محدودیت‌های پیچیده‌تری استفاده کرد. برای مثال، می‌توانیم ترکیب‌هایی از Signed و Root را به‌طور هم‌زمان استفاده کنیم یا از ویژگی‌های اضافی Origin مانند T::AccountId برای انجام بررسی‌های پیچیده‌تر استفاده کنیم.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer_with_limit(
        origin: OriginFor<T>, 
        dest: T::AccountId, 
        amount: u32
    ) -> DispatchResult {
        // بررسی اینکه آیا تراکنش توسط یک حساب امضا شده است
        let sender = ensure_signed(origin)?;

        // فرض کنیم که فقط حساب‌های خاص می‌توانند انتقال‌های بزرگتر از 100 واحد را انجام دهند
        if amount > 100 {
            ensure!(sender == T::RootAccount::get(), Error::<T>::NotAuthorized);
        }

        // انجام عملیات انتقال
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        let success = <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        ensure!(success, Error::<T>::TransferFailed);

        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد:

  • ensure!(sender == T::RootAccount::get(), Error::<T>::NotAuthorized);: این دستور اطمینان حاصل می‌کند که تنها حساب خاصی (که در اینجا به‌عنوان حساب Root در نظر گرفته شده) می‌تواند تراکنش‌هایی با مقادیر خاصی را انجام دهد.
جمع‌بندی

با استفاده از Origin در Substrate می‌توان به‌راحتی دسترسی به توابع مختلف Pallet را کنترل کرد. ما از دستورات مختلفی مانند ensure_signed() و ensure_root() برای محدود کردن دسترسی به توابع استفاده می‌کنیم. این روش‌ها به‌طور مؤثری از دسترسی غیرمجاز جلوگیری کرده و امنیت شبکه را تضمین می‌کنند. در صورتی که نیاز به محدودیت‌های پیچیده‌تری باشد، می‌توان از ترکیب‌های مختلف Origin و سایر ابزارهای موجود استفاده کرد تا اطمینان حاصل شود که تنها کاربران مجاز به اجرای عملیات خاص دسترسی دارند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی Signerها و تأیید هویت کاربران” subtitle=”توضیحات کامل”]در سیستم‌های بلاکچینی، Signerها به‌عنوان عامل‌هایی شناخته می‌شوند که عملیات دیجیتال مانند امضای تراکنش‌ها را انجام می‌دهند. این مفهوم در Substrate برای تأیید هویت کاربران و اعتبارسنجی تراکنش‌ها اهمیت زیادی دارد. در این بخش، به بررسی Signerها و نحوه تأیید هویت کاربران در Substrate می‌پردازیم.

مفهوم Signer در Substrate

در Substrate، Signer به‌طور خاص به هر حساب کاربری که قادر به انجام تراکنش‌ها و امضای آن‌ها باشد اطلاق می‌شود. هر تراکنش در شبکه باید توسط یک Signer امضا شود تا از نظر امنیتی و قانونی معتبر باشد. امضای تراکنش‌ها فرآیندی است که هویت فرستنده را تأیید می‌کند و اطمینان حاصل می‌کند که تراکنش‌ها از طرف کاربر معتبر ارسال شده است.

هر Signer در Substrate معمولاً به‌عنوان یک حساب (Account) تعریف می‌شود که از یک کلید عمومی و کلید خصوصی برای انجام امضا استفاده می‌کند.

نحوه استفاده از Signer در Substrate

برای استفاده از Signerها در Substrate، از Origin برای تأیید هویت و امضای تراکنش‌ها استفاده می‌کنیم. در اینجا، از دستورات ensure_signed() برای تأیید این‌که تراکنش توسط یک حساب امضا شده است استفاده می‌شود. در این صورت، تراکنش تنها در صورتی که توسط یک Signer معتبر امضا شود، اجرا خواهد شد.

مثال: استفاده از ensure_signed() برای تأیید هویت

در این مثال، تابعی را در نظر می‌گیریم که فقط توسط Signerها (حساب‌های امضا شده) قابل دسترسی باشد.

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn transfer(
        origin: OriginFor<T>, 
        dest: T::AccountId, 
        amount: u32
    ) -> DispatchResult {
        // بررسی اینکه تراکنش از طرف یک حساب امضا شده است
        let sender = ensure_signed(origin)?;

        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // انتقال وجوه
        let success = <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        ensure!(success, Error::<T>::TransferFailed);

        // ثبت رویداد
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد:

  • ensure_signed(origin)?: این دستور اطمینان حاصل می‌کند که تراکنش از طرف یک حساب امضا شده است. در غیر این صورت، تراکنش رد می‌شود.
استفاده از Signerها برای تأیید هویت

تأیید هویت در Substrate به‌طور معمول از طریق مفاهیم کلید عمومی و کلید خصوصی انجام می‌شود. وقتی یک تراکنش توسط کاربر ارسال می‌شود، سیستم باید بررسی کند که آیا امضا از یک حساب معتبر صادر شده است یا خیر. این فرآیند معمولاً به این صورت است که:

  1. کلید خصوصی به‌عنوان یک کد امنیتی برای امضای تراکنش استفاده می‌شود.
  2. کلید عمومی برای شناسایی و تأیید هویت صاحب کلید خصوصی مورد استفاده قرار می‌گیرد.
استفاده از Signer در تراکنش‌های پیچیده‌تر

در برخی مواقع ممکن است لازم باشد که از چندین Signer برای تأیید یک تراکنش استفاده شود. در این موارد، می‌توان از ترکیب چند حساب برای تأیید تراکنش استفاده کرد.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn multi_sign_transfer(
        origin: OriginFor<T>, 
        dest: T::AccountId, 
        amount: u32
    ) -> DispatchResult {
        // بررسی اینکه تراکنش از طرف یک حساب امضا شده است
        let sender = ensure_signed(origin)?;

        // بررسی اینکه آیا تراکنش به‌طور مشترک امضا شده است
        let co_signer = ensure_signed(origin)?;

        // بررسی موجودی فرستنده
        let balance = <Pallet<T>>::get_balance(&sender);
        ensure!(balance >= amount, Error::<T>::InsufficientBalance);

        // انتقال وجوه
        let success = <Pallet<T>>::transfer_funds(&sender, &dest, amount);
        ensure!(success, Error::<T>::TransferFailed);

        // ثبت رویداد
        Self::deposit_event(Event::<T>::Transferred(sender, dest, amount));

        Ok(())
    }
}

در این کد، یک تراکنش فقط در صورتی انجام می‌شود که دو حساب مختلف (مربوط به دو Signer مختلف) آن را امضا کنند.

جمع‌بندی

Signerها در Substrate، نقش مهمی در تأیید هویت کاربران دارند. با استفاده از Signerها، می‌توان اطمینان حاصل کرد که تراکنش‌ها از طرف کاربران معتبر امضا و ارسال می‌شوند. با استفاده از ابزارهایی مانند ensure_signed() و Origin می‌توان کنترل‌های دقیقی روی تأیید هویت کاربران و امضای تراکنش‌ها اعمال کرد. این فرآیند برای تأمین امنیت و اطمینان از صحت تراکنش‌ها در شبکه‌های بلاکچینی بسیار ضروری است.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”مدیریت سطوح دسترسی کاربران و نقش‌های مختلف در Substrate” subtitle=”توضیحات کامل”]در شبکه‌های بلاکچینی، مدیریت دسترسی‌ها و نقش‌های کاربران برای اطمینان از امنیت و شفافیت ضروری است. در Substrate، این مدیریت از طریق پالت‌های امنیتی و تعریف نقش‌ها (Roles) انجام می‌شود. با استفاده از این سیستم، می‌توان سطح دسترسی کاربران را بر اساس نیازهای خاص پروژه‌های بلاکچینی تنظیم کرد. در این بخش، نحوه مدیریت سطوح دسترسی کاربران و نقش‌های مختلف در Substrate را بررسی می‌کنیم.

مفهوم مدیریت دسترسی در Substrate

در Substrate، برای مدیریت دسترسی‌ها از مفهوم Origin استفاده می‌شود. Origin تعیین می‌کند که درخواست‌ها یا تراکنش‌ها از طرف کدام کاربر یا نهاد ارسال شده‌اند. با استفاده از این اطلاعات، می‌توان دسترسی‌ها را به توابع مختلف محدود کرد.

به‌طورکلی، برای محدود کردن دسترسی به توابع و پالت‌ها می‌توان از Role-based Access Control (RBAC) استفاده کرد. در این سیستم، هر کاربر می‌تواند نقش خاصی داشته باشد که محدودیت‌های مختلفی را بر اساس آن نقش اعمال می‌شود.

نقش‌ها (Roles) در Substrate

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

برای تعریف نقش‌ها، از پالت‌هایی مانند pallet-membership یا pallet-collective استفاده می‌شود که این امکان را به شما می‌دهند تا نقش‌های مختلف را مدیریت کنید. در این پالت‌ها، می‌توان اعضای یک گروه یا یک سازمان را با نقش‌های مشخص تعریف کرد.

تنظیم دسترسی‌ها با استفاده از Origin

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

به‌طور معمول از دستوراتی مانند ensure_signed() برای بررسی این‌که تراکنش از طرف یک Signatory معتبر ارسال شده است استفاده می‌شود. اما اگر بخواهیم دسترسی‌ها را بر اساس نقش‌های خاص محدود کنیم، باید از ensure_root() یا ensure_member() استفاده کنیم.

مثال از استفاده از نقش‌ها و دسترسی‌ها

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

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn restricted_function(
        origin: OriginFor<T>,
    ) -> DispatchResult {
        // بررسی اینکه آیا درخواست از طرف مدیر یا عضو معتبر است
        let who = ensure_signed(origin)?;

        // اگر کاربر عضو گروه نیست، خطای دسترسی داده می‌شود
        ensure!(T::Membership::is_member(&who), Error::<T>::NotAMember);

        // انجام عملیات خاص برای اعضای مجاز
        Ok(())
    }
}

در این مثال:

  • ensure_signed(origin)?: این دستور اطمینان می‌دهد که تراکنش از طرف یک کاربر امضا شده است.
  • T::Membership::is_member(&who): این دستور بررسی می‌کند که آیا کاربر از اعضای گروه است یا خیر. در صورتی که کاربر عضو نباشد، خطای دسترسی داده می‌شود.
استفاده از pallet-membership برای مدیریت نقش‌ها

pallet-membership یکی از پالت‌های پرکاربرد در Substrate است که برای مدیریت عضویت کاربران در گروه‌ها یا جمع‌های مختلف استفاده می‌شود. در این پالت می‌توان اعضا را به گروه‌های خاص اضافه کرد و دسترسی‌های مختلف را برای هر گروه تنظیم کرد.

برای استفاده از pallet-membership، مراحل زیر را دنبال می‌کنیم:

  1. پیکربندی pallet-membership در Cargo.toml:
[dependencies]
pallet-membership = { version = "3.0", default-features = false }
  1. اضافه کردن پالت به پلتفرم:
#[pallet::call]
impl<T: Config> Pallet<T> {
    #[weight = 10_000]
    pub fn add_member(
        origin: OriginFor<T>,
        new_member: T::AccountId,
    ) -> DispatchResult {
        // بررسی اینکه آیا تراکنش از طرف یک مدیر (Admin) ارسال شده است
        let sender = ensure_signed(origin)?;
        ensure!(T::Admin::is_admin(&sender), Error::<T>::NotAdmin);

        // اضافه کردن عضو جدید به گروه
        T::Membership::add_member(new_member);

        Ok(())
    }
}

در اینجا:

  • T::Admin::is_admin(&sender) بررسی می‌کند که آیا فرستنده، یک مدیر است یا خیر.
  • T::Membership::add_member(new_member)، عضویت جدید را به گروه اضافه می‌کند.
جمع‌بندی

مدیریت سطوح دسترسی و نقش‌های مختلف در Substrate به‌وسیله ابزارهای قدرتمند مانند Origin و pallet-membership امکان‌پذیر است. این ابزارها به شما اجازه می‌دهند تا دسترسی‌ها را بر اساس نیازهای پروژه خود تنظیم کرده و از امنیت و کنترل دقیق بر روی شبکه خود اطمینان حاصل کنید. با استفاده از این سیستم‌ها، می‌توان اطمینان حاصل کرد که تنها کاربران معتبر و با نقش‌های مشخص می‌توانند به توابع و منابع خاصی دسترسی داشته باشند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 7. ایجاد و مدیریت Hooks در Runtime”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”معرفی Lifecycle Hooks در Substrate” subtitle=”توضیحات کامل”]در توسعه بلاکچین‌ها با استفاده از Substrate، می‌توان از مفهومی به نام Lifecycle Hooks برای انجام عملیات‌های خاص در مراحل مختلف زندگی یک پالت استفاده کرد. این hooks به شما این امکان را می‌دهند که به صورت خودکار، در زمان‌های خاصی از فرآیند اجرای پالت‌ها (مانند قبل از شروع، پس از اجرای یک تراکنش، و یا هنگام حذف) کدهایی اجرا کنید. این ابزار به‌ویژه زمانی مفید است که بخواهید شرایط خاصی را برای عملیات‌های مختلف مدیریت کنید.

Lifecycle Hooks به‌طور کلی به عملیات‌های خاصی که در طول زمان زندگی یک پالت رخ می‌دهند اشاره دارد و این عملیات می‌تواند شامل مواردی مانند راه‌اندازی پالت، شروع و پایان تراکنش‌ها، بروز رسانی وضعیت و حتی پاک‌سازی منابع باشد.

مفهوم Lifecycle Hooks

در Substrate، هر پالت می‌تواند در طی عمر خود در معرض تغییرات مختلفی قرار گیرد که به صورت تابعی توسط Lifecycle Hooks کنترل می‌شود. این تغییرات ممکن است شامل تغییرات در وضعیت پالت، ارسال تراکنش‌ها، اعمال رویدادها، یا حتی حذف پالت باشد.

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

مراحل مختلف Lifecycle Hooks در Substrate

در Substrate، چندین نوع hook در پالت‌ها وجود دارد که می‌توانید از آن‌ها استفاده کنید. این مراحل به طور کلی شامل موارد زیر می‌شود:

  1. OnInitialize: این hook زمانی فراخوانی می‌شود که پالت به‌طور کامل راه‌اندازی شود و قبل از انجام هرگونه عملیات بر روی آن پالت، می‌توان اقداماتی را انجام داد.
  2. OnFinalize: زمانی که یک بلاک به پایان می‌رسد و باید عملیات‌هایی انجام شود، این hook فعال می‌شود. معمولاً از این hook برای پردازش‌ها یا پاکسازی منابع استفاده می‌شود.
  3. OnDispatch: این hook در زمانی که تراکنشی برای پالت ارسال می‌شود، فراخوانی می‌شود. این hook به شما این امکان را می‌دهد تا قبل از انجام هر عملیاتی، بررسی‌هایی انجام دهید.
OnInitialize

این تابع زمانی فراخوانی می‌شود که بلاک جدیدی به شبکه اضافه شود یا زمانی که پالت جدیدی برای اولین بار در سیستم راه‌اندازی شود. این hook به‌طور کلی برای تنظیمات اولیه و آماده‌سازی محیط برای استفاده از پالت استفاده می‌شود.

در اینجا یک مثال از استفاده از on_initialize آورده شده است:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::initialization]
    fn on_initialize(block_number: T::BlockNumber) -> Weight {
        // کدهای ابتدایی برای راه‌اندازی پالت
        log::info!("پالت در بلاک شماره {:?} راه‌اندازی شد.", block_number);
        10_000 // هزینه عملیات
    }
}

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

OnFinalize

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

مثال ساده‌ای از استفاده از on_finalize:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::finalization]
    fn on_finalize(block_number: T::BlockNumber) {
        // عملیات‌هایی برای پایان بلاک
        log::info!("بلاک شماره {:?} به پایان رسید.", block_number);
    }
}

در اینجا، پس از تکمیل هر بلاک، یک لاگ ثبت می‌شود که نشان‌دهنده پایان بلاک است.

OnDispatch

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

مثال استفاده از on_dispatch:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::dispatch]
    fn on_dispatch(origin: OriginFor<T>, value: u32) -> DispatchResult {
        let who = ensure_signed(origin)?;
        
        // بررسی میزان مجاز بودن تراکنش
        if value > 1000 {
            Err(Error::<T>::TransactionTooLarge)?
        } else {
            // انجام عملیات
            Ok(())
        }
    }
}

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

مثال کامل از استفاده از Lifecycle Hooks در Substrate

در این مثال، یک پالت ساده داریم که از تمامی Lifecycle Hooks استفاده می‌کند:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::initialization]
        fn on_initialize(block_number: T::BlockNumber) -> Weight {
            log::info!("پالت راه‌اندازی شد. بلاک: {:?}", block_number);
            10_000
        }

        #[pallet::finalization]
        fn on_finalize(block_number: T::BlockNumber) {
            log::info!("پالت به پایان رسید. بلاک: {:?}", block_number);
        }

        #[pallet::dispatch]
        fn on_dispatch(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let who = ensure_signed(origin)?;

            if value > 1000 {
                Err(Error::<T>::TransactionTooLarge)?
            } else {
                log::info!("تراکنش معتبر. کاربر: {:?}", who);
                Ok(())
            }
        }
    }
}

در این مثال:

  • در on_initialize یک لاگ برای شروع پالت ثبت می‌شود.
  • در on_finalize یک لاگ برای پایان بلاک ثبت می‌شود.
  • در on_dispatch چک می‌کنیم که تراکنش معتبر باشد یا خیر.
جمع‌بندی

Lifecycle Hooks در Substrate ابزار قدرتمندی برای مدیریت و کنترل فرایندهای مختلف در طول زندگی یک پالت است. این hooks به شما این امکان را می‌دهند که بتوانید عملیات‌های مختلفی را در مراحل مختلف پردازش بلاک‌ها و تراکنش‌ها انجام دهید. با استفاده از این ابزارها، می‌توان بر روی پالت‌ها کنترل دقیقی اعمال کرده و به‌طور خودکار وظایف خاصی را انجام داد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از Hooks برای اجرای عملیات زمان‌بندی‌شده در Substrate” subtitle=”توضیحات کامل”]در سیستم‌های بلاکچین، یکی از نیازهای معمول، اجرای عملیات به‌صورت زمان‌بندی‌شده و خودکار است. این عملیات می‌تواند شامل وظایفی مانند پردازش تراکنش‌ها، اجرای پالیسی‌های امنیتی، به‌روزرسانی وضعیت و غیره باشد. در Substrate، این عملیات‌های زمان‌بندی‌شده را می‌توان از طریق Lifecycle Hooks پیاده‌سازی کرد. در این بخش، به نحوه استفاده از Hooks برای انجام عملیات زمان‌بندی‌شده در پالت‌ها پرداخته خواهد شد.

مفهوم عملیات زمان‌بندی‌شده در Substrate

عملیات زمان‌بندی‌شده معمولاً به این صورت است که یک تابع در بازه‌های زمانی مشخصی به‌طور خودکار اجرا شود. به عنوان مثال، ممکن است بخواهید یک عملیات را هر ۱۰ بلاک اجرا کنید یا اینکه به‌صورت دوره‌ای برخی از داده‌ها را پردازش کنید.

در Substrate، این نوع عملیات‌ها را می‌توان از طریق یک Hook به نام on_idle یا با استفاده از Scheduled Calls پیاده‌سازی کرد.

استفاده از on_idle در Substrate

یکی از روش‌هایی که می‌توان برای پیاده‌سازی عملیات‌های زمان‌بندی‌شده استفاده کرد، hook on_idle است. این Hook زمانی فراخوانی می‌شود که هیچ تراکنش جدیدی در یک بلاک وارد نشده باشد. بنابراین، می‌توان از آن برای اجرای عملیات‌هایی که نیاز به زمان دارند استفاده کرد.

در اینجا یک مثال ساده از نحوه استفاده از on_idle آورده شده است:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use sp_runtime::traits::Zero;

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        fn on_idle() -> Weight {
            // عملیاتی که در هنگام بی‌کاری بلاک باید انجام شود
            log::info!("هیچ تراکنشی برای پردازش وجود ندارد. عملیات زمان‌بندی‌شده اجرا می‌شود.");
            10_000 // وزن عملیات
        }
    }
}

در این مثال، on_idle زمانی اجرا می‌شود که هیچ تراکنشی برای پردازش وجود نداشته باشد. این hook می‌تواند برای اجرای عملیات‌هایی استفاده شود که نیاز به زمان‌های کوتاه یا دوره‌ای دارند.

استفاده از Scheduled Calls برای عملیات زمان‌بندی‌شده

یکی دیگر از روش‌های معمول برای اجرای عملیات زمان‌بندی‌شده در Substrate، استفاده از Scheduled Calls است. این امکان به شما اجازه می‌دهد تا تراکنش‌هایی را در آینده برنامه‌ریزی کنید.

برای استفاده از Scheduled Calls در Substrate، نیاز است که از pallet-scheduler استفاده کنید. با این پالت می‌توانید تراکنش‌ها را در آینده زمان‌بندی کنید.

مراحل استفاده از pallet-scheduler برای برنامه‌ریزی عملیات
  1. اضافه کردن pallet-scheduler به پروژه

اولین قدم برای استفاده از pallet-scheduler، افزودن آن به پیکربندی پالت است. این پالت به شما این امکان را می‌دهد که تراکنش‌ها را در زمان‌های مشخص‌شده اجرا کنید.

در فایل Cargo.toml، پالت pallet-scheduler را اضافه کنید:

[dependencies]
frame-support = { version = "3.0.0", default-features = false }
frame-system = { version = "3.0.0" }
pallet-scheduler = { version = "3.0.0" }
  1. تعریف وظایف زمان‌بندی‌شده در پالت

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

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_scheduler::{Call as SchedulerCall, pallet::Pallet as Scheduler};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        fn schedule_task(origin: OriginFor<T>, when: T::BlockNumber) -> DispatchResult {
            let who = ensure_signed(origin)?;

            // برنامه‌ریزی یک تراکنش برای اجرا در بلاک خاص
            let call = SchedulerCall::<T>::schedule {
                when,
                priority: 1,
                call: Call::<T>::on_scheduled_operation { who }.into(),
                maybe_periodic: None,
            };

            // ثبت تراکنش در سیستم
            Scheduler::<T>::schedule(origin, call)?;

            Ok(())
        }

        // عملیات زمان‌بندی‌شده
        #[pallet::call]
        fn on_scheduled_operation(who: T::AccountId) -> DispatchResult {
            log::info!("اجرای عملیات زمان‌بندی‌شده توسط {:?}", who);
            Ok(())
        }
    }
}

در این مثال:

  • ما یک تابع schedule_task تعریف کرده‌ایم که یک تراکنش را برای اجرای یک عملیات خاص در یک بلاک خاص زمان‌بندی می‌کند.
  • در صورتی که تراکنش زمان‌بندی‌شده اجرا شود، تابع on_scheduled_operation فراخوانی می‌شود که عمل مورد نظر را انجام می‌دهد.
  1. زمان‌بندی تراکنش‌ها با استفاده از Scheduler

زمانی که تابع schedule_task اجرا می‌شود، یک تراکنش به زمان آینده می‌رود تا در بلاک مشخص‌شده اجرا شود. این تراکنش پس از رسیدن به زمان مورد نظر اجرا خواهد شد.

جمع‌بندی

در Substrate، برای پیاده‌سازی عملیات زمان‌بندی‌شده، می‌توان از ابزارهایی مانند on_idle و Scheduled Calls استفاده کرد. این ابزارها به توسعه‌دهندگان این امکان را می‌دهند تا عملیات‌های خاصی را به صورت خودکار و زمان‌بندی‌شده انجام دهند. با استفاده از این ابزارها، می‌توان اطمینان حاصل کرد که بلاکچین بدون نیاز به دخالت انسان، به‌طور خودکار وظایف مختلف خود را انجام می‌دهد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”پیاده‌سازی on_initialize و on_finalize در Pallet سفارشی” subtitle=”توضیحات کامل”]در Substrate، on_initialize و on_finalize دو تابع از Lifecycle Hooks هستند که به شما این امکان را می‌دهند که عملکردهایی را قبل و بعد از هر بلاک اجرا کنید. این توابع می‌توانند برای تنظیم و بازبینی وضعیت پالت، یا انجام وظایف خاص در چرخه زندگی بلاک‌ها استفاده شوند.

در این بخش، نحوه پیاده‌سازی این توابع در یک Pallet سفارشی را بررسی خواهیم کرد. همچنین، مثال‌هایی از کاربردهای مختلف این توابع ارائه خواهد شد.

مفهوم توابع on_initialize و on_finalize
  • on_initialize: این تابع قبل از اجرای هر تراکنش در یک بلاک، اجرا می‌شود. معمولا برای انجام وظایفی که باید قبل از پردازش تراکنش‌ها انجام شوند، مانند تنظیم وضعیت یا به‌روزرسانی متغیرهای مربوط به بلاک استفاده می‌شود.
  • on_finalize: این تابع پس از پردازش تمامی تراکنش‌ها و انجام عملیات‌های مربوط به بلاک، اجرا می‌شود. معمولاً برای وظایفی که باید پس از پایان هر بلاک انجام شوند، مانند ذخیره‌سازی داده‌ها یا ثبت اطلاعات نهایی در شبکه استفاده می‌شود.

پیاده‌سازی on_initialize و on_finalize در پالت

برای پیاده‌سازی این توابع در پالت خود، باید از ویژگی‌های frame_system::Pallet استفاده کنید و آنها را در پالت خود پیاده‌سازی کنید.

ساختار پالت برای استفاده از on_initialize و on_finalize

در اینجا یک مثال از پیاده‌سازی این توابع در یک پالت سفارشی آورده شده است:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // توابع on_initialize و on_finalize
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        // پیاده‌سازی تابع on_initialize
        #[pallet::call]
        pub fn on_initialize(n: T::BlockNumber) -> Weight {
            // عملیات‌هایی که در آغاز هر بلاک باید انجام شوند
            log::info!("on_initialize در بلاک {:?} اجرا شد", n);
            
            // می‌توانید متغیرهای پالت را بر اساس نیاز به‌روزرسانی کنید یا اقدامات خاصی انجام دهید
            10_000 // وزن عملیات
        }

        // پیاده‌سازی تابع on_finalize
        #[pallet::call]
        pub fn on_finalize(n: T::BlockNumber) -> Weight {
            // عملیات‌هایی که باید پس از پردازش تمامی تراکنش‌ها انجام شوند
            log::info!("on_finalize در بلاک {:?} اجرا شد", n);

            // برای عملیات‌هایی که به اتمام بلاک نیاز دارند، می‌توانید از اینجا استفاده کنید
            10_000 // وزن عملیات
        }
    }

    // توابع لازم برای مدیریت پالت
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn some_other_function(origin: OriginFor<T>) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // عملکردهای مختلف که مربوط به تراکنش‌ها یا اقدامات خاص هستند
            Ok(())
        }
    }
}
توضیحات کد:
  1. on_initialize:
    • این تابع در ابتدای هر بلاک فراخوانی می‌شود و در اینجا از آن برای ثبت پیامی در لاگ استفاده شده است.
    • شما می‌توانید از این تابع برای به‌روزرسانی متغیرهای مربوط به وضعیت پالت، یا انجام پردازش‌های خاص استفاده کنید.
    • وزن (Weight) مشخص‌کننده هزینه محاسباتی این عملیات است که می‌تواند به‌طور دلخواه تنظیم شود.
  2. on_finalize:
    • این تابع پس از اتمام پردازش تراکنش‌ها و انجام تمامی عملیات‌ها فراخوانی می‌شود.
    • در اینجا نیز یک پیام به لاگ ارسال شده است و می‌توانید از این تابع برای پردازش نهایی داده‌ها و ثبت وضعیت‌های پایانی استفاده کنید.
پیاده‌سازی وضعیت پالت در on_initialize

فرض کنید در پالت خود نیاز دارید که یک شمارنده یا متغیر وضعیت را در هر بلاک به‌روزرسانی کنید. شما می‌توانید این کار را در on_initialize انجام دهید.

#[pallet::call]
impl<T: Config> Pallet<T> {
    // پیاده‌سازی تابع on_initialize
    #[pallet::call]
    pub fn on_initialize(n: T::BlockNumber) -> Weight {
        // شمارش بلاک‌ها
        let current_count = <BlockCount<T>>::get();
        <BlockCount<T>>::put(current_count + 1);

        log::info!("on_initialize: شمارنده بلاک افزایش یافت به {:?}", current_count + 1);

        10_000 // وزن عملیات
    }
}

در این مثال، ما از یک متغیر ذخیره‌سازی به نام BlockCount استفاده کرده‌ایم که تعداد بلاک‌ها را ذخیره می‌کند. این متغیر در on_initialize به‌روز رسانی می‌شود.

پیاده‌سازی عملیات نظارت و ثبت در on_finalize

فرض کنید در on_finalize می‌خواهید که وضعیت خاصی را ثبت کنید یا داده‌های پایانی را ذخیره کنید. می‌توانید این کار را به سادگی در این تابع انجام دهید.

#[pallet::call]
impl<T: Config> Pallet<T> {
    // پیاده‌سازی تابع on_finalize
    #[pallet::call]
    pub fn on_finalize(n: T::BlockNumber) -> Weight {
        // ذخیره‌سازی یا ثبت وضعیت در پایان بلاک
        let final_state = <FinalState<T>>::get();
        log::info!("on_finalize: وضعیت نهایی در بلاک {:?}: {:?}", n, final_state);

        10_000 // وزن عملیات
    }
}

در این مثال، ما وضعیت نهایی را که در طول بلاک تغییر کرده است، در on_finalize ثبت کرده‌ایم.

جمع‌بندی
  • توابع on_initialize و on_finalize ابزارهای مفیدی برای مدیریت عملیات‌های زمان‌بندی‌شده و نظارت بر وضعیت پالت در Substrate هستند.
  • on_initialize می‌تواند برای انجام کارهایی که قبل از پردازش تراکنش‌ها باید انجام شوند، مانند به‌روزرسانی وضعیت یا تنظیم متغیرها استفاده شود.
  • on_finalize معمولاً برای انجام وظایف پایانی مانند ذخیره‌سازی اطلاعات یا نظارت بر وضعیت در پایان بلاک استفاده می‌شود.
  • با استفاده از این توابع، می‌توانید کنترل کاملی بر نحوه اجرای کد در هر بلاک داشته باشید و از آنها برای بهینه‌سازی و افزایش کارایی پالت‌های خود استفاده کنید.

[/cdb_course_lesson][cdb_course_lesson title=”فصل 8. ادغام Palletهای مختلف و تعامل بین آنها”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”نحوه ارتباط بین چند Pallet در یک Runtime” subtitle=”توضیحات کامل”]در Substrate، می‌توان از چندین Pallet برای پیاده‌سازی عملکردهای مختلف در یک Runtime استفاده کرد. این Pallet‌ها می‌توانند با هم تعامل داشته باشند تا به توسعه‌دهندگان این امکان را بدهند که عملکردهای مختلف را در کنار یکدیگر ایجاد کنند. برای برقراری ارتباط بین Pallet‌ها در یک Runtime، از مکانیزم‌های مختلفی استفاده می‌شود. در این بخش، نحوه تعامل و ارتباط بین چندین Pallet در یک Runtime را بررسی خواهیم کرد.

مفاهیم اساسی ارتباط بین Pallet‌ها

در Substrate، هر Pallet می‌تواند به صورت مستقل یا با استفاده از پالت‌های دیگر در سیستم تعامل کند. برای این کار، باید از ویژگی‌هایی مانند هایپرلینک‌ها (linking)، توابع مشترک (common functions)، حالت‌های ذخیره‌سازی (storage states) و رویدادها (events) استفاده کرد.

ارتباط بین Pallet‌ها با استفاده از متغیرهای ذخیره‌سازی مشترک

برای اینکه یک Pallet بتواند با یک Pallet دیگر ارتباط برقرار کند، یکی از رایج‌ترین روش‌ها استفاده از متغیرهای ذخیره‌سازی مشترک است. این روش به این صورت است که یک Pallet می‌تواند متغیرهای ذخیره‌سازی یا وضعیت خود را در Pallet دیگری ذخیره کند یا آن را بخواند.

مثال: ارتباط دو Pallet برای ذخیره یک مقدار و تغییر آن

فرض کنید دو Pallet داریم: یکی برای ذخیره اطلاعات (Pallet1) و دیگری برای انجام یک عمل روی آن اطلاعات (Pallet2). در اینجا، از یک متغیر ذخیره‌سازی در Pallet1 استفاده خواهیم کرد که توسط Pallet2 به‌روزرسانی می‌شود.

1. تعریف Pallet1

Pallet1 مسئول ذخیره‌سازی یک مقدار است. این مقدار می‌تواند توسط Pallet2 خوانده و تغییر یابد.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // متغیر ذخیره‌سازی در Pallet1
    #[pallet::storage]
    #[pallet::getter(fn stored_value)]
    pub(super) type StoredValue<T> = StorageValue<_, u32, ValueQuery>;

    // تابعی برای تنظیم مقدار در Pallet1
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // به‌روزرسانی متغیر ذخیره‌سازی
            <StoredValue<T>>::put(value);

            Ok(())
        }
    }
}

در این مثال، Pallet1 یک متغیر ذخیره‌سازی به نام StoredValue دارد که مقدار آن توسط تابع set_value به‌روزرسانی می‌شود.

2. تعریف Pallet2

Pallet2 می‌تواند از متغیر ذخیره‌سازی StoredValue در Pallet1 برای خواندن و تغییر مقدار استفاده کند.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::{StoredValue};  // استفاده از Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // تابعی برای خواندن و تغییر مقدار در Pallet2
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn update_value(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // خواندن مقدار از Pallet1
            let current_value = StoredValue::<T>::get();

            // تغییر مقدار
            let new_value = current_value.saturating_add(increment);

            // به‌روزرسانی مقدار در Pallet1
            pallet_1::Pallet::<T>::set_value(origin, new_value)?;

            Ok(())
        }
    }
}

در این مثال:

  • Pallet2 از متغیر ذخیره‌سازی StoredValue در Pallet1 استفاده می‌کند.
  • تابع update_value مقدار ذخیره‌شده را می‌خواند و سپس آن را با مقداری که از ورودی دریافت کرده است، به‌روزرسانی می‌کند.

ارتباط بین Pallet‌ها با استفاده از توابع عمومی

گاهی ممکن است شما بخواهید که یک Pallet قابلیت‌های خاصی را برای دیگر Pallet‌ها فراهم کند. برای این کار می‌توانید از توابع عمومی استفاده کنید که در یک Pallet تعریف شده و توسط دیگر Pallet‌ها فراخوانی شوند.

1. تعریف تابع عمومی در Pallet1

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        // تابع عمومی برای افزایش مقدار
        pub fn increment_value(amount: u32) -> DispatchResult {
            let current_value = StoredValue::<T>::get();
            let new_value = current_value.saturating_add(amount);
            StoredValue::<T>::put(new_value);
            Ok(())
        }
    }
}

2. فراخوانی تابع عمومی در Pallet2

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::Pallet as Pallet1;  // استفاده از Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn increase_value(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // فراخوانی تابع عمومی از Pallet1
            Pallet1::<T>::increment_value(increment)?;

            Ok(())
        }
    }
}

در این مثال، Pallet2 از تابع عمومی increment_value در Pallet1 استفاده کرده تا مقدار موجود را افزایش دهد.

استفاده از Events برای ارتباط بین Pallet‌ها

گاهی اوقات لازم است که یک Pallet رویدادهایی را برای اطلاع‌رسانی به سایر Pallet‌ها یا کاربران منتشر کند. برای این کار می‌توانید از Events در Substrate استفاده کنید.

1. انتشار Event در Pallet1

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // تعریف Event
    #[pallet::event]
    #[pallet::metadata(T::AccountId)]
    pub enum Event<T: Config> {
        ValueUpdated(u32),
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn update_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // انتشار رویداد
            Self::deposit_event(Event::ValueUpdated(value));

            Ok(())
        }
    }
}

2. گوش دادن به Event در Pallet2

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::{Event as Pallet1Event};  // استفاده از Event در Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn handle_event(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // گوش دادن به Event از Pallet1
            match Pallet1Event::<T>::ValueUpdated(value) {
                Pallet1Event::ValueUpdated(updated_value) => {
                    // واکنش به رویداد
                    log::info!("پالت 1: مقدار به روز رسانی شد: {:?}", updated_value);
                }
            }

            Ok(())
        }
    }
}

جمع‌بندی

  • ارتباط بین Pallet‌ها در Substrate می‌تواند از طریق متغیرهای ذخیره‌سازی مشترک، توابع عمومی، یا استفاده از Events انجام شود.
  • متغیرهای ذخیره‌سازی مشترک به شما این امکان را می‌دهند که داده‌ها را بین Pallet‌ها به اشتراک بگذارید و وضعیت‌ها را به‌روزرسانی کنید.
  • توابع عمومی می

‌توانند برای دسترسی به عملکردهای یک Pallet از سوی Pallet‌های دیگر استفاده شوند.

  • Events برای اطلاع‌رسانی و واکنش به تغییرات یا اتفاقات مختلف در یک Pallet مورد استفاده قرار می‌گیرند.

این روش‌ها به شما این امکان را می‌دهند که عملکردهای پیچیده‌تری را در محیط‌های توزیع‌شده ایجاد کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از Dependency Injection برای ترکیب قابلیت‌های Palletها” subtitle=”توضیحات کامل”]در Substrate، قابلیت Dependency Injection (DI) به طور مستقیم مانند بسیاری از فریمورک‌های دیگر (مانند Spring در جاوا) وجود ندارد. اما می‌توان از روش‌های مشابهی برای تعامل و ترکیب قابلیت‌های مختلف بین Pallet‌ها استفاده کرد. اینکار معمولاً از طریق استفاده از پالت‌های مشترک یا توابع عمومی و نوع‌های وابسته در تنظیمات هر Pallet انجام می‌شود.

در این بخش، نحوه ترکیب قابلیت‌های مختلف Palletها در یک Runtime با استفاده از مفاهیمی مشابه Dependency Injection را بررسی خواهیم کرد.

مفاهیم اصلی برای ترکیب قابلیت‌ها در Substrate

در Substrate، شما می‌توانید از روش‌هایی همچون پالت‌های وابسته (dependent pallets) و توابع عمومی برای ترکیب قابلیت‌های مختلف استفاده کنید. در واقع، این روش‌ها مانند مفهوم Dependency Injection عمل می‌کنند که با استفاده از آن، قابلیت‌ها و عملکردهای مختلف از پالت‌های دیگر در پالت فعلی در دسترس قرار می‌گیرند.

1. استفاده از Pallet‌های وابسته (Dependent Pallets)

یکی از روش‌های ترکیب قابلیت‌ها در Substrate، استفاده از پالت‌های وابسته است. به این صورت که یک Pallet می‌تواند از امکانات پالت‌های دیگر استفاده کند.

مثال: استفاده از Pallet‌های وابسته برای ترکیب قابلیت‌ها

فرض کنید دو پالت داریم: Pallet1 که وظیفه ذخیره‌سازی اطلاعات را دارد و Pallet2 که می‌خواهد از اطلاعات ذخیره‌شده در Pallet1 استفاده کند.

1.1. تعریف Pallet1 (ذخیره‌سازی اطلاعات)

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // متغیر ذخیره‌سازی در Pallet1
    #[pallet::storage]
    #[pallet::getter(fn stored_value)]
    pub(super) type StoredValue<T> = StorageValue<_, u32, ValueQuery>;

    // تابعی برای تنظیم مقدار در Pallet1
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // به‌روزرسانی متغیر ذخیره‌سازی
            <StoredValue<T>>::put(value);

            Ok(())
        }
    }
}

در این مثال، Pallet1 یک متغیر ذخیره‌سازی به نام StoredValue دارد که مقدار آن می‌تواند توسط تابع set_value به‌روزرسانی شود.

1.2. تعریف Pallet2 (استفاده از داده‌های Pallet1)

در اینجا، Pallet2 می‌خواهد مقدار ذخیره‌شده در Pallet1 را خوانده و بر اساس آن عملیاتی انجام دهد.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::{StoredValue};  // استفاده از Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // تابعی برای خواندن و تغییر مقدار از Pallet1
    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn update_value(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // خواندن مقدار از Pallet1
            let current_value = StoredValue::<T>::get();

            // تغییر مقدار
            let new_value = current_value.saturating_add(increment);

            // به‌روزرسانی مقدار در Pallet1
            pallet_1::Pallet::<T>::set_value(origin, new_value)?;

            Ok(())
        }
    }
}

در این مثال:

  • Pallet2 از متغیر ذخیره‌سازی StoredValue در Pallet1 استفاده می‌کند.
  • تابع update_value مقدار ذخیره‌شده را می‌خواند و سپس آن را با مقداری که از ورودی دریافت کرده است، به‌روزرسانی می‌کند.

استفاده از Pallet‌های وابسته

در این سناریو، Pallet2 به طور مستقیم از قابلیت‌های Pallet1 استفاده می‌کند. با استفاده از توابع عمومی یا متغیرهای ذخیره‌سازی که در Pallet1 تعریف شده‌اند، Pallet2 می‌تواند نیازهای خود را برآورده کند. این نوع تعامل مشابه به Dependency Injection است که در آن Pallet2 به طور غیرمستقیم از قابلیت‌های Pallet1 بهره می‌برد.

2. استفاده از توابع عمومی (Public Functions) برای ارتباط بین Palletها

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

مثال: تعریف یک تابع عمومی برای به‌روزرسانی مقدار در Pallet1 و استفاده از آن در Pallet2

در این مثال، یک تابع عمومی در Pallet1 ایجاد می‌کنیم که از هر Pallet دیگر قابل دسترسی است.

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // تابع عمومی برای افزایش مقدار
    pub fn increment_value<T: Config>(amount: u32) -> DispatchResult {
        let current_value = StoredValue::<T>::get();
        let new_value = current_value.saturating_add(amount);
        StoredValue::<T>::put(new_value);
        Ok(())
    }

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        // تابع عمومی که به‌روزرسانی مقدار را انجام می‌دهد
        pub fn update_value(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // فراخوانی تابع عمومی از Pallet1
            increment_value::<T>(increment)?;

            Ok(())
        }
    }
}

استفاده از تابع عمومی در Pallet2

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::increment_value;  // استفاده از تابع عمومی از Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn handle_event(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;

            // فراخوانی تابع عمومی از Pallet1 برای به‌روزرسانی مقدار
            increment_value::<T>(increment)?;

            Ok(())
        }
    }
}

در این مثال، Pallet2 از تابع عمومی increment_value در Pallet1 استفاده می‌کند تا مقدار ذخیره‌شده را تغییر دهد. این روش مشابه به Dependency Injection است که در آن Pallet2 به طور غیرمستقیم از عملکردهای Pallet1 استفاده می‌کند.

3. استفاده از Trait برای ترکیب قابلیت‌ها

در Substrate، می‌توانید از Trait‌ها برای ترکیب قابلیت‌های مختلف بین Pallet‌ها استفاده کنید. با تعریف یک Trait در یک Pallet و سپس پیاده‌سازی آن Trait در سایر Pallet‌ها، می‌توانید قابلیت‌ها و رفتارهای مشترک را میان Pallet‌ها به اشتراک بگذارید.

مثال: استفاده از Trait برای اشتراک‌گذاری قابلیت‌ها بین Pallet‌ها

#[pallet::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    pub trait UpdateValue {
        fn update_value(amount: u32) -> DispatchResult;
    }

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    // پیاده‌سازی Trait در Pallet1
    impl<T: Config> UpdateValue for Pallet<T> {
        fn update_value(amount: u32) -> DispatchResult {
            let current_value = StoredValue::<T>::get();
            let new_value = current_value.saturating_add(amount);
            StoredValue::<T>::put(new_value);
            Ok(())
        }
    }
}

در این سناریو، Pallet1 یک Trait به نام UpdateValue تعریف می‌کند که یک تابع update_value دارد. این Trait می‌تواند توسط سایر Pallet‌ها پیاده‌سازی شود.

جمع‌بندی

  • Dependency Injection به طور مستقیم در Substrate مانند فریمورک‌های دیگر وجود ندارد، اما با استفاده از مفاهیم مشابه مانند Pallet‌های وابسته، توابع عمومی، و Trait‌ها می‌توان قابلیت‌های مختلف را بین Pallet‌ها ترکیب کرد.
  • استفاده از Pallet‌های وابسته به شما این امکان را می‌دهد که یک Pallet بتواند از داده‌ها یا عملکردهای Pallet دیگری استفاده کند.
  • توابع عمومی و Trait‌ها نیز می‌توانند برای به اشتراک‌گذاری قابلیت‌ها و ترکیب عملکردهای مختلف میان Pallet‌ها استفاده شوند.

این روش‌ها مشابه به Dependency Injection در فریمورک‌های دیگر هستند و به شما کمک می‌کنند تا قابلیت‌های مختلف را به راحتی در پروژه‌های Substrate ترکیب کنید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی سیستم‌های Cross-Pallet Messaging در Substrate” subtitle=”توضیحات کامل”]در فریمورک Substrate، تعامل میان Palletها و ارسال پیام‌ها بین آن‌ها، بخش مهمی از معماری Runtime است. با استفاده از Cross-Pallet Messaging، می‌توان عملکردهای مختلف را از یک Pallet به دیگر Palletها ارسال کرده و داده‌ها و اطلاعات را میان آن‌ها منتقل نمود. این ویژگی به توسعه‌دهندگان این امکان را می‌دهد که چندین Pallet را به صورت هماهنگ و یکپارچه پیاده‌سازی کنند و از قابلیت‌های یکدیگر استفاده کنند.

1. مفهوم Cross-Pallet Messaging

Cross-Pallet Messaging به معنای ارتباط و ارسال پیام بین Palletها در یک Runtime است. در Substrate، این ارتباط معمولاً از طریق توابع عمومی، Storage، و Event ها انجام می‌شود. به عبارت دیگر، وقتی یک Pallet می‌خواهد به اطلاعات یا عملکردهای یک Pallet دیگر دسترسی پیدا کند، اینکار را از طریق ارسال پیام‌ها یا فراخوانی توابع عمومی آن Pallet انجام می‌دهد.

2. استفاده از توابع عمومی (Public Functions)

یکی از رایج‌ترین روش‌ها برای انجام Cross-Pallet Messaging استفاده از توابع عمومی است که از یک Pallet به دیگر Palletها ارسال می‌شود. این توابع به طور معمول در هر Pallet برای انجام عملیات خاصی مانند تغییر وضعیت، ارسال اطلاعات و غیره طراحی می‌شوند.

مثال: ارسال پیام از یک Pallet به Pallet دیگر از طریق توابع عمومی

در این مثال، Pallet1 دارای تابع عمومی است که مقدار ذخیره‌شده را تغییر می‌دهد و Pallet2 از این تابع برای به‌روزرسانی داده‌ها استفاده می‌کند.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::storage]
    #[pallet::getter(fn stored_value)]
    pub(super) type StoredValue<T> = StorageValue<_, u32, ValueQuery>;

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;
            StoredValue::<T>::put(value);
            Ok(())
        }
    }
}

در این مثال، Pallet1 یک متغیر ذخیره‌سازی به نام StoredValue دارد که مقدار آن می‌تواند توسط تابع set_value به‌روزرسانی شود.

در Pallet2، از این تابع برای ارسال پیام و به‌روزرسانی مقدار استفاده می‌شود.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{pallet_prelude::*};
    use pallet_1::{StoredValue};  // استفاده از تابع set_value از Pallet1

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::config]
    pub trait Config: frame_system::Config {}

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call]
        pub fn update_value(origin: OriginFor<T>, increment: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;
            let current_value = StoredValue::<T>::get();
            let new_value = current_value.saturating_add(increment);
            pallet_1::Pallet::<T>::set_value(origin, new_value)?;
            Ok(())
        }
    }
}

در این مثال، Pallet2 از تابع set_value در Pallet1 برای به‌روزرسانی مقدار ذخیره‌شده استفاده می‌کند.

3. استفاده از Storage مشترک

روش دیگر برای انجام Cross-Pallet Messaging، استفاده از Storage مشترک است. در این روش، یک Pallet می‌تواند داده‌ها را در Storage ذخیره کند و Pallet دیگر به این داده‌ها دسترسی پیدا کرده و عملیات مورد نیاز را انجام دهد. این روش بسیار مفید است وقتی که دو Pallet نیاز به اشتراک‌گذاری داده‌ها دارند.

مثال: استفاده از Storage برای ارسال داده‌ها بین Palletها

در این سناریو، هر دو Pallet می‌توانند به یک Storage مشترک دسترسی داشته باشند.

#[pallet::storage]
#[pallet::getter(fn shared_data)]
pub(super) type SharedData<T> = StorageValue<_, u32, ValueQuery>;

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::call]
    pub fn set_shared_data(origin: OriginFor<T>, value: u32) -> DispatchResult {
        let _who = ensure_signed(origin)?;
        SharedData::<T>::put(value);
        Ok(())
    }
}

حال در Pallet2 می‌توانیم از این داده‌ها استفاده کنیم:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::call]
    pub fn read_shared_data(origin: OriginFor<T>) -> DispatchResult {
        let _who = ensure_signed(origin)?;
        let shared_value = SharedData::<T>::get();
        // انجام عملیات با داده مشترک
        Ok(())
    }
}

در این مثال، Pallet2 می‌تواند داده‌های ذخیره‌شده در SharedData که توسط Pallet1 تنظیم شده است، بخواند و از آن استفاده کند.

4. استفاده از Events برای ارتباط بین Palletها

یک روش دیگر برای ارسال پیام‌ها بین Palletها استفاده از Events است. وقتی یک Pallet نیاز دارد که دیگر Palletها را از یک تغییر وضعیت مطلع کند، می‌تواند Event مناسبی را منتشر کند و Palletهای دیگر می‌توانند به این تغییرات واکنش نشان دهند.

مثال: ارسال Event از یک Pallet به دیگری

در این مثال، Pallet1 یک Event ارسال می‌کند که نشان‌دهنده تغییر در مقدار ذخیره‌شده است.

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::call]
    pub fn set_value(origin: OriginFor<T>, value: u32) -> DispatchResult {
        let _who = ensure_signed(origin)?;
        StoredValue::<T>::put(value);

        // ارسال Event برای اطلاع‌رسانی به دیگر Palletها
        Self::deposit_event(Event::ValueUpdated(value));
        Ok(())
    }
}

#[pallet::event]
pub enum Event<T: Config> {
    ValueUpdated(u32),
}

در Pallet2، می‌توانید به این Event واکنش نشان دهید:

#[pallet::call]
impl<T: Config> Pallet<T> {
    #[pallet::call]
    pub fn handle_event(origin: OriginFor<T>) -> DispatchResult {
        let _who = ensure_signed(origin)?;

        // واکنش به Event ارسال‌شده از Pallet1
        let event = Event::ValueUpdated(42);
        Self::deposit_event(event);

        Ok(())
    }
}

5. استفاده از Extrinsics برای ارسال پیام

در برخی مواقع، ممکن است بخواهید که یک Extrinsic برای ارسال پیام از یک Pallet به Pallet دیگر استفاده کنید. این روش به شما این امکان را می‌دهد که پیام‌ها را با استفاده از تراکنش‌ها (Extrinsics) ارسال کنید.

مثال: ارسال Extrinsic از یک Pallet به Pallet دیگر

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn send_message(origin: OriginFor<T>, message: u32) -> DispatchResult {
        let _who = ensure_signed(origin)?;

        // ارسال Extrinsic به Pallet دیگر
        pallet_2::Pallet::<T>::receive_message(origin, message)?;

        Ok(())
    }
}

در Pallet2، شما می‌توانید از این Extrinsic برای دریافت پیام‌ها استفاده کنید.

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn receive_message(origin: OriginFor<T>, message: u32) -> DispatchResult {
        let _who = ensure_signed(origin)?;

        // انجام عملیات با پیام دریافت‌شده
        Ok(())
    }
}

جمع‌بندی

  • Cross-Pallet Messaging در Substrate یکی از مفاهیم کلیدی برای تعامل بین Palletها است.
  • برای ارسال پیام بین Palletها می‌توان از توابع عمومی، Storage مشترک، Eventها و Extrinsics استفاده کرد.
  • این روش‌ها امکان ارسال داده‌ها و اطلاع‌رسانی میان Palletها را فراهم می‌کنند.
  • هر کدام از این روش‌ها می‌توانند بسته به نیازهای مختلف پروژه برای برقراری ارتباط و ارسال پیام‌ها به کار گرفته شوند.

این سیستم‌ها باعث می‌شوند که Substrate توانایی تعامل میان Palletها را به صورت مؤثر و مقیاس‌پذیر فراهم کند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 9. تست و دیباگ کردن Palletهای Substrate”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”راه‌اندازی محیط تست و نوشتن تست‌های واحد برای Pallet” subtitle=”توضیحات کامل”]در این بخش به آموزش راه‌اندازی محیط تست و نوشتن تست‌های واحد برای Pallet در Substrate خواهیم پرداخت. این فرایند به شما کمک می‌کند تا بتوانید کیفیت کد خود را ارزیابی کرده و مطمئن شوید که تمامی توابع و عملکردهای Pallet شما به‌درستی کار می‌کنند. تست‌های واحد ابزاری بسیار مهم برای بررسی صحت عملکرد کد و اطمینان از برآورده شدن انتظارات سیستم هستند.


۱. راه‌اندازی محیط تست برای Pallet

برای راه‌اندازی محیط تست برای Pallet در Substrate، ابتدا باید مطمئن شویم که ابزارهای مورد نیاز نصب و پیکربندی شده‌اند. یکی از مهم‌ترین ابزارهای برای انجام تست‌ها، Substrate’s frame-support است که شامل ویژگی‌های ضروری برای تست‌های واحد است.

تنظیمات و پیکربندی:

برای شروع باید مطمئن شویم که محیط توسعه‌مان آماده است. ابتدا باید ابزارهای زیر را نصب کنید:

  1. Rust (نسخه‌ی پایدار)
  2. Substrate (با استفاده از Cargo)
  3. ابزار تست (Cargo test)
گام اول: نصب Substrate

برای نصب Substrate، ابتدا باید cargo و rustup را روی سیستم خود نصب کنید.

برای نصب rustup و cargo (که همراه با Rust نصب می‌شوند)، از دستور زیر استفاده کنید:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

پس از نصب، اطمینان حاصل کنید که نسخه‌های صحیح Rust را نصب کرده‌اید:

rustup update
rustup show

برای نصب Substrate، به مخزن رسمی آن در GitHub مراجعه کنید و سپس دستور زیر را برای کلون کردن پروژه استفاده کنید:

git clone https://github.com/paritytech/substrate.git
cd substrate
گام دوم: ایجاد یک پروژه جدید با Substrate

با استفاده از ابزار substrate که در مخزن اصلی قرار دارد، می‌توانیم پروژه جدیدی بسازیم:

cargo new pallet-example --lib
cd pallet-example
گام سوم: اضافه کردن dependencies در Cargo.toml

در این مرحله، باید پیکربندی‌های مربوط به تست را به فایل Cargo.toml اضافه کنید. این کار به شما امکان استفاده از ویژگی‌های تست در Substrate را می‌دهد. به این فایل بروید و بخش زیر را به آن اضافه کنید:

[dependencies]
frame-support = { version = "3.0", default-features = false }
frame-system = { version = "3.0", default-features = false }
sp-runtime = { version = "3.0", default-features = false }

[dev-dependencies]
substrate-test-utils = { version = "3.0", default-features = false }

این تنظیمات وابستگی‌های مورد نیاز را برای نوشتن و اجرای تست‌ها فراهم می‌کنند.


۲. نوشتن تست‌های واحد برای Pallet

پس از راه‌اندازی محیط، می‌توانیم تست‌های واحد را برای توابع مختلف در Pallet بنویسیم. تست‌ها به‌طور کلی در پوشه tests نوشته می‌شوند. در اینجا نحوه نوشتن و اجرای تست‌ها را توضیح می‌دهیم.

ایجاد پوشه و فایل تست:

ابتدا یک پوشه tests در ریشه پروژه ایجاد کنید و سپس فایل‌هایی مانند pallet_tests.rs برای نوشتن تست‌ها اضافه کنید:

mkdir tests
touch tests/pallet_tests.rs
نوشتن تست‌ها:

حالا داخل فایل pallet_tests.rs می‌توانیم کدهای تست را بنویسیم. در اینجا یک نمونه تست برای یک تابع ساده در Pallet آورده شده است:

use frame_support::{assert_ok, dispatch::DispatchResult};
use pallet_example::{Pallet, Call};
use sp_core::H256;
use frame_system::{self as system, pallet_prelude::*};
use frame_support::traits::{Currency, OnInitialize};

#[test]
fn test_example_function() {
    let mut ext = sp_io::TestExternalities::default();
    ext.execute_with(|| {
        let result = Pallet::<Test>::example_function(100);
        assert_ok!(result);
    });
}

در این کد:

  • از assert_ok! برای بررسی موفقیت‌آمیز بودن تابع استفاده می‌شود.
  • تست بر روی یک تابع ساده example_function انجام شده است که ورودی آن 100 است.
اجرای تست‌ها:

پس از نوشتن تست‌ها، می‌توانید آن‌ها را با استفاده از دستور cargo test اجرا کنید:

cargo test

اگر همه چیز به درستی تنظیم شده باشد، نتایج تست‌ها در کنسول ظاهر خواهد شد.


۳. استفاده از Mock در تست‌ها

برای تست صحیح عملکرد Pallet‌ها، باید از داده‌های Mock استفاده کنیم. این کار به‌ویژه زمانی مفید است که بخواهیم برای عملکردهای مختلف تست‌های جداگانه بنویسیم.

ایجاد Mock:

در Substrate، برای نوشتن تست‌های واحد و تست رفتارهای مختلف، از Mock استفاده می‌شود. یک مثال ساده از استفاده Mock در تست‌ها به‌صورت زیر است:

use frame_support::{parameter_types, traits::Currency};
use sp_runtime::traits::{BlakeTwo256, IdentityLookup};
use frame_system::{self as system, pallet_prelude::*};

parameter_types! {
    pub const BlockHashCount: u32 = 250;
}

pub struct Test;

impl system::Config for Test {
    type BaseCallFilter = ();
    type BlockNumber = u32;
    type Call = Call<Test>;
    type Event = ();
    type Hash = H256;
    type Hashing = BlakeTwo256;
    type AccountId = u64;
    type Lookup = IdentityLookup<Self::AccountId>;
    type BlockHashCount = BlockHashCount;
    type Header = Header;
    type WeightInfo = ();
    type Origin = system::Origin<Self>;
}

این Mock به شما کمک می‌کند تا محیطی شبیه‌سازی‌شده از اجرای Pallet را ایجاد کنید.


جمع‌بندی

در این بخش، مراحل راه‌اندازی محیط تست و نوشتن تست‌های واحد برای Pallet در Substrate را بررسی کردیم. راه‌اندازی صحیح محیط توسعه و نوشتن تست‌های واحد از جمله مراحل حیاتی در فرآیند توسعه Pallet است. با استفاده از این تست‌ها، می‌توانیم اطمینان حاصل کنیم که تمامی بخش‌های کد به‌درستی عمل می‌کنند. همچنین استفاده از Mock‌ها و اجرای تست‌ها از طریق cargo test باعث می‌شود که فرآیند تست به‌راحتی قابل انجام باشد.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از ابزار Substrate Test Runtime برای شبیه‌سازی شبکه” subtitle=”توضیحات کامل”]در این بخش، به نحوه استفاده از ابزار Substrate Test Runtime برای شبیه‌سازی شبکه در Substrate خواهیم پرداخت. این ابزار برای تست‌های پیچیده و ارزیابی عملکرد شبکه در شرایط مختلف بسیار مفید است. ابزار Test Runtime به شما این امکان را می‌دهد که بدون نیاز به شبکه واقعی، تمام عملکردهای زنجیره بلوک خود را به‌طور محلی تست و شبیه‌سازی کنید.


۱. نصب ابزار Substrate Test Runtime

قبل از شروع، باید مطمئن شویم که محیط Substrate و ابزار Test Runtime به درستی نصب شده‌اند. در اینجا گام‌های مورد نیاز برای نصب و راه‌اندازی ابزار آورده شده است.

گام اول: نصب Substrate

اگر هنوز Substrate را نصب نکرده‌اید، باید مراحل نصب را انجام دهید. در ابتدا دستور زیر را برای نصب Rust و ابزارهای وابسته به آن اجرا کنید:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

پس از نصب Rust، باید مطمئن شوید که Substrate را نیز نصب کرده‌اید. دستور زیر را برای کلون کردن مخزن Substrate از GitHub اجرا کنید:

git clone https://github.com/paritytech/substrate.git
cd substrate
گام دوم: نصب Test Runtime

پس از نصب Substrate، باید ابزار Test Runtime را نصب کنید. این ابزار به‌طور معمول همراه با Substrate نصب می‌شود و نیازی به نصب جداگانه ندارد. اما برای اطمینان از نصب صحیح آن، از دستور زیر استفاده کنید:

cargo install --force --git https://github.com/paritytech/substrate.git

۲. پیکربندی و راه‌اندازی Test Runtime

برای شبیه‌سازی یک شبکه و انجام تست‌های مختلف روی آن، ابتدا باید یک محیط تست با استفاده از Substrate Test Runtime ایجاد کنیم. این کار شامل راه‌اندازی نود‌ها، ایجاد زنجیره بلوک و اجرای تست‌های مختلف است.

گام اول: ایجاد یک تست جدید

برای شروع، می‌توانیم یک پروژه جدید Substrate ایجاد کنیم که شامل پیکربندی‌ها و اجزای Test Runtime باشد. ابتدا یک پوشه جدید ایجاد کنید:

cargo new substrate-test-example --lib
cd substrate-test-example

در اینجا، فایل‌های Cargo.toml و lib.rs به‌طور پیش‌فرض ایجاد می‌شوند.

گام دوم: پیکربندی Test Runtime

حالا می‌توانیم فایل lib.rs را برای تنظیمات Test Runtime و شبیه‌سازی شبکه تغییر دهیم. یک نمونه کد برای پیکربندی Test Runtime به‌صورت زیر است:

use frame_support::{parameter_types, traits::Currency};
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header};
use frame_system::{self as system, pallet_prelude::*};

parameter_types! {
    pub const BlockHashCount: u32 = 250;
}

pub struct Test;

impl system::Config for Test {
    type BaseCallFilter = ();
    type BlockNumber = u32;
    type Call = Call<Test>;
    type Event = ();
    type Hash = H256;
    type Hashing = BlakeTwo256;
    type AccountId = u64;
    type Lookup = IdentityLookup<Self::AccountId>;
    type BlockHashCount = BlockHashCount;
    type Header = Header;
    type WeightInfo = ();
    type Origin = system::Origin<Self>;
}

در این کد، پارامترهای مختلف مانند BlockNumber و AccountId پیکربندی شده‌اند تا شرایط شبکه را شبیه‌سازی کنند.

گام سوم: شبیه‌سازی شبکه با استفاده از Test Runtime

در این مرحله، می‌توانیم با استفاده از ابزار frame-support شبکه را شبیه‌سازی کنیم. برای انجام این کار، می‌توانیم از محیط TestExternalities استفاده کنیم که به شما این امکان را می‌دهد تا حالت‌های مختلف را در شبکه شبیه‌سازی کرده و نتیجه را ارزیابی کنید.

use sp_io::TestExternalities;
use frame_support::assert_ok;

#[test]
fn test_runtime_simulation() {
    let mut ext = TestExternalities::default();
    ext.execute_with(|| {
        // اجرای توابع مختلف در شبکه شبیه‌سازی‌شده
        assert_ok!(some_runtime_function());
    });
}

در این کد، TestExternalities برای شبیه‌سازی وضعیت شبکه و اجرای توابع مختلف استفاده می‌شود.


۳. استفاده از Substrate Test Runtime برای اجرای تست‌های پیچیده

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

شبیه‌سازی چندین نود:

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

برای شبیه‌سازی چندین نود در یک محیط تست، می‌توانید از کد زیر استفاده کنید:

use substrate_test_runtime::Test;
use frame_support::assert_ok;
use sp_runtime::traits::BlakeTwo256;
use frame_system::{self as system, pallet_prelude::*};

#[test]
fn test_multiple_nodes() {
    let mut ext = sp_io::TestExternalities::default();

    ext.execute_with(|| {
        // شبیه‌سازی تعامل بین نودها
        assert_ok!(execute_transaction_on_node_1());
        assert_ok!(execute_transaction_on_node_2());
    });
}

در اینجا، دو نود به نام‌های node_1 و node_2 شبیه‌سازی می‌شوند و تعاملات بین آن‌ها بررسی می‌شود.


جمع‌بندی

در این بخش، نحوه استفاده از ابزار Substrate Test Runtime برای شبیه‌سازی شبکه و اجرای تست‌های مختلف بررسی شد. ابزار Test Runtime امکان شبیه‌سازی شبکه در محیط‌های آزمایشی را فراهم می‌کند و به شما این اجازه را می‌دهد تا بدون نیاز به راه‌اندازی شبکه واقعی، عملکرد Pallet و توابع مختلف خود را تست کنید. با استفاده از ابزارهای مختلف مانند TestExternalities و شبیه‌سازی چندین نود، می‌توانیم به بررسی عملکرد شبکه در شرایط مختلف بپردازیم و مطمئن شویم که تمام اجزای سیستم به درستی کار می‌کنند.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بررسی لاگ‌ها و دیباگ کردن اجرای Pallet‌ها” subtitle=”توضیحات کامل”]در این بخش، به بررسی نحوه استفاده از لاگ‌ها و دیباگ کردن اجرای Pallet‌ها در Substrate خواهیم پرداخت. دیباگ کردن و لاگ‌گذاری (logging) از ابزارهای مهم برای شناسایی مشکلات و بهینه‌سازی عملکرد کد در محیط‌های توسعه و تولید است. Substrate به‌طور پیش‌فرض از سیستم لاگ‌گذاری مبتنی بر frame-support برای ثبت و نمایش لاگ‌ها استفاده می‌کند. این اطلاعات می‌تواند برای شناسایی مشکلات یا بررسی رفتار برنامه در هنگام اجرا بسیار مفید باشد.


۱. پیکربندی سیستم لاگ‌گذاری

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

گام اول: اضافه کردن ماژول frame_support::log

برای استفاده از قابلیت لاگ‌گذاری در Substrate، باید از ماژول frame_support::log استفاده کنید. این ماژول اجازه می‌دهد که پیام‌ها در هنگام اجرا به کنسول یا فایل لاگ ارسال شوند.

use frame_support::{log, pallet_prelude::*};

پس از وارد کردن این ماژول، می‌توانید از توابع لاگ‌گذاری در کد خود استفاده کنید.

گام دوم: استفاده از توابع لاگ‌گذاری

در Substrate، توابع مختلفی برای ایجاد لاگ‌ها وجود دارد. به‌طور مثال، می‌توانید از توابع log::info!, log::warn!, log::error! و غیره استفاده کنید. این توابع به ترتیب برای ثبت پیام‌های اطلاعاتی، هشدارها و خطاها استفاده می‌شوند.

مثال:

fn some_function() {
    log::info!("This is an info log message.");
    log::warn!("This is a warning log message.");
    log::error!("This is an error log message.");
}

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

گام سوم: پیکربندی سطح لاگ

برای تنظیم سطح لاگ‌گذاری در Substrate، باید فایل کانفیگ chain_spec.rs را ویرایش کنید و سطح لاگ را برای محیط توسعه خود تعیین کنید.

مثال:

use sp_core::logging::Level;

pub fn get_runtime_config() -> sc_service::Configuration {
    let mut config = sc_service::Configuration::default();
    config.log_level = Level::Info; // تنظیم سطح لاگ به Info
    config
}

در این کد، سطح لاگ‌گذاری به Info تغییر داده شده است تا پیام‌های اطلاعاتی و بالاتر در کنسول نمایش داده شوند.


۲. دیباگ کردن Pallet‌ها با استفاده از دستورات CLI

یکی از ابزارهای اصلی برای دیباگ کردن و بررسی خطاها در Substrate، استفاده از دستورات CLI است. این ابزارها به شما کمک می‌کنند تا فرآیند‌های مختلف شبکه خود را زیر نظر بگیرید و مشکلات موجود را شناسایی کنید.

گام اول: استفاده از Substrate Node

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

./target/release/node-template --dev --tmp --log=debug

در این دستور، --dev برای استفاده از حالت توسعه و --log=debug برای نمایش تمام لاگ‌ها در سطح دیباگ است. این دستور باعث می‌شود که تمام لاگ‌ها با جزئیات بیشتر نمایش داده شوند، از جمله خطاها، هشدارها و پیام‌های اطلاعاتی.

گام دوم: تنظیم لاگ‌ها برای سطوح مختلف

شما می‌توانید سطح لاگ‌گذاری را در هنگام راه‌اندازی نود تعیین کنید. به‌طور پیش‌فرض، Substrate از سطح info استفاده می‌کند، اما می‌توانید از سطح‌های debug, warn, error, trace, و off نیز استفاده کنید.

./target/release/node-template --dev --tmp --log=error

در این مثال، فقط خطاها در لاگ‌ها نمایش داده می‌شوند.

گام سوم: بررسی لاگ‌های تولید شده

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

برای فیلتر کردن خطاها:

tail -f /path/to/log/file | grep "error"

۳. دیباگ کردن با استفاده از Rust و gdb

برای دیباگ کردن دقیق‌تر کد در سطح Rust، می‌توانید از ابزارهایی مانند gdb (GNU Debugger) استفاده کنید. این ابزار به شما این امکان را می‌دهد که فرآیند اجرای کد را مرحله به مرحله بررسی کنید و مشکلات را شناسایی کنید.

گام اول: نصب gdb

برای نصب gdb، دستور زیر را اجرا کنید:

sudo apt-get install gdb
گام دوم: کامپایل کد با قابلیت‌های دیباگ

برای اینکه از gdb برای دیباگ کردن استفاده کنید، باید کد Rust خود را با گزینه‌های دیباگ کامپایل کنید. برای این کار از دستور زیر استفاده کنید:

cargo build --debug
گام سوم: شروع دیباگ با gdb

پس از کامپایل کد با قابلیت‌های دیباگ، می‌توانید دیباگر gdb را برای شروع فرآیند دیباگ باز کنید:

gdb target/debug/your_project

در اینجا، your_project نام پروژه Rust شما است.


جمع‌بندی

در این بخش، نحوه استفاده از ابزارها و تکنیک‌های مختلف برای بررسی لاگ‌ها و دیباگ کردن اجرای Pallet‌ها در Substrate بررسی شد. ابزارهای لاگ‌گذاری و دیباگ در Substrate به شما این امکان را می‌دهند که مشکلات موجود را شناسایی کنید و عملکرد Pallet‌ها را به‌طور دقیق بررسی کنید. استفاده از دستورات CLI برای مشاهده لاگ‌ها، تنظیم سطوح مختلف لاگ‌گذاری و استفاده از ابزارهایی مانند gdb برای دیباگ کردن کد در سطح Rust، از جمله روش‌هایی هستند که به شما در شناسایی مشکلات و بهبود عملکرد کمک می‌کنند.[/cdb_course_lesson][cdb_course_lesson title=”فصل 10. بهینه‌سازی عملکرد و استقرار Pallet سفارشی”][/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”بهینه‌سازی مصرف حافظه و پردازش در Pallet” subtitle=”توضیحات کامل”]Pallet‌ها در Substrate، بخش‌های کلیدی برای ایجاد بلاک‌چین‌های خاص به شمار می‌آیند. یکی از چالش‌های اصلی در توسعه Pallet‌ها، بهینه‌سازی مصرف منابع، به‌ویژه حافظه و پردازش، به‌طور مؤثر است. در این بخش، تکنیک‌ها و روش‌هایی برای بهینه‌سازی مصرف حافظه و پردازش در Pallet‌ها به‌طور جامع و کاربردی مورد بررسی قرار می‌گیرد.


۱. بهینه‌سازی مصرف حافظه در Pallet

گام اول: استفاده بهینه از انواع داده‌ها

یکی از روش‌های اصلی بهینه‌سازی مصرف حافظه در Substrate، انتخاب صحیح انواع داده‌ها است. برای ذخیره‌سازی داده‌ها در Pallet، باید از انواع داده‌ای استفاده کرد که حافظه کمتری مصرف کنند و متناسب با نیازهای پروژه باشند.

استفاده از انواع داده‌ای کم‌حجم‌تر:

  • از u32 یا u64 به جای u128 استفاده کنید مگر در مواقع ضروری.
  • از ساختارهای داده‌ای مانند Vec<u8> به جای String برای ذخیره داده‌های باینری استفاده کنید.
  • در مواردی که داده‌ها بیشتر نیاز به ذخیره‌سازی دارند و ممکن است بسیار بزرگ شوند، از Option<T> یا Result<T, E> برای ذخیره مقادیر اختیاری یا خطاها استفاده کنید.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn store_data(origin: OriginFor<T>, data: Vec<u8>) -> DispatchResult {
        let who = ensure_signed(origin)?;
        // استفاده از Vec<u8> به جای String برای ذخیره داده‌ها
        <DataStorage<T>>::insert(who, data);
        Ok(())
    }
}

در این مثال، داده‌های باینری در قالب Vec<u8> ذخیره می‌شوند که مصرف حافظه بهینه‌تری نسبت به ذخیره داده‌ها به شکل متنی دارد.

گام دوم: استفاده از Storage Map به جای Storage DoubleMap

در Substrate، Storage Map‌ها نسبت به Storage DoubleMap‌ها مصرف حافظه کمتری دارند. اگر نیازی به دسترسی دو بعدی به داده‌ها ندارید، از Storage Map به‌جای Storage DoubleMap استفاده کنید.

مثال:

#[pallet::storage]
pub type DataStorage<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, Vec<u8>>;

در این کد، از StorageMap برای ذخیره داده‌های کاربران استفاده می‌شود که نسبت به استفاده از DoubleMap برای داده‌های دو بعدی بهینه‌تر است.

گام سوم: استفاده از PrefixedStorageMap

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

مثال:

#[pallet::storage]
pub type UserData<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, Vec<u8>>;

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn store_user_data(origin: OriginFor<T>, data: Vec<u8>) -> DispatchResult {
        let who = ensure_signed(origin)?;
        UserData::<T>::insert(who, data);  // ذخیره داده‌ها با استفاده از StorageMap
        Ok(())
    }
}

در این مثال، داده‌ها در یک StorageMap ذخیره می‌شوند که باعث کاهش نیاز به فضای ذخیره‌سازی اضافی می‌شود.


۲. بهینه‌سازی مصرف پردازش در Pallet

گام اول: کاهش پیچیدگی الگوریتم‌ها

یکی از مهم‌ترین روش‌های بهینه‌سازی مصرف پردازش در Pallet، ساده‌سازی و بهینه‌سازی الگوریتم‌ها است. باید از الگوریتم‌هایی استفاده کرد که پیچیدگی زمانی پایین‌تری دارند و تأثیر منفی کمتری بر پردازش شبکه می‌گذارند.

مثال: برای یافتن یک عنصر خاص در مجموعه‌ای از داده‌ها، از الگوریتم‌های جستجوی مؤثر مانند جستجوی دودویی به جای جستجوی خطی استفاده کنید.

fn binary_search(data: &[u32], target: u32) -> Option<usize> {
    let mut low = 0;
    let mut high = data.len() - 1;

    while low <= high {
        let mid = (low + high) / 2;
        if data[mid] == target {
            return Some(mid);
        } else if data[mid] < target {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    None
}

در این کد، جستجوی دودویی برای یافتن داده‌ها در آرایه استفاده می‌شود که زمان پردازش کمتری نسبت به جستجوی خطی دارد.

گام دوم: استفاده از DispatchResultWithPostInfo برای پردازش‌های غیرضروری

اگر در حال انجام پردازش‌های سنگین در یک تراکنش هستید که ممکن است غیرضروری باشد یا بر کارایی تأثیر بگذارد، می‌توانید از DispatchResultWithPostInfo استفاده کنید. این نوع نتیجه به شما این امکان را می‌دهد که برخی از عملیات‌ها را به بعد موکول کنید.

مثال:

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn perform_heavy_task(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
        let _who = ensure_signed(origin)?;
        
        // پردازش سنگین که می‌تواند به‌صورت ناهمزمان انجام شود
        Ok(().into()) // بازگشت به صورت DispatchResultWithPostInfo
    }
}

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

گام سوم: استفاده از کش (Cache)

در صورتی که در حال انجام عملیات‌هایی هستید که شامل خواندن داده‌ها از ذخیره‌سازی به‌صورت مکرر است، می‌توانید از کش (Cache) برای ذخیره‌سازی موقت داده‌های پراستفاده استفاده کنید تا مصرف پردازش کاهش یابد.

مثال:

#[pallet::storage]
pub type DataCache<T: Config> = StorageValue<_, Vec<u8>, ValueQuery>;

#[pallet::call]
impl<T: Config> Pallet<T> {
    pub fn fetch_data_from_cache(origin: OriginFor<T>) -> DispatchResult {
        let who = ensure_signed(origin)?;

        let cached_data = DataCache::<T>::get();
        // استفاده از داده‌های کش شده به جای بارگذاری مجدد از ذخیره‌سازی
        Ok(())
    }
}

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


جمع‌بندی

در این بخش، روش‌های مختلف بهینه‌سازی مصرف حافظه و پردازش در Pallet‌ها بررسی شد. با انتخاب انواع داده‌ای بهینه، استفاده از الگوریتم‌های کارآمد، و کاهش پیچیدگی در پردازش‌ها، می‌توان به‌طور مؤثر عملکرد Pallet‌ها را بهبود بخشید. همچنین، استفاده از کش و ذخیره‌سازی موقت داده‌ها می‌تواند به کاهش فشار روی سیستم کمک کند. پیاده‌سازی این تکنیک‌ها در کدهای Substrate می‌تواند منجر به کاهش هزینه‌های پردازش و بهبود کارایی کلی بلاک‌چین شود.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”استفاده از Benchmarking برای ارزیابی عملکرد Pallet” subtitle=”توضیحات کامل”]Benchmarking یک ابزار قدرتمند برای ارزیابی و بهینه‌سازی عملکرد Palletها در Substrate است. این ابزار به شما این امکان را می‌دهد که زمان اجرای تراکنش‌ها و عملکرد‌های مختلف بلاک‌چین را اندازه‌گیری کرده و بر اساس نتایج، به بهینه‌سازی‌های لازم بپردازید. در این بخش، استفاده از ابزار Benchmarking برای ارزیابی عملکرد Palletها به‌طور کامل، از تنظیمات تا کدنویسی و نحوه‌ی پیاده‌سازی آن، مورد بررسی قرار می‌گیرد.


۱. تنظیمات اولیه برای Benchmarking

برای استفاده از Benchmarking در Substrate، شما باید پیکربندی‌های خاصی را در فایل‌های پروژه خود انجام دهید. این تنظیمات شامل افزوده‌شدن وابستگی‌های مورد نیاز و پیکربندی مناسب برای benchmark شدن هر متد در Pallet است.

گام اول: اضافه کردن وابستگی‌های مورد نیاز در فایل Cargo.toml

در ابتدا باید وابستگی‌های Benchmarking را در فایل Cargo.toml پروژه خود اضافه کنید. این وابستگی‌ها به شما اجازه می‌دهند که عملیات benchmarking را روی هر متدی در Pallet انجام دهید.

[dependencies]
frame-benchmarking = { version = "3.0.0", default-features = false }
frame-system = { version = "3.0.0" }

در این کد، وابستگی‌های لازم برای استفاده از frame-benchmarking و frame-system وارد پروژه می‌شوند. این وابستگی‌ها به شما این امکان را می‌دهند که عملکرد تراکنش‌ها را اندازه‌گیری کنید.

گام دوم: پیکربندی ویژگی‌های Benchmarking در فایل runtime

در فایل runtime خود، باید ویژگی‌های Benchmarking را فعال کنید. برای این منظور، کافی است یک پیکربندی برای پشتیبانی از Benchmarking در runtime خود ایجاد کنید.

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;
use frame_support::{
    pallet_prelude::*,
    weights::{Weight, DispatchClass},
};
use frame_system::{self as system, pallet_prelude::*};

#[frame_support::pallet]
pub mod pallet {
    use super::*;

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        pub fn some_function_to_benchmark(origin: OriginFor<T>) -> DispatchResult {
            let _who = ensure_signed(origin)?;
            // کد متد اصلی
            Ok(())
        }
    }
}

در این فایل، متد اصلی some_function_to_benchmark برای انجام عملیات benchmark پیاده‌سازی می‌شود.


۲. پیاده‌سازی Benchmarking برای ارزیابی عملکرد

برای اندازه‌گیری زمان اجرا و عملکرد متدهای مختلف در Pallet، باید برای هر متد یک benchmark بنویسید. این benchmarkها به‌طور خودکار زمان مصرفی و منابع مورد نیاز را اندازه‌گیری می‌کنند.

گام اول: استفاده از ویژگی‌های frame-benchmarking

در این گام، برای اضافه کردن benchmark به متدهای خود، باید از ویژگی‌های frame-benchmarking استفاده کنید. این ویژگی‌ها به شما اجازه می‌دهند که زمان و مصرف منابع را برای هر تراکنش بررسی کنید.

برای شروع، باید در فایل pallet خود از ماکرو #[benchmarks] استفاده کنید تا benchmarkها را روی متدهای مختلف اعمال کنید.

#[cfg(test)]
mod benchmarking {
    use super::*;
    use frame_benchmarking::{benchmarking, Benchmarking, WithForEach};
    use frame_support::dispatch::DispatchResult;

    #[benchmark]
    fn benchmark_some_function() -> DispatchResult {
        // Benchmarking برای متد
        let caller = T::AccountId::default();
        let _result = Pallet::<T>::some_function_to_benchmark(caller);
        Ok(())
    }
}

در این کد، از ماکرو #[benchmark] برای اندازه‌گیری عملکرد متد some_function_to_benchmark استفاده شده است.

گام دوم: اجرای Benchmarking

برای اجرای Benchmarking باید از ابزار cargo استفاده کنید. در اینجا نحوه اجرای benchmarking برای ارزیابی عملکرد نشان داده شده است.

cargo bench --features runtime-benchmarks

این دستور باعث می‌شود که benchmarking اجرا شده و زمان اجرای هر متد به‌طور خودکار محاسبه شود.

گام سوم: تحلیل نتایج

پس از اجرای benchmarkها، باید نتایج را تحلیل کرده و مواردی که نیاز به بهینه‌سازی دارند را شناسایی کنید. نتایج benchmarking معمولاً زمان‌های اجرای متدها را در حالت‌های مختلف بررسی می‌کنند.

[INFO] Benchmarking Results:
    Time taken for some_function_to_benchmark: 500ms

در اینجا، زمان اجرای متد some_function_to_benchmark به‌طور دقیق اندازه‌گیری شده است.


۳. بهینه‌سازی بر اساس نتایج Benchmarking

پس از دریافت نتایج benchmarking، شما می‌توانید به بهینه‌سازی Pallet خود بپردازید تا مصرف منابع و زمان اجرای آن کاهش یابد. بهینه‌سازی‌هایی که می‌توانید در نظر بگیرید عبارتند از:

گام اول: استفاده از الگوریتم‌های کارآمدتر

اگر در متدی که benchmark کرده‌اید، الگوریتم‌ها زمان زیادی می‌برند، می‌توانید آن‌ها را با الگوریتم‌های بهینه‌تر جایگزین کنید.

مثال:

به جای استفاده از جستجوی خطی، از جستجوی دودویی استفاده کنید که کارایی بهتری دارد.

گام دوم: کاهش مصرف حافظه

در مواردی که benchmark نشان می‌دهد مصرف حافظه بالا است، می‌توانید از انواع داده‌ای بهینه‌تر استفاده کنید.

گام سوم: استفاده از توزیع کار (Offloading)

اگر یک متد زمان زیادی را می‌برد و از منابع زیادی استفاده می‌کند، می‌توانید آن را به صورت ناهمزمان (asynchronously) اجرا کنید.


جمع‌بندی

Benchmarking ابزاری ضروری برای ارزیابی عملکرد Palletها در Substrate است. با استفاده از آن می‌توانید عملکرد متدهای مختلف را اندازه‌گیری کرده و بر اساس نتایج آن‌ها را بهینه‌سازی کنید. از جمله کارهایی که باید برای استفاده از Benchmarking انجام دهید، پیکربندی فایل‌های پروژه، نوشتن benchmark برای متدها، و اجرای آن‌ها برای تحلیل نتایج است. با توجه به نتایج حاصل از benchmarking، می‌توانید به بهینه‌سازی الگوریتم‌ها، کاهش مصرف منابع، و افزایش سرعت اجرای تراکنش‌ها بپردازید.[/cdb_course_lesson][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”lecture” private_lesson=”true” title=”راه‌اندازی Pallet سفارشی در یک شبکه آزمایشی” subtitle=”توضیحات کامل”]راه‌اندازی یک Pallet سفارشی در یک شبکه آزمایشی (Test Network) یکی از مراحل کلیدی در توسعه بلاک‌چین با استفاده از Substrate است. این فرآیند شامل طراحی، پیاده‌سازی، و آزمایش عملکرد Pallet است که قابلیت‌های خاصی را به شبکه شما اضافه می‌کند. در این بخش، نحوه راه‌اندازی یک Pallet سفارشی در یک شبکه آزمایشی را به‌طور کامل و با جزئیات توضیح خواهیم داد.


۱. ساخت و تنظیم یک پروژه Substrate

برای شروع، ابتدا نیاز به ایجاد یک پروژه Substrate دارید. شما می‌توانید از الگوهای موجود برای ایجاد یک پروژه جدید استفاده کنید.

گام اول: نصب ابزارهای لازم

قبل از ایجاد یک پروژه Substrate، باید ابزارهای لازم مانند rustup, cargo و git را نصب کرده باشید. برای نصب آن‌ها، از دستورات زیر استفاده کنید:

# نصب rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# نصب xargo و cargo
cargo install cargo-binutils
گام دوم: ایجاد پروژه Substrate جدید

برای ایجاد یک پروژه جدید Substrate، می‌توانید از دستور substrate-node-template استفاده کنید که یک پروژه پایه را برای شما ایجاد می‌کند:

# دانلود و ایجاد پروژه
git clone https://github.com/substrate-developer-hub/substrate-node-template
cd substrate-node-template

# ساخت پروژه
cargo build --release

با این دستور، یک پروژه جدید با ساختار پایه‌ای که آماده افزودن Pallet سفارشی است، ایجاد می‌شود.


۲. ایجاد Pallet سفارشی

برای ایجاد یک Pallet سفارشی، شما باید یک فایل جدید در پوشه pallets/ پروژه خود اضافه کنید.

گام اول: ساخت پوشه و فایل جدید

ابتدا پوشه‌ای برای Pallet سفارشی خود ایجاد کنید و سپس فایلی برای کدهای Pallet بنویسید.

# ایجاد پوشه برای Pallet سفارشی
mkdir pallets/my_pallet
cd pallets/my_pallet

# ایجاد فایل Rust برای کد Pallet
touch lib.rs
گام دوم: نوشتن کد Pallet سفارشی

در این فایل، شما می‌توانید کدهای مربوط به Pallet سفارشی خود را بنویسید. در زیر نمونه‌ای از یک Pallet ساده برای ذخیره‌سازی داده‌ها آمده است:

#![cfg_attr(not(feature = "std"), no_std)]

pub use pallet::*;

#[frame_support::pallet]
pub mod pallet {
    use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
    use frame_system::{self as system, pallet_prelude::*};

    #[pallet::pallet]
    pub struct Pallet<T>(_);

    #[pallet::call]
    impl<T: Config> Pallet<T> {
        #[pallet::call_index(0)]
        #[pallet::weight(10_000)]
        pub fn set_data(origin: OriginFor<T>, value: u32) -> DispatchResult {
            let _who = ensure_signed(origin)?;
            // ذخیره داده در Pallet
            Ok(())
        }
    }
}

در این کد، یک متد ساده برای ذخیره داده‌ها (set_data) ایجاد شده است. این متد یک مقدار عددی را به‌عنوان ورودی می‌گیرد و آن را در Pallet ذخیره می‌کند.


۳. افزودن Pallet سفارشی به پروژه

برای این که Pallet سفارشی شما به پروژه اصلی افزوده شود، باید آن را به تنظیمات runtime خود اضافه کنید.

گام اول: ویرایش فایل runtime/src/lib.rs

در فایل runtime/src/lib.rs، شما باید Pallet خود را وارد کرده و آن را در پیکربندی runtime ثبت کنید.

pub use pallet_my_pallet;

#[frame_support::pallet]
pub struct Pallet<T>(_);

impl pallet_my_pallet::Config for Runtime {
    type Event = Event;
}

در اینجا، pallet_my_pallet به runtime اضافه می‌شود و پیکربندی آن نیز انجام می‌شود.


۴. ایجاد یک شبکه آزمایشی (Test Network)

برای آزمایش Pallet سفارشی خود، باید یک شبکه آزمایشی Substrate راه‌اندازی کنید. در این مرحله، یک شبکه محلی برای تست ایجاد می‌کنید.

گام اول: راه‌اندازی شبکه محلی

برای راه‌اندازی یک شبکه محلی Substrate، از دستور زیر استفاده کنید:

# اجرای نود محلی Substrate
cargo run --release -- --dev

این دستور یک شبکه محلی را با مشخصات پیش‌فرض راه‌اندازی می‌کند. می‌توانید از این شبکه برای آزمایش Pallet سفارشی خود استفاده کنید.

گام دوم: اتصال به شبکه و ارسال تراکنش‌ها

برای ارسال تراکنش‌ها به شبکه آزمایشی، می‌توانید از رابط کاربری Polkadot-JS استفاده کنید. ابتدا باید Polkadot-JS را در مرورگر خود باز کنید و به شبکه محلی متصل شوید.

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


۵. آزمایش و دیباگ کردن Pallet سفارشی

بعد از راه‌اندازی شبکه آزمایشی، باید عملکرد Pallet سفارشی خود را آزمایش کنید. شما می‌توانید از ابزارهایی مانند substrate-test برای انجام این کار استفاده کنید.

گام اول: ایجاد تست برای Pallet سفارشی

در فایل pallets/my_pallet/src/tests.rs، تست‌های خود را بنویسید.

#[cfg(test)]
mod tests {
    use super::*;
    use frame_support::{assert_ok, dispatch::DispatchResult};
    use frame_system::{self as system, pallet_prelude::*};

    #[test]
    fn test_set_data() {
        // فراخوانی متد set_data برای تست
        assert_ok!(Pallet::<Test>::set_data(Origin::signed(1), 42));
    }
}
گام دوم: اجرای تست‌ها

برای اجرای تست‌ها، از دستور زیر استفاده کنید:

cargo test

این دستور تست‌های تعریف‌شده را اجرا کرده و عملکرد Pallet شما را ارزیابی می‌کند.


جمع‌بندی

راه‌اندازی یک Pallet سفارشی در یک شبکه آزمایشی Substrate شامل مراحل مختلفی است که از ایجاد پروژه و نوشتن کد Pallet گرفته تا اتصال به شبکه آزمایشی و آزمایش عملکرد آن را در بر می‌گیرد. در این بخش، مراحل ایجاد یک Pallet سفارشی و راه‌اندازی آن در شبکه آزمایشی به‌طور کامل شرح داده شد. با استفاده از ابزارهای موجود و شبکه‌های آزمایشی می‌توانید عملکرد Pallet خود را بررسی و بهینه‌سازی کنید تا به نتیجه مطلوب برسید.[/cdb_course_lesson][/cdb_course_lessons]

[cdb_course_lessons title=”پاسخ به سوالات فنی کاربران”][cdb_course_lesson icon=”fas fa-arrow-alt-circle-down” badge=”free” title=”پشتیبانی دائمی و در لحظه” subtitle=”توضیحات کامل”]ما در این دوره تمام تلاش خود را کرده‌ایم تا محتوایی جامع و کاربردی ارائه دهیم که شما را برای ورود به دنیای حرفه‌ای آماده کند. اما اگر در طول دوره یا پس از آن با سوالات فنی، چالش‌ها یا حتی مشکلاتی در اجرای مطالب آموزشی مواجه شدید، نگران نباشید!

پرسش‌های شما، بخش مهمی از دوره است:
هر سوال یا مشکلی که مطرح کنید، با دقت بررسی شده و پاسخ کامل و کاربردی برای آن ارائه می‌شود. علاوه بر این، سوالات و پاسخ‌های شما به دوره اضافه خواهند شد تا برای سایر کاربران نیز مفید باشد.
پشتیبانی دائمی و در لحظه:
تیم ما همواره آماده پاسخگویی به سوالات شماست. هدف ما این است که شما با خیالی آسوده بتوانید مهارت‌های خود را به کار بگیرید و پروژه‌های واقعی را با اعتماد به نفس کامل انجام دهید.
آپدیت دائمی دوره:
این دوره به طور مداوم به‌روزرسانی می‌شود تا همگام با نیازهای جدید و سوالات کاربران تکمیل‌تر و بهتر گردد. هر نکته جدید یا مشکل رایج، در نسخه‌های بعدی دوره قرار خواهد گرفت.
حرف آخر

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

📩 اگر سوالی دارید یا به مشکلی برخوردید، همین حالا مطرح کنید!
ما در کوتاه‌ترین زمان ممکن پاسخ شما را ارائه خواهیم داد. 🙌[/cdb_course_lesson][/cdb_course_lessons]

نقد و بررسی ها

نقد و بررسی وجود ندارد.

فقط مشتریانی که وارد سیستم شده اند و این محصول را خریداری کرده اند می توانند نظر بدهند.

سبد خرید

سبد خرید شما خالی است.

ورود به سایت