মূল কন্টেন্টে যান
Change page

Ethash

ইথহ্যাস (Ethash) ছিল ইথিরিয়ামের প্রুফ-অফ-ওয়ার্ক মাইনিং এ্যালগরিদম। প্রুফ-অফ-ওয়ার্ক এখন সম্পূর্ণরূপে বন্ধ করা হয়েছে এবং এর পরিবর্তে ইথিরিয়াম এখন প্রুফ-অফ-স্টেক ব্যবহার করে সুরক্ষিত। দ্য মার্জ, প্রুফ-অফ-স্টেক এবং স্টেকিং সম্পর্কে আরও পড়ুন। এই পেজটি ঐতিহাসিক আগ্রহের জন্য!

ইথহ্যাস হলো ড্যাগার-হাশিমোতো (Dagger-Hashimoto) এ্যালগরিদমের একটি পরিবর্তিত সংস্করণ। ইথহ্যাস প্রুফ-অফ-ওয়ার্ক হলো মেমরি হার্ড (opens in a new tab), যা এ্যালগরিদমটিকে ASIC প্রতিরোধী করে তুলবে বলে মনে করা হয়েছিল। শেষ পর্যন্ত ইথহ্যাস ASIC-গুলো তৈরি করা হয়েছিল, কিন্তু প্রুফ-অফ-ওয়ার্ক বন্ধ হওয়ার আগ পর্যন্ত GPU মাইনিং একটি কার্যকর বিকল্প ছিল। ইথহ্যাস এখনও অন্যান্য নন-ইথিরিয়াম প্রুফ-অফ-ওয়ার্ক নেটওয়ার্কে অন্যান্য কয়েন মাইন করতে ব্যবহৃত হয়।

ইথহ্যাস কীভাবে কাজ করে?

মেমরি হার্ডনেস এমন একটি প্রুফ-অফ-ওয়ার্ক এ্যালগরিদমের মাধ্যমে অর্জিত হয় যার জন্য নন্স এবং ব্লক হেডারের উপর নির্ভরশীল একটি নির্দিষ্ট রিসোর্সের সাবসেট বেছে নেওয়া প্রয়োজন। এই রিসোর্সটিকে (কয়েক গিগাবাইট আকারের) DAG বলা হয়। DAG প্রতি 30000 ব্লকস পর পর পরিবর্তিত হয়, যা ~125-ঘণ্টার একটি উইন্ডো যাকে এপোক (প্রায় 5.2 দিন) বলা হয় এবং এটি তৈরি হতে কিছুটা সময় নেয়। যেহেতু DAG শুধুমাত্র ব্লক হাইটের উপর নির্ভর করে, তাই এটি আগে থেকেই তৈরি করা যায়, কিন্তু যদি তা না হয় তবে একটি ব্লক তৈরি করার জন্য ক্লায়েন্টকে এই প্রক্রিয়াটি শেষ হওয়া পর্যন্ত অপেক্ষা করতে হবে। যদি ক্লায়েন্টরা আগে থেকে DAG তৈরি এবং ক্যাশ না করে, তবে নেটওয়ার্ক প্রতিটি এপোক ট্রানজিশনে ব্যাপক ব্লক বিলম্বের সম্মুখীন হতে পারে। মনে রাখবেন যে প্রুফ-অফ-ওয়ার্ক যাচাই করার জন্য DAG তৈরি করার প্রয়োজন নেই, যা মূলত কম CPU এবং ছোট মেমরি উভয়ের মাধ্যমেই যাচাইকরণের অনুমতি দেয়।

এ্যালগরিদমটি সাধারণত যে পদ্ধতি অনুসরণ করে তা নিচে দেওয়া হলো:

  1. একটি সিড (seed) রয়েছে যা সেই পয়েন্ট পর্যন্ত ব্লক হেডারগুলো স্ক্যান করে প্রতিটি ব্লকের জন্য গণনা করা যেতে পারে।
  2. সিড থেকে, একটি 16 MB সিউডোর‍্যান্ডম ক্যাশ গণনা করা যায়। লাইট ক্লায়েন্টরা ক্যাশ স্টোর করে।
  3. ক্যাশ থেকে, আমরা একটি 1 GB ডেটাসেট তৈরি করতে পারি, যার বৈশিষ্ট্য হলো ডেটাসেটের প্রতিটি আইটেম ক্যাশ থেকে শুধুমাত্র অল্প সংখ্যক আইটেমের উপর নির্ভর করে। ফুল ক্লায়েন্ট এবং মাইনাররা ডেটাসেট স্টোর করে। ডেটাসেট সময়ের সাথে সাথে লিনিয়ারলি বৃদ্ধি পায়।
  4. মাইনিংয়ের ক্ষেত্রে ডেটাসেটের র‍্যান্ডম স্লাইসগুলো নেওয়া এবং সেগুলোকে একসাথে হ্যাস করা জড়িত। আপনার প্রয়োজনীয় ডেটাসেটের নির্দিষ্ট অংশগুলো পুনরায় তৈরি করতে ক্যাশ ব্যবহার করে কম মেমরির মাধ্যমে যাচাইকরণ করা যেতে পারে, তাই আপনার শুধুমাত্র ক্যাশ স্টোর করার প্রয়োজন হয়।

বড় ডেটাসেটটি প্রতি 30000 ব্লকস পর পর একবার আপডেট করা হয়, তাই একজন মাইনারের বেশিরভাগ প্রচেষ্টাই ডেটাসেট পড়ার ক্ষেত্রে ব্যয় হবে, এতে পরিবর্তন করার ক্ষেত্রে নয়।

সংজ্ঞাসমূহ

আমরা নিচের সংজ্ঞাসমূহ ব্যবহার করি:

'SHA3' এর ব্যবহার

ইথিরিয়ামের ডেভেলপমেন্ট SHA3 স্ট্যান্ডার্ডের ডেভেলপমেন্টের সাথে মিলে যায়, এবং স্ট্যান্ডার্ড প্রক্রিয়াটি চূড়ান্ত হ্যাস এ্যালগরিদমের প্যাডিংয়ে একটি বিলম্বিত পরিবর্তন করে, যার ফলে ইথিরিয়ামের "sha3_256" এবং "sha3_512" হ্যাসগুলো স্ট্যান্ডার্ড sha3 হ্যাস নয়, বরং একটি ভ্যারিয়েন্ট যা অন্যান্য ক্ষেত্রে প্রায়শই "Keccak-256" এবং "Keccak-512" হিসেবে উল্লেখ করা হয়। আলোচনা দেখুন, যেমন, এখানে (opens in a new tab), এখানে (opens in a new tab), অথবা এখানে (opens in a new tab)

অনুগ্রহ করে এটি মনে রাখবেন কারণ নিচের এ্যালগরিদমের বর্ণনায় "sha3" হ্যাসগুলো উল্লেখ করা হয়েছে।

প্যারামিটারসমূহ

ইথহ্যাস এর ক্যাশ এবং ডেটাসেটের প্যারামিটারগুলো ব্লক নম্বরের উপর নির্ভর করে। ক্যাশ সাইজ এবং ডেটাসেট সাইজ উভয়ই লিনিয়ারলি বৃদ্ধি পায়; তবে, সাইক্লিক আচরণের দিকে পরিচালিত আকস্মিক নিয়মিততার ঝুঁকি কমানোর জন্য আমরা সর্বদা লিনিয়ারলি ক্রমবর্ধমান থ্রেশহোল্ডের নিচে সর্বোচ্চ প্রাইম (মৌলিক সংখ্যা) নিই।

ডেটাসেট এবং ক্যাশ সাইজ ভ্যালুর টেবিলগুলো পরিশিষ্টে (appendix) দেওয়া হয়েছে।

ক্যাশ জেনারেশন

এখন, আমরা একটি ক্যাশ তৈরি করার ফাংশন নির্দিষ্ট করছি:

ক্যাশ উৎপাদন প্রক্রিয়ায় প্রথমে ক্রমান্বয়ে 32 MB মেমরি পূরণ করা হয়, তারপর Strict Memory Hard Hashing Functions (2014) (opens in a new tab) থেকে Sergio Demian Lerner-এর RandMemoHash এ্যালগরিদমের দুটি পাস সম্পাদন করা হয়। এর আউটপুট হলো 524288 টি 64-বাইট ভ্যালুর একটি সেট।

ডেটা এগ্রিগেশন ফাংশন

আমরা কিছু ক্ষেত্রে XOR-এর নন-অ্যাসোসিয়েটিভ বিকল্প হিসেবে FNV হ্যাস (opens in a new tab) দ্বারা অনুপ্রাণিত একটি এ্যালগরিদম ব্যবহার করি। মনে রাখবেন যে আমরা সম্পূর্ণ 32-বিট ইনপুটের সাথে প্রাইম গুণ করি, যা FNV-1 স্পেকের বিপরীত, যেখানে প্রাইমকে পর্যায়ক্রমে এক বাইট (অকটেট) দিয়ে গুণ করা হয়।

FNV_PRIME = 0x01000193

def fnv(v1, v2):
    return ((v1 * FNV_PRIME) ^ v2) % 2**32

অনুগ্রহ করে মনে রাখবেন, ইয়েলো পেপারেও fnv-কে v1*(FNV_PRIME ^ v2) হিসেবে নির্দিষ্ট করা হয়েছে, তবে বর্তমান সমস্ত ইমপ্লিমেন্টেশন ধারাবাহিকভাবে উপরের সংজ্ঞাটি ব্যবহার করে।

সম্পূর্ণ ডেটাসেট ক্যালকুলেশন

সম্পূর্ণ 1 GB ডেটাসেটের প্রতিটি 64-বাইট আইটেম নিচের মতো করে গণনা করা হয়:

মূলত, আমরা 256 টি সিউডোর‍্যান্ডমভাবে নির্বাচিত ক্যাশ নোড থেকে ডেটা একত্রিত করি এবং ডেটাসেট নোড গণনা করতে সেটিকে হ্যাস করি। সম্পূর্ণ ডেটাসেটটি এরপর নিচের মাধ্যমে তৈরি করা হয়:

def calc_dataset(full_size, cache):
    return [calc_dataset_item(cache, i) for i in range(full_size // HASH_BYTES)]

মেইন লুপ

এখন, আমরা প্রধান "hashimoto"-এর মতো লুপ নির্দিষ্ট করছি, যেখানে আমরা একটি নির্দিষ্ট হেডার এবং নন্স এর জন্য আমাদের চূড়ান্ত ভ্যালু তৈরি করতে সম্পূর্ণ ডেটাসেট থেকে ডেটা একত্রিত করি। নিচের কোডে, header একটি ট্রাংকেটেড ব্লক হেডারের RLP রিপ্রেজেন্টেশনের SHA3-256 হ্যাস উপস্থাপন করে, অর্থাৎ, এমন একটি হেডার যা থেকে mixHash এবং nonce ফিল্ডগুলো বাদ দেওয়া হয়েছে। nonce হলো বিগ-এন্ডিয়ান অর্ডারে একটি 64 বিট আনসাইনড ইন্টিজারের আট বাইট। তাই nonce[::-1] হলো সেই ভ্যালুর আট-বাইট লিটল-এন্ডিয়ান রিপ্রেজেন্টেশন:

মূলত, আমরা 128 বাইট চওড়া একটি "mix" বজায় রাখি, এবং বারবার ক্রমান্বয়ে সম্পূর্ণ ডেটাসেট থেকে 128 বাইট ফেচ করি এবং এটিকে মিক্সের সাথে একত্রিত করতে fnv ফাংশন ব্যবহার করি। 128 বাইটের সিকোয়েন্সিয়াল অ্যাক্সেস ব্যবহার করা হয় যাতে এ্যালগরিদমের প্রতিটি রাউন্ড সর্বদা RAM থেকে একটি সম্পূর্ণ পেজ ফেচ করে, যা ট্রান্সলেশন লুকাসাইড বাফার মিসগুলো কমিয়ে দেয় যা তাত্ত্বিকভাবে ASIC-গুলো এড়াতে সক্ষম হবে।

যদি এই এ্যালগরিদমের আউটপুট কাঙ্ক্ষিত টার্গেটের নিচে হয়, তবে নন্সটি বৈধ। মনে রাখবেন যে শেষে sha3_256-এর অতিরিক্ত প্রয়োগ নিশ্চিত করে যে একটি ইন্টারমিডিয়েট নন্স রয়েছে যা প্রমাণ করতে দেওয়া যেতে পারে যে অন্তত অল্প পরিমাণ কাজ করা হয়েছে; এই দ্রুত আউটার PoW ভেরিফিকেশন অ্যান্টি-DDoS উদ্দেশ্যে ব্যবহার করা যেতে পারে। এটি পরিসংখ্যানগত নিশ্চয়তা প্রদান করতেও কাজ করে যে ফলাফলটি একটি আনবায়াসড, 256-বিট নম্বর।

মাইনিং

মাইনিং এ্যালগরিদমটি নিচের মতো করে সংজ্ঞায়িত করা হয়েছে:

def mine(full_size, dataset, header, difficulty):
    # একই ডিজিটে হ্যাস-এর সাথে তুলনা করতে টার্গেট জিরো-প্যাড করুন
    target = zpad(encode_int(2**256 // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce

সিড হ্যাস সংজ্ঞায়িত করা

একটি প্রদত্ত ব্লকের উপরে মাইন করতে ব্যবহৃত হবে এমন সিড হ্যাস গণনা করার জন্য, আমরা নিচের এ্যালগরিদমটি ব্যবহার করি:

 def get_seedhash(block):
     s = '\x00' * 32
     for i in range(block.number // EPOCH_LENGTH):
         s = serialize_hash(sha3_256(s))
     return s

মনে রাখবেন যে মসৃণ মাইনিং এবং যাচাইকরণের জন্য, আমরা একটি পৃথক থ্রেডে ভবিষ্যতের সিডহ্যাস এবং ডেটাসেটগুলো আগে থেকে গণনা করার পরামর্শ দিই।

আরও পড়ুন

আপনাকে সাহায্য করেছে এমন কোনো কমিউনিটি রিসোর্স সম্পর্কে জানেন? এই পেজটি এডিট করুন এবং এটি যোগ করুন!

পরিশিষ্ট

আপনি যদি উপরের পাইথন স্পেকটি কোড হিসেবে রান করতে আগ্রহী হন তবে নিচের কোডটি আগে যুক্ত করা উচিত।

ডেটা সাইজ

নিচের লুকআপ টেবিলগুলো ডেটা সাইজ এবং ক্যাশ সাইজের প্রায় 2048 টি ট্যাবুলেটেড এপোক প্রদান করে।

পেজ সর্বশেষ আপডেট করা হয়েছে: 15 এপ্রিল, 2026

এই নিবন্ধটি কি সহায়ক ছিল?