Last active
January 9, 2018 11:52
-
-
Save nishimura/3fd6af566bb4372a7c7a26dfbf91d69f to your computer and use it in GitHub Desktop.
Search Block Index by PHP5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// needs: PHP5, db4.so | |
// from oracle web site | |
// | |
// php db4blkindex.php <XP_data_directory> [<block hash suffix>] | |
error_reporting(-1); | |
$dbenv = new Db4Env(); | |
$ret = $dbenv->open($argv[1], | |
DB_CREATE | | |
DB_INIT_CDB | | |
DB_INIT_MPOOL, | |
0444); | |
if ($ret === false){ | |
die('dbenv open error'); | |
} | |
$db = new Db4($dbenv); | |
$ret = $db->open(null, 'blkindex.dat', 'main'); | |
$cursor = $db->cursor(); | |
function reverse16($str){ | |
return implode('', array_reverse(str_split($str, 2))); | |
} | |
class uint256 | |
{ | |
private $uint32s; | |
public function __construct($uint32s) | |
{ | |
$this->uint32s = $uint32s; | |
} | |
public function __toString() | |
{ | |
$ret = ''; | |
$len = count($this->uint32s); | |
for ($i = 1; $i < $len; $i++){ | |
$ret .= sprintf('%08x', $this->uint32s['i'.$i]); | |
} | |
return reverse16($ret);; | |
} | |
} | |
// $txkey = bin2hex("\x02tx"); | |
// echo "$txkey\n"; | |
// $blockkey = bin2hex("\nblockindex"); | |
// echo "blockkey: $blockkey\n"; | |
// | |
// $range = pack("N", 0x02780000); | |
// $range = pack("NNN", 0x0a626c6f, 0x636b696e, 0x00); | |
// | |
// echo "range: $range\n"; | |
// echo printf("08x: %08x\n", unpack('Ni1', $range)['i1']); | |
// echo "strlen:" . strlen($range) . "\n"; | |
$i = 0; | |
function strPack($str, $block = null){ | |
$len = strlen($str); | |
$chars = []; | |
$prefix = ''; | |
for ($i = 0; $i < $len; $i++){ | |
$prefix .= sprintf('%02x', ord($str[$i])); | |
} | |
$len = strlen($prefix); | |
$int8s = str_split($prefix, 2); | |
$int32s = []; | |
$blocklen = 0; | |
if ($block !== null){ | |
$block = str16Pack($block); | |
$blocklen = strlen($block); | |
$pad = $blocklen % 8; | |
$block = str_pad($block, $blocklen + (8 - $pad) % 8, '0'); | |
$int32s = str_split($block, 8); | |
} | |
$retlen = $len + $blocklen; | |
$len8 = count($int8s); | |
$len32 = count($int32s); | |
foreach ($int8s as $k => $v) | |
$int8s[$k] = intval($v, 16); | |
foreach ($int32s as $k => $v) | |
$int32s[$k] = intval($v, 16); | |
return [$retlen / 2, | |
pack(str_repeat('C', $len8) . str_repeat('N', $len32), | |
...$int8s, ...$int32s)]; | |
} | |
function str16Pack($str){ | |
$len = strlen($str); | |
$pad = $len % 2; | |
$str = str_pad($str, $len + $pad, '0', STR_PAD_LEFT); | |
$ret = reverse16($str); | |
return $ret; | |
} | |
function startsWith($haystack, $needle){ | |
return (strpos($haystack, $needle) === 0); | |
} | |
$prefix = "\nblockindex"; | |
$block = null; | |
if (isset($argv[2])) | |
$block = $argv[2]; | |
list($len, $prefix) = strPack($prefix, $block); | |
// var_dump(['len' => $len, $prefix]); | |
// $unpack = unpack('C/ni0/N/N/Ni1/Ni2', $prefix); | |
// var_dump(sprintf("08x: %08x %08x %08x\n", | |
// $unpack['i0'], $unpack['i1'], $unpack['i2'])); | |
// var_dump(['uint256' => new uint256(str16Pack($argv[2])) . '']); | |
$key = $prefix; | |
//$key = pack("NNN", 0x0a626c6f, 0x636b696e, 0x64657800); | |
$value = 0; | |
$ret = $cursor->get($key, $value, DB_SET_RANGE); | |
$prefix = substr($prefix, 0, $len); | |
while ($ret == 0){ | |
if (!startsWith($key, $prefix)){ | |
break; | |
} | |
//printf("%d, %d\n", strlen($key), strlen($value)); | |
//printf("%s, %s\n", $key, $value); | |
// uint256: N(32) * 8 | |
// \0x0a blockindex [4 * 8 = 32byte] | |
$uint32s = unpack('n/C/N/N/Ni1/Ni2/Ni3/Ni4/Ni5/Ni6/Ni7/Ni8', $key); | |
$uint256 = new uint256($uint32s); | |
$i++; | |
if ($i % 10000 === 0){ | |
echo "$i."; | |
} | |
$ret = $cursor->get($key, $value, DB_NEXT); | |
// test | |
echo $uint256 . "\n"; | |
if ($i > 3) break; | |
} | |
var_dump(['count' => $i]); | |
$cursor->close(); | |
$db->close(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment