مقدمه

شما هم می‌خواهید بدانید بلاکچین چیست اما تا کنون هرچه این‌ور آن ور خوانده‌اید جز به سردرگمی‌تان نیفزوده؟ شما که غریبه نیستید، خود من هم تا حدود دو سال پیش با رجوع به انواع متن‌ها، کلیپ‌ها، اینفوگرافیک‌ها و دیگر هاها نتوانستم بفهمم این بلاکچین یعنی چه. بنا به شرایطی بالاخره فهمیدم بلاکچین چیست و وقتی فهمیدم، تازه عیار عمدۀ محتوای فارسی توضیح بلاکچین را دریافتم! پس از آن، برای دوستان مشتاقم -چه با زمینه‌های فنی و چه غیرفنی- بلاکچین را توضیح دادم، از آن‌ها بازخورد مثبت گرفتم. بسیاری‌شان اذعان داشتند هیچ‌کدام از محتوا‌های فارسی‌ای که تا آن موقع به آن مراجعه کرده بودند مطلب را این‌طور برایشان جا نینداخته بوده (لابد می‌گویید از کجا معلوم تو واقعاً مطلب درست را جا انداخته‌ای؟! خیلی بی‌ادبید!).

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

هدف این متن دادن یک شهود ابتدایی از مفاهیم مرتبط با شبکۀ بلاکچینی بیت‌کوین است؛ جزئیات فنی را برای بعد وامی‌گذارم، هدف این است که شما یک شهود روشن از این شبکه پیدا کنید و من برای این که حواس شما را پرت نکنم تا می‌توانم از حاشیه رفتن و پرداختنِ بی‌موقع به جزئیات فنی و افاضه فضل و این طور مسائل اجتناب می‌کنم؛ پس اگر در متن دیدید جایی دارم به مسائل فنی اشاره می‌کنم بدانید اولاً حتماً لازم بوده و ثانیاً قرار نیست آن را طوری توضیح دهم که کسی که پیش زمینۀ فنی ندارد متوجه نشود. نکتۀ آخر این که اگر می‌بینید جایی به بدیهیات اشاره می‌کنم فکر نکنید شما را خنگ فرض کرده‌ام، استغفرالله معاذ الله شأن شما اجل از این حرفاست! اگر دیدید توضیح واضحاتی می‌دهم یا بدیهیاتی را با آب و تاب می‌پرورانم لابد حتماً آن همه تاکید مهم بوده و جز از این طریق نمی‌توانسته‌ام بحث را باز کنم و جا بندازم. خلاصه، به‌تان بر نخورد! یک نموداری هم آماده کردیم که فکر کنم پس از خواندن این متن مطالعه‌اش برایتان مفید باشد.

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

مگه قبل بلاکچین چجوری بود؟

مثال اول

وقتی می‌خواهیم یک سایت را ببینیم چه اتفاقی می‌افتد؟ اطلاعات سایت درون یک سرور قرار دارد؛ «اطلاعات» شامل متن‌های یک سایت، عکس‌های آن، نحوۀ چینش آن‌ها و ... . منظور از «سرور» هم یک چیزی شبیه همین کامپیوتر یا گوشی جلوی جنابتان است؛ یعنی واقعاً یک سخت افزاری چیزی یک جایی هست (واقعاً وجود داره! فیزیکی! مجازی نیست!) که یک هاردی دارد، پردازش‌گری دارد، دم و دستگاهی دارد و البته به شبکۀ اینترنت هم وصل است. شما وقتی یک سایتی را (مثلاً رجانیوز را) می‌خواهید ببینید به شبکۀ اینترنت وصل می‌شوید و برای آدرس آن «سرور» یک درخواست می‌فرستید. باورتان نمی‌شود هر دفعه این کار را می‌کنید؟ وقتی در مرورگرتان می‌نویسید www.rajanews.com فی‌الواقع دارید آدرس را وارد می‌کنید و به محض آن‌که اینتر را می‌فشارید درخواست شما برای «سروری» که اطلاعات رجانیوز در آن قرار دارد از طریق شبکۀ اینترنت فرستاده می‌شود.

سرورِ رجانیوز می‌بیند یک درخواست از طرف فردی (که شما باشید) به‌آدرس فلان (که یه چیزی شبیه 192.168.16.1 ــه) آمده؛ چه درخواستی؟ درخواست نمایش صفحۀ اول سایت رجانیوز. او هم می‌بیند شما بچۀ خوبی هستید و اطلاعات صفحۀ اول رجانیوز (متن‌ها، عکس‌ها، نحوۀ چینش و ...) را از طریق شبکۀ اینترنت برای آدرس شما بازمی‌فرستد. شما اطلاعات را دریافت می‌کنید و مرورگرتان آن اطلاعات را می‌خواند و می‌چیند و صفحۀ اول رجانیوز در مرورگرتان بالا می‌آید.

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

بانک عزیز

برویم جلو. نه فقط یک سایت خبری، اطلاعات بانک‌ها هم همینطورند. مثلاً شما با موبایل‌بانکتان یا اینترنت‌بانکتان یا هر کوفت‌بانک دیگرتان می‌خواهید پولی را برای دیگری واریز کنید. اطلاعات حساب شما درون سرور بانک قرار دارد؛ «اطلاعات» شامل نام و نام خانوادگی، موجودی حساب شما، تاریخچۀ تراکنش‌ها و همینطور یک سری اطلاعات برای احراز هویت مثل رمزعبور و ... . منظور از «سرور» هم یک چیزی شبیه همین کامپیوتر یا گوشی جلوی جنابتان است؛ یعنی واقعاً یک سخت افزاری چیزی یک جایی هست (واقعاً وجود داره! فیزیکی! مجازی نیست!) که یک هاردی دارد، پردازش‌گری دارد، دم و دستگاهی دارد و البته به شبکۀ اینترنت هم وصل است و البته نزد بانک است؛ محفوظ و نگه‌داری شده.

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

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

ببینید وقتی سرور را می‌دهید دست یک نفر چه می‌شود! حالا کاری ندارم چه اتفاقات دیگری ممکن است بیفتد. مثلا از کجا مطمئنید صاحب بانک (صاحب سرور) نرفته یک صفر جلوی موجودی حساب پسرخاله‌اش بگذارد؟ از کجا مطمئنید بانک تراکنش‌های همه را واقعاً چک می‌کند؛ مثلا نمی‌تواند از طرف یک نفر بدون آن که حسابش پر باشد برای دیگری پول بریزد؟ می‌تواند! مگر در رودروایستی گیر کند و الا قدرتش را دارد! حتی حالت‌های عجیب‌تری هم می‌توان تصور کرد.

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

ببینید وقتی سرور را می‌دهید دست یک نفر چه می‌شود!

جمع‌بندی علمی این قسمت

حالا برای این که فکر نکنید این لاطائلات چیست که من می‌بافم یک مرور سریع نسبتاً علمی بر آن چه گفتم می‌کنم. در دو مثال بالا، سیستم متمرکز بود. سیستم‌های متمرکز ایراداتی دارند، از جمله:

  1. می‌توانند به دلخواه هر که را می‌خواهند سانسور یا تحریم کنند.
  2. به یک مو بندند (Single Point of Failure). یعنی اگر آن مرکزیت که همه‌چیز را در اختیار دارد به فنا رفت، همه‌چیز به فنا رفته است.

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

  1. مسئلۀ دوبارپرداخت (Double Spending)

خوب عزیزان، چگونه این مشکلات را حل کنیم؟ دیدید این مشکلات از کجا آب می‌خورد؟ با ما همراه باشید!

قدم قدم

بیایید با هم مسئله‌ها را دانه دانه قدم قدم حل کنیم. معماری بخش قبل را در نظر بگیرید؛ یک سرور مرکزی، یک متصدی، یک مشت مشتری و ارباب رجوع و یک مشت درخواست. این معماری را اصلاح می‌کنیم تا مشکلاتی را که برشمردیم و برنشمردیم، رفع کنیم. کاربرد را هم همان مثال بانک بینگارید.

به چند مو بند بودن

مسئلۀ به یک مو بند بودن (Single Point of Failure) ساده‌تر به‌نظر می‌آید؛ از آن شروع می‌کنیم. چه‌کنیم سیستم به یک مو بند نباشد؟ به چند مو بندش می‌کنیم، خیلی ساده. اما یعنی چه؟ پیشنهادی دارید؟ سیستمی که به چند مو بند باشد به یک مو بند نیست سخن بزرگان

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

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

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

تبریک می‌گم، یک قدم مسئله را حل کردیم! اما...

مسئلۀ تصدی‌گری

اما طرح ابتدایی ما اشکالاتی دارد که باید رفع کنیم. بر فرض که مشکل به یک مو بند بودن را حل کردیم، هنوز مشکلات دیگر باقی هستند؛ یعنی هنوز هم یک نفر و یک نهاد صاحب و مالک و متصدی همۀ این بیست تا سرور است و اگر بخواهد می‌تواند همۀ این سرورها را با هم هماهنگ کند تا مثلا به یک شخص خاص خدمات ندهند یا یک اطلاعات خاص را در تمامی این سرورها باب میل خودش تغییر دهد. برای حل مسئلۀ تصدی‌گری چه کنیم؟

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

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

مسئلۀ ذخیرۀ اطلاعات

یک مشکل خیلی جدی دیگر؛ این چندین سرورِ ما، اطلاعاتشان را کجا ذخیر می‌کنند؟ نزد خودشان یا در جای دیگر؟ اگر نزد خودشان، هر کس همۀ اطلاعات را دارد یا فقط بخشی از اطلاعات را به هر سرور می‌سپاریم؟ چون این مسئلۀ ذخیرۀ اطلاعات و داده‌ها بسیار مهم است بیایید انواع حالات را در نظر بگیریم.

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

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

یک راه حل این است که همۀ سرورها همۀ اطلاعات را همزمان داشته باشند؛ هر سرور هم تا دادۀ جدیدی به اطلاعات قبلی افزود سریع به بقیه هم خبر می‌دهد تا اطلاعاتشان را به‌روز برسانند. این باز بهتر است، چون دیگر درصورت از دورخارج‌شدن یک سرور وقفه‌ای در خدمات‌رسانی دیگر سرورها ایجاد نمی‌شود. همۀ سرورها همه‌جا همۀ اطلاعات را عین هم داشته باشند اما یک مشکل خیلی عجیب دیگر ممکن است رخ دهد؛ مثلا فرض کنید من به یکی از این سرورها درخواست بدهم همۀ پول حسابم را برای شما واریز کند؛ همزمان خیلی سریع بروم به یک سرور دیگر درخواست بدهم همۀ موجودی حسابم را برای دوست دیگرم واریز کند. فی‌الواقع چون می‌دانم یک سرور از وقتی اطلاعات حسابم را چک می‌کند و آن را تغییر می‌دهد تا وقتی که بقیۀ سرورهای شبکه را از این تغییرات باخبر می‌کند طول می‌کشد، از این تاخیر در مطلع‌شدن سایرین سواستفاده می‌کنم و پول حسابم را «دوبار می‌پردازم»؛ همان دغدغۀ Double Spending!

امیدوارم کاملاً توجیه شده باشید که مسئلۀ مدیریت داده‌ها چقدر مهم است. برویم سراغش!

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

من بعد، هر سرور هر بار که تراکنش‌های جدید دریافت کرد، خیلی تمیز هر کدام را روی یک برگه می‌نویسد، آن‌ها را درون یک بسته مرتب قرار می‌هد (احیاناً یک کش هم دورشان می‌اندازد!)، بسته را امضا می‌کند که او صحت تراکنش‌ها را تضمین می‌کند و آن‌گاه آن بسته را (که رویش یک شناسۀ مخصوص درج شده) منتشر می‌کند تا دیگر سرورها هم این بسته را به ذخائرشان بیفزایند. حال اگر سرور دیگری خواست داده‌های جدیدی بیفزاید، او هم داده‌هایش را مرتب درون یک بسته قرار می‌دهد، بسته را امضا می‌کند و ضمناً روی بسته می‌نویسد که صحت محتویات آن را براساس اطلاعات کدام بسته‌های پیشین سنجیده است؛ برای این کافیست شناسۀ بستۀ پیشین (یعنی آخرین بسته‌ای که یک سرور دیگر منتشر کرده) را ذکر کند. این‌گونه هر که بخواهد اطلاعات به سیستم اضافه کند مشخص می‌کند صحت این اطلاعات بر اساس کدام سلسله اطلاعات قبلی (که درون بسته‌های قبلی قرار داشتند) سنجیده شده‌اند. خوب، داده‌هامان و ترتیبشان منظم شد:

داده‌ها را منظم و مرتب ذخیره می‌کنیم. یعنی یک مشت دادۀ جدید را که خواستیم ذخیره کنیم درون یک بسته (پوشه، دفتر، اوارج یا هر تعبیر دیگر که عشقتان می‌کشد) می‌گذاریم و روی بسته می‌نویسیم که وقتی این اطلاعات را بررسی می‌کرده‌ایم آخرین بستۀ منتشر شده توسط سایرین کدام بسته بوده.

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

یک مرور بر این بخش

تعدادی سرور داریم که همه به هم متصلند و از طریق شبکۀ اینترنت می‌توان با آن‌ها در ارتباط بود؛ متصدی این سرورها هر کسی می‌تواند باشد، حتی شما دوست عزیز (فعلا فرض کنید همه‌شان درستکارند و دغدغه‌مان این است که سیستم درست و منظم و بادوام و باقوام کار کند). همۀ این سرورها نزد خود اطلاعات مشابهی را ذخیره کرده‌اند؛ اطلاعات موجودی حساب همۀ انسان‌ها نزد همۀ سرورها هست.

وقتی یک نفر می‌خواهد تراکنشی را ثبت کند، به شبکۀ اینترنت وصل می‌شود و فریاد می‌زند: «می‌خواهم انقدر پول به فلانی بدهم». نزدیک‌ترین سروری که صدای او را شنید درخواست او را بررسی می‌کند (و فرض کردیم ملت هم درستکارند) و آن تراکنش را به همراه چند تراکنش دیگر که احتمالاً همزمان از چند مشتری دیگر دریافت کرده، ثبت می‌کند؛ «ثبت می‌کند» یعنی آن‌ها را مرتب درون یک بسته قرار می‌دهد، بسته را امضا می‌کند، یک شناسۀ مخصوص بسته به آن الصاق می‌کند (مثلاً فرض کن شناسه‌اش #2987 باشد) و سپس آن را در شبکه منتشر می‌کند؛ «در شبکه منتشر می‌کند» یعنی آن را برای دیگر سرورها می‌فرستد که آن‌ها هم آن را نزد خود داشته باشند تا اطلاعات نزد همۀ سرورها عین هم بماند.

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

یک سرور دیگر یک جای دیگر جهان هم اگر تراکنش‌هایی دریافت کرد همین کار را می‌کند و او هم روی بستۀ جدید تولیدی خودش ذکر می‌کند که بسته‌اش با اطلاعات بستۀ #9972 سازگار است (که البته خود #9972 هم با #2987 سازگار بود) و آن را منتشر می‌کند.

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

قدم قدم، دور دوم

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

دوبارپرداخت

در بخش قبل گفتیم یک سودجو می‌تواند از تاخیری که بین دو سر سیستم وجود دارد سوءاستفاده کند، موجودی حسابش را دوبار بپردازد. حتی اگر چنین سودجویان قالتاقی هم در عالم امکان نباشند باز شبکه شیرتوشیر می‌شود؛ چرا؟ فرض کنید یک سرور یک جای شبکه تند و تند تراکنش بپذیرد و هی بسته تولید کند منتشر کند، یک سرور دیگر هم یک جای دیگر شبکه همینطور، سرورهای دیگر هم همینطور. شبکه هم که همین‌طور یک تاخیری دارد کمی طول می‌کشد تا یک بسته از یک سر شبکه برای سرورهای سر دیگر شبکه فرستاده شوند و کلا این فرایند به‌روزرسانی داده‌های سرورها با کمی تاخیر صورت می‌گیرد، کمی طول می‌کشد مطمئن شویم همه عین هم شده‌اند. حالا در این هیروویر فکر کن فرط‌وفرط از این‌سر و اون‌سر شبکه بسته‌های تراکنش بپاشد تو شبکه. آن موقع مثلاً یک سرور وقتی یک بستۀ جدید را بر اساس آخرین بسته‌ای که دریافته بود، ساخت و خواست آن را منتشر کند مطمئن نیست در این فاصله آیا بستۀ جدیدی در نقطۀ دیگری از شبکه تولید شده که هنوز به دستش نرسیده یا نه. در این هرج‌ومرج احتمالاً در لحظه تعداد زیادی بسته تولید می‌شود که همه بر اساس بسته‌های پیشین درستند اما اطلاعات تراکنش‌های درون خود آن‌ها ممکن است تکراری یا در تضاد با هم باشد. بگذریم که در میان این بسته‌پراکنی‌ها معلوم نیست اصلاً سروری فرصت کند تراکنش‌ها را با سابقۀ داده‌ها بررسی کند.

چه قاعده‌ای بگذاریم تا ملت نتوانند سریع‌سریع بسته در شبکه بپراکنند؟ راه حل؟ کاری کنیم ملت تندوتند نتوانند فرط‌وفرط بسته بسازند تا شبکه شیرتوشیر شود. مثلا اگر یک کاری کنیم حداقل ده دقیقه بین تولید دو بستۀ متوالی (در هر جای شبکه توسط هر سروری که  می‌خواهد باشد) زمان باشد، کمی توانسته‌ایم شبکه را آرام کنیم و آن موقع قشنگ همۀ بسته‌ها مرتب تولید می‌شوند؛ همه هم فرصت دارند اطلاعات قبلی خود را به‌روزبرسانند و هیچ ناسازگاری در ذخیرۀ اطلاعات در هیچ جای شبکه نخواهیم داشت (همه با فرض این که ملت و متصدیان درستکارند. حالت‌های ناجور را هم به حسابش خواهیم رسید بعداً، دندان روی جگر بگذارید).

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

تابع هش

هش (Hash یا #)، نام یک تابع است. ویژگی تابع هش این است که یک ورودی می‌گیرد، یک خروجی می‌دهد؛ بعد وقتی ورودی را یک اپسیلون، به اندازۀ یک دانۀ خردل، یک ذره، یک کمی، خیلی کوچک، زیاد می‌کنید، خروجی‌اش به طور کلی به طرز فجیعی عوض می‌شود به طوری که اصلاً و اصلاً انتظار نداریم همچنین تغییری رخ دهد! اصلاً ویژگی این تابع همین است، خروجی‌اش تصادفی‌نماست! تصادفی نیست ها... یعنی به ازای هر ورودی واقعاً فقط یک خروجی وجود دارد، اما چون رفتار تابع به هیچ وجه قابل پیش‌بینی نیست گویی خروجی تصادفی تولید می‌کند. (یکی از معانی واژۀ هش، جویدن است؛ به خصوص وقتی گاو یک مشت علف را می‌جود این فعل به کارش تعلق می‌گیرد. تابع هش هم عین گاو. آخرت با مسمایی!)

از این تابع ویژگی‌هایی را انتظار داریم که برخی‌اش را در بند قبل شمردم. حالا مرتب آن را ذکر می‌کنم:

  1. اولاً با دیدن خروجی آن نباید بتوان ورودی تابع را حدس زد. (Preimage Resistance)
  2. ثانیاً با داشتن یک ورودی و خروجی نباید بتوان ورودی دیگری یافت که همان خروجی را بدهد. (Second Preimage Resistance)
  3. ثالثاً نباید بتوان دو ورودی یافت که خروجی یکسان داشته باشند. (Collision Resistance)

(مورد دوم و سوم شبیه هم شدند؟ هه! فتأمل) این تابع ویژگی‌های دیگری هم دارد، مثلاً هر نوع ورودی‌ای می‌گیرد (مثلا می‌توانید در ورودی بهش متن هم بدهید، مثلاً اسمتان را. متن هم در رایانه به شکل یک عدد و رشته بیت ذخیره می‌شود دیگر خودتان بهتر از من می‌دانید). همین‌طور اصلاً مهم نیست ورودی چقدر بزرگ باشد، اصلاً شما برو کل متون کتابخانۀ ملی ایران را تایپ کن پشت سر هم بچین بده به تابع؛ تابع هش می‌پذیرد، رد نمی‌کند آن را می‌گیرد که مدیون کسی نشود. اما خروجی‌اش یک تعداد بیت محدود است (محض تأکید و یادآوری، اگر یک نقطه به همۀ آن متون کتابخانۀ مرکزی بیفزایید خروجی کلا عوض می‌شود). عه، برایتان سوال شد مگر می‌شود تعداد خروجی‌ها محدود باشد و آن سه ویژگی بالا هم محقق شود؟ سوال خوبی است. اجالتاً بدانید که توابع هشِ فعلی آن سه ویژگی را به صورت عملی و نه نظری پیاده‌سازی کرده‌اند؛ یعنی مثلاً برای تحقق مورد سوم «عملاً ممکن نیست دو ورودی یافت که خروجی یکسان داشته باشند».

حالا این هش را گفتیم که چه؟ دیدید خروجی هش تصادفی‌نما بود؟ پس وقتی یک ورودی دلخواه به هش می‌دهید، هر بیت خروجی هش در حکم یک سکه است، گویی به تعداد بیت‌های خروجی تابع هش سکه انداخته‌اید ببینید کدامشان شیر می‌آید کدامشان خط! حالا تاس نداریم، سکه که داریم، از سرورها می‌خواهیم یک ورودی معرفی کنند که وقتی آن را به تابع هش می‌دهیم شش بیت سمت چپ عدد خروجی تابع هش مثلاً همه صفر شوند (مثل همان ایده که شش تا تاس بیندازید همه شش بیایند)!

طرح پس این‌گونه می‌شود. جملۀ زیر را داشته باشید تا نشان دهم مسائل دیگرمان را هم حل می‌کند:

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

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

با یک تیر چند نشان را زدیم. اولاً یادتان هست هر بسته قرار بود یک شناسه داشته باشد؟ خوب این از شناسه، شناسۀ هر بسته، خروجی تابع هشی است که ورودی‌اش محتوای آن بسته است (چون دیدم عده‌ای باور نمی‌کنند بگذارید توضیح واضحات دهم: یعنی همۀ اطلاعات درون یک بسته را میچینیم کنار هم، می‌شود یک رشته بیت دیگر، آن را به عنوان ورودی می‌دهیم به تابع هش ببینیم خروجی‌اش چه می‌شود).

این‌طوری تغییر نکردن محتوای یک بسته هم تضمین می‌شود!  اگر امروز کسی در بسته‌ای اطلاعاتی را ثبت کرد و منتشر کرد، یک سال بعد نمی‌تواند ادعا کند محتوای بسته چیز دیگری بوده و دیگر سرورها اشتباه آن را ذخیره کرده‌اند؛ چون دیگر به‌راحتی می‌توان ادعایش را سنجید، کافی‌ست محتوایی که آن فرد مدعی‌ست محتوای حقیقی آن بسته است را به تابع هش بدهیم ببینیم خروجی‌اش با شناسه‌ای که قبلاً ثبت شده منطبق می‌شود یا نه. می‌گویید ممکن است ادعا کند شناسه را هم عوضی ذخیره کرده‌اند؟ آن هم قابل راستی‌آزمایی است، به‌یاد بیاورید شناسۀ یک بسته خودش یکی از محتواهای بستۀ بعدی است و درون بستۀ بعدی قرار دارد و به همان شکل می‌شود این ادعا را هم سنجید. تازه، شناسه بستۀ بعدی هم در یک خط درون بستۀ بعدی‌اش درج شده! و همین‌طور تا جدیدترین بستۀ حاضر.

برگردیم به همان دغدغۀ تاخیر. می‌خواستیم سرورها را که بسته‌ها را تولید می‌کردند به تاس انداختن واداریم تا نتوانند فرط‌وفرط بسته در شبکه بپراکنند و شبکه را مختل کنند و هر آن چه گفتیم. الان سرورها به تکاپو می‌افتند تا آن عدد دلخواه را هی تغییر دهند، کل محتوای بسته (شامل تراکنش‌ها، شناسه بستۀ قبل و آن عدد دلخواه) را به تابع هش بدهند ببینند شش بیت سمت چپ خروجی تابع صفر شده است یا خیر. مثلا فرض کنید هر ده دقیقه یک بار یک نفر یک جای شبکه شانسش می‌گیرد و این عدد دلخواه را می‌یابد. حالا هر کسی با دادن محتوای بسته به هش می‌تواند چک کند آیا واقعاً شش رقم سمت چپ خروجی صفر می‌شود و معلوم می‌شود چه کسی واقعاً زحمت تاس ریختن را کشیده (Proof-of-work)! این‌گونه آن مسئلۀ تاخیر تحمیلی را که می‌خواستیم، حل کردیم. تازه، تا یک نفر آن عدد دلخواه را یافت و بسته‌اش را منتشر کرد، تلاش‌های دیگران به باد می‌رود، چون آخرین بستۀ ثبت شده در شبکه دیگر بستۀ قبلی که روی آن کار می‌کرده‌اند نیست و باید برای یک بسته با محتوای جدید بگردند عدد دلخواه را بیابند! پس این نرخ «ده دقیقه یک بسته» باقی می‌ماند.

بی‌کاریم مگه؟

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

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

شاید باورتان نشود

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

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

شاید باورتان نشود، توضیحات بالا همان شبکۀ بلاکچین است برای رمزارز بیت‌کوین! دیدید چه روشن بود؟ واقعا تمام شد. شما الان متخصص بلاکچین در غرب آسیا هستید.

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

داده نما || سلسله بسته، یک سناریوی تخیلی برای توضیح برخی مفاهیم بلاکچینی

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

نمایش تصویر با کیفیت jpg | دریافت فایل pdf

مسئلۀ اجماع

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

یعنی یک کاونده (همان ماینر، همان کسی که تا چند بخش قبل صرفاً او را سِروِر می‌نامیدیم) این سر عالم تراکنش‌های من و دوستانم را دریافت کرده بوده، یک تراکنش 12.5 تایی برای خودش هم کنار آن‌ها گذاشته بوده، به همراه هش آخرین بستۀ ذخیره شده نزد همه (که از این به بعد با نماد #آخرین نشان می‌دهیمش) و یک عدد دلخواه درون بسته گذاشته بوده، آن را به تابع هش می‌داده بررسی می‌کرده آیا شش رقم سمت چپ خروجی هش همه‌شان صفر شده‌اند یا نه؛ اگر نه، عدد دلخواه را تا صفر شدن آن شش‌تا عوض کرده. حالا آن عدد دلخواهی که چنین کند را یافته، بسته‌اش را منتشر کرده. ( گفتیم شناسۀ هر بسته، هش آن بسته است. هش این بسته -که یک عدد است البته- را با نماد #آخرتر_این‌سردنیا نشان می‌دهیم).

یک کاوندۀ دیگر هم همزمان آن سر دنیا تراکنش‌های بچه‌محل‌هاشان را گرفته با 12.5 واحد پول برای خودش و دیگر مخلفات در بسته‌ای گذاشته، همان حرکات بند قبل را تکرار کرده و عاقبت پس از امتحان کلی عدد تصادفی، آن عدد دلخواه را که شش رقم سمت چپ خروجی هش بسته‌اش را صفر می‌کند، یافته؛ سپس بسته‌اش را منتشر کرده. (وی چون در آن سر دنیا بوده، هنوز مطلع نشده بوده که یکی این سر دنیا یک بستۀ جدید ساخته؛ نامبرده تنها نسخۀ قدیمی یعنی تا بستۀ #آخرین را نزد خود داشته، بالاخره یک چند دقیقه یا ثانیه‌ای شبکه تاخیر دارد دیگر). هش بستۀ این فرد را #آخرتر_آن‌سردنیا می‌نامیم.

حالا دو بستۀ حاوی تراکنش‌ها داریم که هر دو با تمامی تراکنش‌های قبلی سازگارند، هر دو مدعی‌اند آخرین بستۀ پیش از آن‌ها بستۀ #آخرین بوده. اطلاعات این دو بسته هم عین هم نبوده؛ #آخرتر_این‌سردنیا با #آخرتر_آن‌سردنیا یکی نیست (به داده‌نمای ضمیمه شده نگاه کنید، بلایی که سر بسته‌های شمارۀ 300 آمده).

هر پیشنهادی که می‌دهید نباید باز به متمرکز شدن بینجامد سوال. کاوندۀ بعدی، بستۀ خود را مبتنی بر کدام یک از این دو شاخه بنا نهد؟ در بسته‌اش، در جایگاه «هش بستۀ قبلی» کدام را قرار دهد، #آخرتر_این‌سردنیا را یا #آخرتر_آن‌سردنیا را؟ کاوندۀ بعدی صحت تراکنش‌هایی را که از ملت می‌گیرد با کدام سلسله بسته‌های قبلی بسنجد، سلسله‌ای که تا بستۀ #آخرتر_این‌سردنیا آمده یا سلسله‌ای که به #آخرتر_آن‌سردنیا ختم شده؟

خوب چه کنیم، کدام را بپذیریم؟ پیشنهادی دارید؟ رای‌گیری کنیم؟ساعت را نگاه کنیم که کدام زودتر بوده؟! هر پیشنهادی که می‌دهید نباید باز به متمرکز شدن بینجامد، ولو در حد این که ساعت را از یک نهاد مشخص (یک جای متمرکز) بخوانیم!

می‌خواهم بگویم قاعدۀ جدیدی لازم نیست بگذارید! خود شبکه تا حدی مسئله را حل می‌کند! چگونه؟

این طور می‌شود که یک عده بالاخره یکی از دو بسته را مثلاً #آخرتر_این‌سردنیا را به‌عنوان بستۀ آخر می‌گیرند (بقیه هم بستۀ دیگر را) و شروع می‌کنند مبتنی بر سلسله بسته‌هایی که به آن ختم می‌شود بستۀ بعدی را مهیا می‌کنند. تا عدد دلخواه کذایی را یافتند بستۀ جدید خود را منتشر می‌کنند؛ شناسۀ این بسته را #این‌سردنیا_یک بگیرید. پس طول سلسلۀ بسته‌های این سر دنیا از طول سلسله بسته‌هایی که به بستۀ #آخرتر_آن‌سردنیا ختم می‌شد یکی بیشتر می‌شود.

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

حالا فرض کنید یک نفر اصرار داشت بستۀ بعدی خود را در ادامۀ شاخۀ کوتاه‌تر تعریف کند؛ بر عبث می‌پاید! چرا؟ چون بر فرض که چنین کرد؛ مثلاً در بسته‌اش یک تراکنش قرار داد که به خودش 12.5 تا پول برسد. آیا بعدا می‌تواند این 12.5 تا را خرج کند؟ خیر! چرا؟ چون دیگر کاونده‌ها که شاخۀ دیگر را پذیرفته‌اند و پی آن رفته‌اند از او می‌پرسند کجای این سلسله بسته‌ها تو 12.5 تا پول گرفتی؟ او می‌گوید در شاخۀ موازی! و کاونده‌های دیگر به وی خنده‌ای کنند و او را به حال خود واگذارند! این بود که گفتم اطلاعات ثبت شده در شاخۀ کوتاه‌تر عملاً از اعتبار می‌افتد.

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

پیِ شاخۀ بلندتر بروید.

معاندین و براندازها

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

خیلی بد شد که، یک عده توانستند تقلب کنند.

اما سیستم خود را اصلاح می‌کند. چگونه؟ کاوندۀ بعدی که آدم درستکاری است احتمالاً، حین فراهم کردن بستۀ بعدی خود که داشته تراکنش‌هایش را با تراکنش‌های قبلی می‌سنجیده می‌بیند که تراکنش‌های بستۀ اخیر بی‌پشتوانه‌اند. به‌نظرتان چه کار کند؟ از بقیه بخواهد آن را حذف کنند؟ در تراکنشی آن پول را از آن‌ها بگیرد؟ نمی‌شود که... آقا پیشنهاد جدید نمی‌خواد بدید؛ شبکه فعلی خودش حل می‌کند مسئله را! چگونه؟

کاوندۀ درستکار کافیست آخرین بسته را ندید بگیرد و بستۀ جدید خود را مبتنی بر بستۀ #یکی‌مانده‌به‌آخر بسازد و منتشر کند (نام بسته‌اش را می‌گذاریم #سالم). آن موقع سلسلۀ بسته‌ها دو شاخه می‌شود. کاونده‌های بعدی که می‌بینند این سلسله دو شاخه شد، براق می‌شوند که یعنی چه شبکه دو شاخه شد، بررسی می‌کنند ببینند نکند تراکنش‌های درون یکی از بسته‌ها متقلبانه باشد. تا یافتند #کرمو متقلبانه است، بسته‌های بعدی خود را در ادامۀ بستۀ #سالم مهیا می‌کنند و منتشر می‌کنند.

خیلی ساده شبکه خودش را تصحیح می‌کند! ممکن است در یک لحظه اطلاعات غلط در شبکه ثبت شود. اما نهایتاً در عاقبت شبکه بر روی تراکنش‌های صحیح به اجماع می‌رسد و روی ندیدگرفتن شاخه‌های ناصواب اجماع می‌کند (به بستۀ شمارۀ 303 در داده‌نما بنگرید).

سوال. به نظرتان معاندین کی می‌توانند شبکه را مختل کنند یا آن که یک اطلاعات غلط را در شبکه ثبت کنند؟  آنانی که توان پردازشی بیشتری داشته باشند، به احتمال بیشتری توفیق تولید بستۀ بعدی شبکه را دارند. یادتان باشد که متصدیان این شبکه تعداد زیادی کاونده‌اند؛ این کاونده‌ها هر کسی از هر جای جهان می‌توانند باشند. بستۀ اطلاعات بعدی شبکه را یکی از این کاونده‌ها -آن‌ هم اتفاقی، اگر شانس داشته باشد- توفیق می‌یابد بسازد. پس عملاً قدرت ثبت یا تغییر اطلاعات در شبکه در دست یک نفر یا یک گروه نمی‌تواند باشد. اما فرض کنید یک نفر یک رایانۀ بسیار قوی داشت که با آن می‌توانست خیلی سریع همۀ عددهای دلخواه کذایی را در بستۀ جدیدش بگذارد و بیازماید و بستۀ جدید را تولید کند؛ آن موقع او احتمالا می‌تواند بسته‌های بیشتری را بسازد و منتشر کند.

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

چه جالب. فتامل!

جمع‌بندی

پایان.

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

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

در قسمت بعد خواهید دید

با این حال در این مقاله نگفتیم حریم خصوصی ملت چگونه حفظ می‌شود؟ چگونه مالکیت یک پول به شخص دیگر منتقل می‌شود؟ چرا اصلاً بیت‌کوین و پولی که در این شبکه تعریف شده با ارزش است و اعتبار دارد؟ و بسیار سوالات دیگر. چرا که اصلا هدف این متن نبود. اما اکنون که این متن را از نظر گذرانده‌ایم می‌دانیم آماده‌ایم تا پاسخ سوالات بالا را به روشنی بیابیم. نمودار ضمیمه شده حاوی برخی اطلاعات دربارۀ نوع ذخیرۀ اطلاعات و انتقال مالکیت است. با این حال شاید در مقالۀ بعدی بیشتر دربارۀ خود بیت‌کوین (نه شبکۀ بلاکچین) نوشتم یا نوشتند دوستان!

قدردانی

از محمدرضا ممنونم که متن را خواند و پیشنهاداتی داد. همچنین تشکر از دست‌اندرکاران مسابقۀ الکاپ و نیز آزمایشگاه دیسنترالب، شما هم ممنون!

مشق شب

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

  1. این متن توضیح فناوری بلاکچین بود؛ یک شبکه‌ای که طراحی شده تا بی‌آن‌که مرکزیتی آن را بپاید سرپا بماند. چه واژۀ فارسی‌ای را معادل بلاکچین پیشنهاد می‌کنید که معنایی نزدیک به آن چه دریافته‌اید را برساند؟ مثلاً برخی زنجیرۀ بلوکی را جایگزین کرده‌نداند. من واژۀ سلسله را به دلایل متعددی که شاید در یک متن دیگر آن را شکافتم به‌جای زنجیره پسندیدم. این شد که در این متن از آن با نام سلسله‌بسته یاد کردم. حالا می‌تواند به‌جای بسته بگذارید سلسله‌اوراج! (اوراج یعنی Ledger، دفتر حساب؛ برید خدا را شکر کنید من رئیس فرهنگستان ادب و زبان فارسی نیستم). شما چه واژه‌ای را نزدیک‌تر به معنایی که اکنون در وجودتان یافته‌اید پیشنهاد می‌کنید؟
  2. دیدید چه جالب توانستیم نگذاریم هیچ‌کس در پول الکترونیکی دخل و تصرف کند بی‌آن‌که بقیه بفهمند؟ کسی نمی‌تواند یک شبه پول حساب خود را چندین برابر کند یا کم کند یا کسی را تحریم کند یا سانسور. تازه به‌دست آوردن بیت‌کوین هم مثل کاویدن معدن برای یافتن طلا طاقت‌فرساست. خیلی شبیه طلا شد، نه؟ طلا را هم می‌توانیم به هم دیگر بدهیم، بدون آن که ارزش آن از اعتبار بیفتد و لازم باشد حتماً ذیل نظارت نهاد خاصی باشد. اما یک سوال، در دنیای واقعی آن کسی که طلای بیش‌تری دارد عملاً بر بقیه فائق می‌آید و مرکزیت قضیه را دست خود می‌گیرد. در این شبکۀ بلاکچینی نیز چنین است؟ چه کسی می‌تواند در این دنیای جدید نو بر بقیه فائق آید و امورات را به‌دست گیرد؟ اصلاً برایش می‌صرفد چنین تلاشی کند؟ (این سوالات استفهام انکاری و شعر و معر نیست‌ها! واقعا جواب دارد!)
  3.  در این سوال تقلبی برای سوال قبل وجود دارد. دیدید در متن گفتیم کسی که توان پردازشی بیشتر داشته باشد احتمالاً توفیق بیشتری خواهد داشت که بسته‌های بیشتری تولید کند؛ این از کجا آب می‌خورد؟ کدام قاعده‌ای که گذاشتیم به مهم‌شدن «توان پردازشی بیش‌تر» انجامید؟ حالا سوال اصلی: آن قاعده را چگونه عوض کنیم تا به‌جای توان پردازشی بیش‌تر موجودی حساب بیشتر مهم شود؟ سوال اصلی‌تر: آن قاعده را چگونه عوض کنیم تا هیچ چیزی مهم‌تر نشود و همه به یک میزان احتمال داشته باشد بسته تولید کنند؟ این خوب است یا بد؟

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

پایان