Php
如何使這個 PHP merkle 根腳本遞歸?
我一直在嘗試用 PHP 編寫我自己的 merkle root 腳本來幫助我自己理解,但我一直在為遞歸而苦苦掙扎。
我已經設法編寫了將散列成對 TXID 的函式,但我不知道如何讓它繼續呼叫自己,以便最終在數組中只剩下一個散列。
<http://pastebin.com/1C6sSbeE>
你的腳本是一個很好的嘗試!我修改了一些非常小的更改使其遞歸。
通常在設計遞歸函式時,它會檢查狀態是否代表一個完整的計算,否則它會執行一些程式碼並再次呼叫自己。您的功能缺少這部分。
它似乎也錯誤地計算了散列 - 散列操作是
SHA256(SHA256($pair))
. 我重構了函式binFlipByteOrder()
,它只適用於二進制,所以我們可以在將其渲染為十六進制之前翻轉雜湊。<?php function binFlipByteOrder($string) { return implode('', array_reverse(str_split($string, 1))); } function merkleroot($txids) { // Check for when the result is ready, otherwise recursion if (count($txids) === 1) { return $txids[0]; } // Calculate the next row of hashes $pairhashes = []; while (count($txids) > 0) { if (count($txids) >= 2) { // Get first two $pair_first = $txids[0]; $pair_second = $txids[1]; // Hash them $pair = $pair_first.$pair_second; $pairhashes[] = hash('sha256', hash('sha256', $pair, true), true); // Remove those two from the array unset($txids[0]); unset($txids[1]); // Re-set the indexes (the above just nullifies the values) and make a new array without the original first two slots. $txids = array_values($txids); } if (count($txids) == 1) { // Get the first one twice $pair_first = $txids[0]; $pair_second = $txids[0]; // Hash it with itself $pair = $pair_first.$pair_second; $pairhashes[] = hash('sha256', hash('sha256', $pair, true), true); // Remove it from the array unset($txids[0]); // Re-set the indexes (the above just nullifies the values) and make a new array without the original first two slots. $txids = array_values($txids); } } return merkleroot($pairhashes); } $txids = array( 'AB7ED423933FE5413DC51B1041A58FD8AF0CD70491B1CE607CB41DDDCE74A92B', 'C763E59A79C9F1E626DDF1C3E9F20F234959C457FF82918F7B24E9D18A12DB99', '80EA3E647AEEF92973F5414E0CAA1721C7B42345B99ED161DD505ACC41F5516B', '1B72EEFD70CE0A362EC0CB48E2213274DF3C55F9DABD5806CDC087A335498CD3', '23E13370F6D59E2D7C7A9CA604B872312DE34A387BD7DECA2C8F4486F7E66173', '149A098D6261B7F9359A572D797C4A41B62378836A14093912618B15644BA402', ); $txidsBEbinary = []; foreach ($txids as $txidBE) { // covert to binary, then flip $txidsBEbinary[] = binFlipByteOrder(hex2bin($txidBE)); } $root = merkleroot($txidsBEbinary); echo bin2hex(binFlipByteOrder($root)) . PHP_EOL;