Як згенерувати Proof of Work програмою ZennoPoster

Криптовалюта набирає популярності, а майнінг ETH з алгоритму PoW (Proof of Work) вже давно перейшов на алгоритм Proof of Stake. Проте цікаво розуміти, як саме відбувається процес майнингу, так як інколи може знадобитись згенерувати необхідний хеш. У 2017 приходилось мати справу з монетою XRB де PoW потрібен був для переводу токенів, а у 2021-му – цей алгоритм використовується у P2E ігрі Alien Worlds для збору TLM.

Власне щоб писати код для генерації PoW токенів, потрібно в першу чергу розуміти як це працює. Тому напевне підходити до цього питання було б правильно тоді, коли зрозуміла концепція блокчейн. Але якщо потрібних знаннь немає – також не біда – розберемось.

Значить давайте уявимо, що у нас є якісь дані, які для зручності запису буду зберігати його в форматі json.

{"data":"Якесь повідомлення"}

У будь-який час я можу з цих даних отримати хеш sha256.
Результат буде мати приблизно такий вигляд: 362264c2d3d08e6a6508d314a77d430deed27ae391bf9e4b73f2cf37d18936e5.
Власне це ключове поняття – на вхід у нас є дані, на виході – у нас sha256 хеш.

Є ще таке поняття як складність PoW. Простими словами результатом повинен бути хеш, у якого зліва буде необхідна кількість нулів. Виглядати це може так: 00057100260fc007b281fc7711787731da505d8762849baa36322fed9bfd297. Але, проблема в тому, що з одних одинакових даних завжди буде получатись одинаковий хеш. Тому, потрібно ввести ще таке поняття як блок.

Блок це точно такий json з даними, який буде містити в собі інші додаткові поля. В криптовалюті там буде свій номер, унікальне значення nonce, хеш попереднього блока, а в якості даних там буде список транзакцій. Проте для демонстрації принципу, я обмежусь одним полем nonce з унікальним значенням і полем data з даними.

{"nonce":166495,"data":"Якесь повідомлення"}

Тепер, якщо у мене стоїть задача згенерувати хеш у якого зліва буде чотири нулі 0000, мій алгоритм дій повинен бути таким – устанавлюю nonce в значення 0. Генерую sha256. Перевіряю хеш – якщо те що получилось містить зліва чотири нулі 0000 – значить я знайшов шукане значення. В іншому випадку – збільшую nonce на 1 і знову генерую хеш. Так продовжується до того часу, поки не буде знайдене значення яке задовільняє умову.

Результат: 00000e7efdfda197cfff0f35ac404e5a4778c10b12ccb4974e4cdad0196046a5 – це і буде шукане значення.

PoW sha256

Реалізація алгоритму PoW в C# для програми ZennoPoster буде мати такий вигляд:

long nonce = 0;
string data = "Якесь повідомлення";
string sha256 = string.Empty;
do {
string json = Global.ZennoLab.Json.JsonConvert.SerializeObject(new{ nonce, data });
var sb = new StringBuilder();
using (var hash = System.Security.Cryptography.SHA256Managed.Create()) {
var enc = Encoding.UTF8;
foreach (var b in hash.ComputeHash(enc.GetBytes(json))){
sb.Append(b.ToString("x2"));
}
}
sha256 = sb.ToString();

if(sha256.StartsWith("0000")) project.SendInfoToLog(json, true);
else nonce++;
}
while(!sha256.StartsWith("0000"));
return sha256;

Звичайно, що це спрощений варіант, адже тут перевіряється тільки умова на 0000, а у реальних умовах може бути набагато більше, наприклад у мережі Bitcoin зараз повинно бути приблизно 19 нулів зліва (подивився у блокчейні останній блок – 0000000000000000000 ).

Також я вище писав про те, що дані у мене находяться у json. Проте в залежності від умов, які поставили розробники дані можуть бути і у xml, і у base64, і у вигляді звичайного масиву байт. Тому, у реалізацію в кожному конкретному випадку потрібно вносити поправки.

З іншої сторони – приблизне бачення того, як саме відбувається майнинг (а власне пошук потрібного хеша з накладеними на нього обмеженнями методом підбору nonce і є майнингом або Proof of Work) я думаю мені получилось показати. Навіть код получився робочим, який можна запустити в програмі ZennoPoster, попробувати поміняти дані, поміняти кількість нулів в хеші (щоб зрозуміти наскільки довше шукається хеш при зміні умови). Щоб не вимірювати час вручну – можна скористатись способом вимірювання часу виконання блоків кода в проєкті ZennoPoster, про це писав у цій публікації

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *