آموزش ساخت بلاک چین (Blockchain) با پایتون – راهنمای کاربردی

۴۶۵۹ بازدید
آخرین به‌روزرسانی: ۱۷ تیر ۱۴۰۲
زمان مطالعه: ۱۳ دقیقه
دانلود PDF مقاله
آموزش ساخت بلاک چین (Blockchain) با پایتون – راهنمای کاربردیآموزش ساخت بلاک چین (Blockchain) با پایتون – راهنمای کاربردی

افراد علاقمند به موضوع داغ و جذاب «رمز ارزها» (Cryptocurrencies) مخاطبان اصلی این مطلب خواهند بود. همچنین، به کلیه علاقمندان به یادگیری چگونگی عملکرد «بلاک چین» (Blockchain | زنجیره بلوکی) و فناوری پایه نهفته در پس آن، مطالعه این مطلب توصیه می‌شود. نکته قابل توجه آن است که بلاک چین در فارسی «زنجیره بلوکی» ترجمه شده و بنابراین در ادامه این مطلب سعی بر آن است که از این معادل نیز در کنار واژه شناخته شده بلاک چین استفاده شود. لازم به ذکر است که درک بلاک چین آسان نیست و برای یادگیری دقیق و عمیق آن نیاز به تخصیص وقت قابل توجه و مطالعه راهنماهای متنی و ویدئویی متعدد و مشاهده مثال‌های گوناگون است. در ادامه سعی بر آن است که مفهوم بلاک چین (زنجیره بلوکی) از طریق ساخت آن با کدهایی به زبان برنامه‌نویسی پایتون آموزش داده شود. به مخاطبان توصیه می‌شود برای درک بهتر مطلب و داشتن یک بلاک چین (زنجیره بلوکی) در پایان این مطلب، مراحل انجام شده را گام به گام همراه با این نوشتار انجام دهند. با مطلب آموزش ساخت بلاک چین مجله فرادرس همراه باشید.

997696

پیش از آغاز

بلاک چین (زنجیره بلوکی) یک زنجیره پیوسته و تغییرناپذیر از رکوردهایی است که به آن‌ها «بلوک» (Block) گفته می‌شود. این بلوک‌ها می‌توانند در برگیرنده «تراکنش‌ها» (Transactions)، فایل‌ها یا هر نوع داده انتخابی دیگری باشند. اما مساله مهم آن است که این بلوک‌ها با استفاده از «هش‌ها» (hashes) به یکدیگر زنجیر شده‌اند. (مطالعه مطلب «تابع هش یا درهم سازی (Hash Function) چیست؟ -- به زبان ساده» برای آشنایی با مفهوم هش توصیه می‌شود.)

پرسشی که امکان دارد برای مخاطبان این مطلب مطرح شود آن است که برای مطالعه نوشتار پیش رو به چه پیش‌نیازهایی نیاز دارند؟ آشنایی مقدماتی با نوشتن و خواندن کدهای پایتون و داشتن درک مقدماتی از چگونگی عملکرد درخواست‌های HTTP مورد نیاز است، زیرا بلاک چین ساخته شده در این مطلب برمبنای HTTP است. کدهای ارائه شده در اینجا بر اساس پایتون ۳.۶ نوشته شده‌اند، بنابراین مخاطبان باید اقدام به نصب پایتون ۳.۶، و همچنین چارچوب Flask و کتابخانه Requests کنند. برای انجام این کار با بهره‌گیری از pip، می‌توان از دستور زیر استفاده کرد.

همچنین، نیاز به یک کلاینت HTTP مانند Postman یا cURL نیز هست. کد نهایی استفاده شده در این مطلب از اینجا (+) در دسترس است.

گام ۱: ساخت بلاک چین

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

ارائه بلاک چین

یک کلاس Blockchain ساخته می‌شود که «سازنده» (Creator) آن یک لیست اولیه خالی (برای ذخیره‌سازی بلاک چین)، و یک فایل دیگر نیز برای ذخیره‌سازی تراکنش‌ها ایجاد می‌کند. کد کلاس مذکور در ادامه آمده است.

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

یک بلوک چگونه است؟

در بحث ساخت بلاک چین، هر بلوک دارای یک «اندیس» (index)، «برچسب زمان» (timestamp) (به زمان یونیکس)، یک لیست از تراکنش‌ها، یک proof و هش بلوک قبلی است.

در ادامه مثالی از چگونگی یک بلوک مجرد آمده است.

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

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

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

متد ()new_transaction مسئول انجام این کار خواهد بود. کد این متد به شرح زیر است.

پس از آنکه ()new_transaction یک تراکنش را به لیست اضافه می‌کند، اندیس بلوکی را که تراکنش به آن افزوده شده باز می‌گرداند. این کار بعدا برای کاربر جهت وارد کردن تراکنش‌ها مفید خواهد بود.

ساخت بلوک جدید

هنگامی که Blockchain نمونه‌سازی شد مرحله بعدی در ساخت بلاک چین نیاز به خوراک دادن به آن با یک «بلوک پیدایش» (genesis block) - یک بلوک بدون هیچ‌گونه اجدادی - است. همچنین نیاز به اضافه کردن یک «proof» به بلوک genesis است که در نتیجه کاوش (mining) (یا اثبات کارکرد | Proof of Work) به وقوع می‌پیوندد.

در این رابطه بعدا بیش‌تر صحبت خواهد شد. علاوه بر ساخت بلوک genesis در سازنده، متدهایی برای ()new_block() ،new_transaction و ()hash نیاز است.

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

درک الگوریتم Proof of Work

الگوریتم Proof of Work (به اختصار PoW | اثبات کارکرد) چگونگی ساخت یا کاوش بلوک‌های جدید در بلاک چین (زنجیره بلوکی) است. هدف از PoW کشف عددی محسوب می‌شود که مساله را حل می‌کند. پیدا کردن این عدد - از جهت محاسبات کامپیوتری -  توسط هر شخصی که در شبکه قرار دارد باید دشوار و تایید پاسخ آن باید آسان باشد.

این ایده اصلی نهفته در پس الگوریتم Proof of Work است. در ادامه نگاهی به مثالی ساده در این رابطه انداخته می‌شود. هش یک عدد صحیح x توسط یک y چندین برابر می‌شود و عدد حاصل باید به صفر ختم شود. بنابراین، hash(x * y) = ac23dc...0. در مثال ساده پیش رو، x = 5 در نظر گرفته می‌شود. پیاده‌سازی این مثال در پایتون به صورت زیر است.

راهکار در اینجا y = 21 است، زیرا هش تولید شده توسط آن با ۰ پایان پیدا می‌کند.

در رمزارز «بیت‌کوین» (Bitcoin)، الگوریتم Proof of Work با عنوان «Hashcash» نامیده می‌شود و خیلی از مثال پایه‌ای مطرح شده در بالا متفاوت نیست. این الگوریتمی است که ماینرها (miners) برای حل آن به منظور ساخت یک بلوک جدید با یکدیگر رقابت می‌کنند. به طور کلی، دشواری با تعداد کاراکترهایی که برای یک رشته جست‌و‌جو می‌شوند تعیین می‌شود. بنابراین، ماینرها برای راهکارهای خود با دریافت سکه - در یک تراکنش - پاداش دریافت می‌کنند و از سوی دیگر شبکه به سادگی قادر به تایید راهکار آن‌ها است.

پیاده‌سازی الگوریتم پایه Proof of Work

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

قاعده مورد استفاده مطابق آنچه در بالا بیان شد است:

عدد P را پیدا کن که وقتی با بلاک پیشین هش می‌شود یک هش با چهار «0» مقدم تولید شود.

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

گام ۲: زنجیره بلوکی به عنوان یک رابط کاربردی برنامه‌نویسی

اکنون از «چارچوب پایتون فلسک» (Python Flask Framework) استفاده خواهد شد. فلسک یک میکرو-چارچوب است و نگاشت «نقاط پایانی» (endpoints) به توابع پایتون را آسان‌تر می‌سازد.

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

  • transactions/new/: برای ساخت یک تراکنش جدید برای یک بلاک
  • mine/: برای آنکه به سرور گفته شود بلوک جدید را «ماین» (mine) کند.
  • chain/: برای بازگرداندن بلاک چین کامل.

راه‌اندازی Flask

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

یک توضیح کوتاه از کاری که کد بالا انجام می‌دهد:

  • خط ۱۵: نمونه‌گیری از گره
  • خط ۱۸: ساخت یک نام تصادفی برای گره
  • خط ۲۱: نمونه‌گیری از کلاس Blockchain
  • خط ۲۶-۲۳: ساخت نقطه پایانی mine/ که یک درخواست GET است.
  • خط ۳۰-۲۸: ساخت نقطه پایانی transactions/new/ که یک درخواست POST است زیرا داده‌ها به آن ارسال خواهند شد.
  • خط ۳۸-۳۲: ساخت یک نقطه پایانی chain/ که کل بلاک چین را باز می‌گرداند.
  • خط ۴۱-۴۰: سرور را روی پورت ۵۰۰۰ اجرا می‌کند.

نقطه پایانی تراکنش

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

{
"sender": "my address",
"recipient": "someone else's address",
"amount": 5
}

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

نقطه پایانی ماینینگ

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

در این نقطه تنها کافی است سه کار اتفاق بیافتد:

  1. محاسبه Proof of Work
  2. پاداش دادن به ماینر با افزودن تراکنشی که ۱ سکه به کاربر می‌دهد.
  3. Forge کردن بلوک جدید با افزودن آن به زنجیره

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

گام ۳: تعامل با بلاک چین

می‌توان از cURL یا Postman برای تعامل کردن با API جدید در شبکه استفاده کرد.

راه‌اندازی سرور:

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

تعامل با بلاک چین
استفاده از Postman برای ایجاد دستور GET

با استفاده از یک درخواست POST به http://localhost:5000/transactions/new با بدنه دربرگیرنده ساختار تراکنش ارائه شده در این مطلب، یک تراکنش جدید ساخته می‌شود.

استفاده از Postman برای ایجاد درخواست POST

افرادی که از Postman استفاده نمی‌کنند می‌توانند درخواست مشابهی را با استفاده از cURL انجام دهند:

$ curl -X POST -H "Content-Type: application/json" -d '{
"sender": "d4ee26eee15148ee92c6cd394edd974e",
"recipient": "someone-other-address",
"amount": 5
}' "http://localhost:5000/transactions/new"

سرور ریست شد و دو بلوک را ماین کرد تا ۳ تا در کل بدهد. اکنون کل زنجیره بلوک با درخواست http://localhost:5000/chain بازرسی (inspect) می‌شود:

{
"chain": [
{
"index": 1,
"previous_hash": 1,
"proof": 100,
"timestamp": 1506280650.770839,
"transactions": []
},
{
"index": 2,
"previous_hash": "c099bc...bfb7",
"proof": 35293,
"timestamp": 1506280664.717925,
"transactions": [
{
"amount": 1,
"recipient": "8bbcb347e0634905b0cac7955bae152b",
"sender": "0"
}
]
},
{
"index": 3,
"previous_hash": "eff91a...10f2",
"proof": 35089,
"timestamp": 1506280666.1086972,
"transactions": [
{
"amount": 1,
"recipient": "8bbcb347e0634905b0cac7955bae152b",
"sender": "0"
}
]
}
],
"length": 3
}

گام ۴: اجماع

این گام بسیار جالب توجه محسوب می‌شود. اکنون یک بلاک چین پایه موجود است که تراکنش‌ها را می‌پذیرد و امکان ماین کردن بلوک‌های جدید را به کاربران می‌دهد. اما نکته اصلی بلاک چین‌ها آن است که باید غیر متمرکز باشند. اگر بلاک چین (زنجیره بلوکی) غیر متمرکز است، چطور می‌توان اطمینان حاصل کرد که همه آن‌ها یک زنجیره یکسان را منعکس می‌کنند؟ به این موضوع «مساله اجماع» (Consensus Problem) گفته می‌شود و در صورت تمایل به داشتن بیش از یک گره در شبکه باید یک الگوریتم Consensus پیاده‌سازی شود.

ثبت گره‌های جدید

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

  1. nodes/register/ برای پذیرش لیستی از گره‌های جدید به شکل URL‌ها
  2. nodes/resolve/ برای پیاده‌سازی الگوریتم Consensus، که هرگونه ناسازگاری را رفع می‌کند (برای اطمینان از اینکه یک گره دارای زنجیره صحیحی است).

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

روشی برای افزودن گره‌های همسایگی به شبکه

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

پیاده‌سازی الگوریتم Consensus

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

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

اولین متد ()valid_chain، با حلقه زدن در هر بلوک و اعتبارسنجی هش و Proof مسئول بررسی این است که آیا یک زنجیره معتبر است یا خیر. ()resolve_conflicts متدی است که در میان همه گره‌های همسایگی حلقه می‌زند، زنجیرهای آن را دانلود می‌کند و آن‌ها را با استفاده از روش بالا تایید می‌کند.

اگر یک زنجیره معتبر پیدا شد که طول آن بیشتر از زنجیره ساخته شده است، با زنجیره موجود جایگزین می‌شود. اکنون، دو نقطه پایانی رابط کاربردی برنامه‌نویسی (Application Programming Interface | API) ثبت می‌شوند، یکی برای افزودن گره‌های همسایگی و دیگری برای حل ناسازگاری.

در این نقطه می‌توان در صورت تمایل یک ماشین متفاوت را دریافت کرد و گره‌های مختلفی را به شبکه افزود و یا فرآیندها را با استفاده از پورت‌های گوناگون در ماشینی یکسان چرخاند. اکنون گره دیگری در ماشین موجود در پورت دیگری افزوده می‌شود و با گره کنونی ثبت می‌شود. بنابراین اکنون دو گره http://localhost:5000 و http://localhost:5001 وجود دارد.

ثبت یک گره جدید

سپس، برخی از بلوک‌های جدید در گره ۲ ماین شده‌اند تا اطمینان حاصل شود که زنجیره طولانی‌تر است. پس از آن، GET /nodes/resolve در گره ۱ فراخوانی می‌شود که زنجیره با الگوریتم Consensus جایگزین شده است.

الگوریتم Consensus

اگر مطلب بالا برای شما مفید بوده، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۴۳ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
Hackernoon
دانلود PDF مقاله
۲۱ دیدگاه برای «آموزش ساخت بلاک چین (Blockchain) با پایتون – راهنمای کاربردی»

سلام، ممنون از آموزش خوبتون
یه سوال دارم… ترنزکشن های جدید به نود های مختلف ارسال میشه. پس اون نودی که موفق میشه proof را به دست بیاره چطوری همه ترنزکشن ها را در بلاکچین خودش اضافه می‌کنه؟

سلام .با تشکر از اموزش خوبتون.
ایا میشه شبکه بلاکچینی خودمون بنویسیم و برای زیر ساخت یه کارخونه معمولی ازش استفاده کرد؟؟ برای ماین کردن همچین بلاکچینی چ سیستم یا انرژی ای نیاز هست؟؟
لطفا راهنماییم کنید

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

سلام.متشکرم از شما.من متوجه یم خطا در متد
new_transaction
شدم.لطفا خط آخر متد رو به صورت زیر تغییر بدید تا مشکل حل شود.
return self.last_block()[‘index’] + 1

صمیمانه از همراهی شما با مجله فرادرس و ارائه بازخورد سپاس‌گزاریم.

کد مربوطه به همان شکلی که نوشته شده، صحیح است و نباید از پرانتز استفاده شود. زیرا پیش از متُد last_block، از آرایه‌‏گر خصوصیت یا همان Decorator Property استفاده شده است. بنابراین last_block درست مثل یک متغیر عمل می‌کند و نمی‌توان آن را مانند یک تابع فراخوانی کرد.

برای شما آرزوی سلامتی و موفقیت داریم.‌

چجوری پایتون و pip رو نصب کنیم

سلام، وقت شما بخیر؛

از همراهی شما با مجله فرادرس بسیار سپاسگزاریم. برای یادگیری نصب پایتون روی سیستم عامل‌ها و پلتفرم‌های گوناگون می‌توانید از این مطلب مجله فرادرس با عنوان «آموزش نصب پایتون» استفاده کنید.

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

سلام خسته نباشید ، پیشنهاد شما برای یک فرد ۲۳ ساله که میخواد یه مهارت برنامه نویسی داشته باشه و کسب درآمد بکنه و حتی بعداً به عنوان رزومه ازش استفاده کنه چیه؟و چه مراحلی رو باید طی کنه؟

با عرض سلام و وقت به خیر خدمت جنابعالی؛

اتفاقاً به تازگی مقاله‌ای دقیقاً با همین موضوع در مجله فرادرس منتشر شده است که در آن به طور جامع به نحوه کسب درآمد از برنامه‌نویسی پرداخته شده و شما می‌توانید با مطالعه آن کاملاً به پاسخ سوال خود برسید:
«چگونه از برنامه‌نویسی پول در بیاوریم‌؟ — کاربردی و اصولی‌ترین روش‌ها»
علاوه بر این، مطالعه مقاله دیگری هم برای شناخت مسیر یادگیری پایتون پیشنهاد می‌شود. چرا که پایتون یکی از محبوب‌ترین و پر استفاده‌ترین زبان‌های برنامه‌نویسی به حساب می‌آید. این زبان همه‌منظوره است و با یادگیری آن می‌توانید در حوزه‌های مختلف (مورد علاقه خود) به عنوان برنامه‌نویس پایتون مشغول به کار شوید:
«بهترین مسیر یادگیری پایتون چیست؟ — راهنمای شروع آموزش»

با تشکر از شما و با آرزوی موفقیت و سلامتی.

سلام خسته نباشید
من با یک یاهو دوتا بلاک چین دارم این مشکلی ایجاد نمیکنه؟؟؟

لطفا جواب بدید

با سلام
چطور میشه بلاک چین رو به تعداد انبوه و صنعتی تولید کرد

لطفا جواب بدید

سلام
میخواستم بدونم چطور میشه بلاک چین رو به طور انبوه تولید کرد

سلام
مطالب خوبی دارید .

سلام آیا ممکنه از بلاک چین رمز ارزهای دیگر مانند بیت کوین و غیره و یا هر بلاک چین دیگر ، جهت رمز ارز جدید استفاده کنیم؟ و اگر چنین چیزی ممکنه میشه توضیح بدید.

با سلام؛

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

پیروز، شاد و تندرست باشید.

سلام.لطفن فیلم آموزشی این مقاله رو فراهم کنید….ممنون میشم

سلام خسته نباشید ، پیشنهاد شما برای یک فرد ۲۳ ساله که میخواد یه مهارت برنامه نویسی داشته باشه و کسب درآمد بکنه و حتی بعداً به عنوان رزومه ازش استفاده کنه چیه؟و چه مراحلی رو باید طی کنه؟

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

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *