سلام. من امیرعلی سمیعی هستم دانشجوی کارشناسی علوم کامپیوتر دانشگاه تهران مرکز؛ باید به عنوان فعالیت کلاسی برای درس طراحی اصول نرمافزار استاد حاجیاسمعیلی مقالهای مینوشتم، که یاد این موضوع ۲۱ میلیون بودن بیتکوین افتادم! چند وقت پیش یکی از مقامات گفته بود باور نداره که ۲۱ میلیون بیتکوین داشته باشیم، از کجا بیشتر نباشه؟ یادمه یه ویدیویی در مورد اثبات این موضوع تو یوتوب دیده بودم ولی نتونستم ویدیو رو پیدا کنم به عنوان منبع براتون بذارم، از اونجایی که روش کار رو یادمه میخوام این موضوع رو توضیح بدم!
منبع کد بیتکوین مشخصه و همه نودها و ماینرها از اون منبع کد باید استفاده کنند. برای اینکه ثابت کنیم بیشتر از ۲۱ میلیون بیتکوین نداریم باید دست به کد بشیم! اول از همه منبع کدمون یا همون سورس کد رو باید بگیریم. پس ابتدا وارد گیتهاب بیتکوین میشیم، آدرس ریپوزیتوری رو کپی میکنیم و تو دستگاه خودمون ریپوزیتوری رو clone میکنیم.
تو vsCode سورس کدمون رو باز میکنیم. اصلا الزامی وجود نداره که شما زبان سیپلاسپلاس بلد باشید تا متوجه پاسخ این سوال بشید. فقط کافی است مفهوم برنامهنویسی و یک زبان برنامهنویسی را بلد باشید. من برای حل این مسئله از پایتون استفاده میکنم، نوشتنش سادهتره و دوستان بیشتری با این زبان آشنایی دارند.
همونطوری که گفتم، من هم یک بار این راه حل رو دیده بودم و سرچ هم کردم چیز خاصی بدست نیاوردم. فقط یادمه این موضوع به هاوینگ مرتبط بود. میتونید در مورد هاوینگ تو لینکی که ضمیمه کردم کامل مطالعه کنید ولی به صورت خلاصه توضیحش میدم؛ هاوینگ عملیاتی است که حدودا ۴ سال یک بار یا به عبارتی هر ۲۱۰ هزار بلاک یکبار در بلاکچین بیتکوین اتفاق میفته که باعث میشه جایزهی بلاک از آن بلاک به بعد نصف شود! ابتدا هر بلاکی که ماین میشد ۵۰ بیتکوین برای ماینر جایزه داشت. در حال حاضر که ۳ بار هاوینگ اتفاق افتاده مقدار آن به ۶.۲۵ رسیده است. این عملیات انقدر ادامه دارد تا زمانیکه جایزه بلاک به صفر برسد! (تقریبا سال ۲۱۴۰ میلادی) از آن زمان به بعد ماینر فقط حق تراکنش را از هر بلاکی که ماین میکند دریافت میکند.
من سعی میکنم خیلی مفاهیم پایهای بیتکوین رو توضیح ندم چون هدف این مقاله، بدست آوردن حداکثر تعداد بیتکوین است ولی هاوینگ ما را به جواب میرساند. اولین بلاکی که ساتوشی، خالق ناشناس بیتکوین ماین کرد ۵۰ بیتکوین تولید کرد، در حال حاضر ۶.۲۵ بیتکوین بعد از هر بلاکی که ماین میشود به مجموع کل بیتکوینها اضافه میشود که در زمان نگارش این مقاله کمتر از ۱۹ میلیون میباشد. تنها راه تولید بیتکوین و اضافه شدن آن به تعداد کل آن، ماینکردن است! کافی است محاسبه کنیم چه زمانی هاوینگ باعث میشود که شبکه دیگر جایزهای به ماینر ندهد و فقط حق تراکنش را به او اهدا میکند، از آنجایی که روش دیگری برای تولید بیتکوین نیست، در آن زمان هر چقدر بیتکوین باقیمانده باشد، حداکثر تعداد بیتکوین موجود خواهد بود.
به این منظور، عبارت having رو در سورس کد بیتکوین سرچ میکنم.
همونطوری که در عکس مشاهده میکنید، در ۲۸ جای این پروژه، عبارت halving استفاده شده. تک تک فایلها رو باز کردم، یه مروری کردم ببینم همون متدی است که به دنبالشم یا خیر. که پاسخ رو در فایل validation.cpp پیدا کردم. (در عکس بالا نشانگر ماوس روی آن است)
برای اینکه مفهوم هر کدام از این عبارات را متوجه بشیم میتونیم رو عبارت مورد نظر کلیک راست کرده و به Go To Definistion رفته یا عبارت مورد نظر را در پروژه جستجو کنیم. من عبارت nSubsidyHalvingInterval را سرچ میکنم تا ببینم مقدار آن چند است. همانطور که در عکس مشاهده میکنید در همان قسمت جستجو به ما مقدار این متغیر را نمایش میدهد.
بر میگردم به متد GetBlockSubsidy. همانطوری که از نام این متد مشخص است، جایزهی ماینر را محاسبه میکند. ابتدای این متد متغیر halvings مقداردهی میشود. که از تقسیم nHeight به nSubsidyHalvingInterval (210,000) بدست میآید. nHeight همان شماره بلاک میباشد (به همین منظور بعد از هر ۲۱۰ هزارتا بلاک هاوینگ اتفاق میفتد، چون این تقسیم پاسخی صحیح دارد و هر ۲۱۰ هزار بلاک یکبار، به تعداد آن یکی اضافه میشود).
در این متد ذکر شده اگر عدد هاوینگ بزرگتر برابر با 64 باشد صفر بازگرداند؛ یعنی بعد از شصت و چهارمین هاوینگ دیگر جایزهای به هیچ ماینری تعلق نمیگیرد.
سپس متغیر nSubsidy را مقدار دهی کرده است که ۵۰ برابر COIN است. روی عبارت COIN راست کلیک کرده و Go To Definistion را زده و طبق عکس زیر وارد کدی که این متغیر تعریف شده است میشویم.
همانطور که مشاهده میکنید COIN که در واقع یک بیتکوین است، برابر با ۱۰۰ میلیون است. ( که به هر COIN یک ساتوشی گفته میشود. به پیشنهاد یکی از کاربران فروم بیتکوین در ابتدای شکلگیری آن، برای اینکه اعداد را راحتتر بیان کنند، به هر بیتکوین عدد ۱۰۰ میلیون ساتوشی نسبتدهی شد.)
پس جایزهی هر شخص تا اینجا (اگر halving بزرگتر مساوی ۶۴ نباشد) برابر است با ۵ میلیارد ساتوشی (50 بیتکوین). ولی پس از آن عبارت nSubsidy >>= halvings را مشاهده میکنیم و سپس nSubsidy بازگردانده میشود. عبارت nSubsidy >>= halvings در واقع یعنی nSubsidy = nSubsidy >> halvings. علامت << به معنای شیفت راست میباشد. تصور کنید عدد باینری ۱۰۰ که در مبنای ۱۰ برابر با ۴ است را یه عدد شیفت راست کنیم، یعنی صفر پایانی را حذف کنیم، میشود عدد باینری ۱۰ که در مبنای ۱۰ برابر است با ۲. در عبارت ذکر شده، در واقع nSubsidy به تعداد halvings تقسیم بر ۲ میشود؛ یعنی در حال حاضر که عدد halvings برابر با ۳ است، عدد ۵۰ را در مبنای ۲، سه بار شیفت راست کرده که یعنی در مبنای ۱۰ سه بار تقسیم بر ۲ میکند، به این معنا که در حال حاضر هر بلاکی که ماین میشود nSubsidy آن برابر با ۶.۲۵ است.
حال فهمیدیم GetBlockSubsidy چگونه محاسبه میشود. در این قسمت من یک کد پایتون مینویسم که همواره از زمانی که halvings برابر با ۰ است تا زمانیکه به ۶۴ (مقدار پایانی خود) میرسد تعداد بیتکوینهای تولید شده را محاسبه کند. از آنجایی که راه دیگری برای تولید بیتکوین نیست، وقتی به شصت و چهارمین halvings برسم یعنی تعداد کل بیتکوینهای موجود را بدست آوردم.
همانطوری که در عکس مشاهده میکنید، همان متغیرهایی که داشتیم را تعریف کردم. فقط nHeight را از صفر مقداردهی کردم چون میخواستم از اولین ماینی که صورت گرفته تا آخرین ماینی که صورت خواهد گرفت (وقتی که جایزه به ماینر اهدا میشود) بیتکوین تولید شده را حساب کنم. (توجه کنید که halvings در عبارت nSubsidy >> halvings باید در تابع int قرار گیرد وگرنه ارور میدهد.)
پس تا زمانی که halvings از ۶۴ کوچکتر است باید محاسبه صورت گیرد. به ازای هر بلاک halvings محاسبه میشود. هر بار که حلقه شروع میشود به عدد بلاک یکی اضافه میشود. جایزه محاسبه شده و در متغیر totalSatoshi هر ساتوشی تولید شده را اضافه میکنم. وقتی این چرخه تمام شود، یعنی زمانی که halvings از ۶۴ بیشتر شود و قطعا بیتکوینی دیگری تولید نخواهد شد، مقدار totalSatoshi رو چاپ میکنم. که در عکس مقدار چاپ شده را مشاهده میکنید.
در واقع کمی کمتر از ۲۱ میلیون بیتکوین خواهیم داشت (۲۰,۹۹۹,۹۴۹.۹۷۶۹) و بیشتر از آن بیتکوینی تولید نخواهد شد!
نام استاد: دکتر مریم حاجی اسمعیلی. دکترای علوم کامپیوتر از دانشگاه کینگستون لندن
PhD of computer science from Kingston university of London