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

ইথহ্যাশ

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

ইথহ্যাশ হলো 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" হ্যাশগুলো উল্লেখ করা হয়েছে।

প্যারামিটার

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

ডেটাসেট এবং ক্যাশে আকারের মানগুলোর টেবিল পরিশিষ্টে দেওয়া হয়েছে।

ক্যাশে তৈরি

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

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

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

আমরা কিছু ক্ষেত্রে XOR-এর নন-অ্যাসোসিয়েটিভ বিকল্প হিসেবে FNV hash (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 একটি কাটা (truncated) ব্লক হেডারের 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

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

আরও পড়ুন

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

পরিশিষ্ট

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

ডেটার আকার

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