Php

如何使這個 PHP merkle 根腳本遞歸?

  • April 1, 2016

我一直在嘗試用 PHP 編寫我自己的 merkle root 腳本來幫助我自己理解,但我一直在為遞歸而苦苦掙扎。

我已經設法編寫了將散列成對 TXID 的函式,但我不知道如何讓它繼續呼叫自己,以便最終在數組中只剩下一個散列。

<http://pastebin.com/1C6sSbeE>

你的腳本是一個很好的嘗試!我修改了一些非常小的更改使其遞歸。

通常在設計遞歸函式時,它會檢查狀態是否代表一個完整的計算,否則它會執行一些程式碼並再次呼叫自己。您的功能缺少這部分。

它似乎也錯誤地計算了散列 - 散列操作是SHA256(SHA256($pair)). 我重構了函式binFlipByteOrder(),它只適用於二進制,所以我們可以在將其渲染為十六進制之前翻轉雜湊。

&lt;?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) &gt; 0) {
       if (count($txids) &gt;= 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;

引用自:https://bitcoin.stackexchange.com/questions/43565