Skip to main content

احتمالا این روزها با داغ بودن بحث بلاک‌چین و بیت‌کوین و سایر مباحث مرتبط با رمزارزها، احتمالا اگر عمیق‌تر از سایرین وارد ماجرای مرتبط با رمزارز شده باشید، متوجه شدید که یکی از مهم‌ترین بخش‌های تعاریف مرتبط با رمزارز، الگوریتمی به نام «اثبات کار» یا Proof of work است.

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

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

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

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

اثبات کار در رمزارز چطور کار می‌کنه؟

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

یک مثال خیلی ساده رو در نظر بگیریم :

رشته های مختلفی در یک سرور وجود دارند که به صورت متن خالص (plain text) نوشته شدند. ما میخواهیم شما این ها رو طوری hash کنید که پنج رقم ابتدای هش، حتما 1a1b0 باشه.

اگر نمی‌دونید هش چیه، ویدئوهای جادی (قسمت اول، قسمت دوم، قسمت سوم) می‌تونه در درک هش به شما کمک کنه.

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

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

پیاده سازی در روبی

هش کردن در روبی

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

require 'digest'

و سپس برای دریافت هش مورد نظر (در این مطلب از sha256 استفاده خواهیم کرد) کافیه که چنین کاری کنیم :

hash = Digest::SHA256.hexdigest("Hello, world!")
 
puts hash

و پاسخ ما چنین خواهد بود :

315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3

و اما بریم سراغ همون ساده ترین راه حلی که داشتیم، این راه حل بعنوان یک راه حل ساده، به ذهن من رسید. راه حل اینه :

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

خب کد ما در نهایت چنین چیزی میشه :

########
# POW in Ruby 
########
 
require 'digest'
 
i = 0 
while true
    i = i + 1 
    string = "Sample Text" + i.to_s 
    hash = Digest::SHA256.hexdigest(string)
 
    if hash[0..4] == "1a1b0" 
 
        puts "--------"
        puts "Work proven. You worked so hard :)"
        puts "The result is #{string} and the hash is #{hash}"
        break 
 
    else 
        puts "We are at attempt No. #{i}"
    end  
 
end

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

We are at attempt No. 751270
We are at attempt No. 751271
We are at attempt No. 751272
--------
Work proven. You worked so hard :)
The result is Sample Text751273 and the hash is 1a1b0ae39e178300c5ae7650d9c809da499eb165f7e621b70c0634d673874b5d

همونطور که می‌بینید بعد از ۷۵۱۲۷۳ تلاش، تونسته اون چیزی که ما مد نظر داریم رو برامون بسازه.

این تمرین خوبیه. ولی برای کار واقعی خوب نیست. چرا؟

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

در پایان هم امیدوارم که این آموزش، به دردتون خورده باشه. راستی شما برای اثبات کار چه می‌کنید؟ در بخش نظرات منتظرتونیم 🙂