mirror of
https://github.com/kvazar-network/crawler.git
synced 2025-01-22 04:45:18 +00:00
implement transaction parser
This commit is contained in:
parent
ee221bb535
commit
ea5c775df3
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,4 @@
|
||||
|
||||
/composer.lock
|
||||
/config.json
|
||||
/.block
|
||||
/.state
|
@ -10,4 +10,5 @@
|
||||
* `cd crawler`
|
||||
* `cp example/config.json config.json`
|
||||
* `crontab -e`:`* * * * * php kvazar/crawler/src/index.php`
|
||||
* drop index: `php kvazar/crawler/src/index.php drop`
|
||||
* drop index: `php kvazar/crawler/src/index.php drop`
|
||||
* optimize index: `php kvazar/crawler/src/index.php optimize`
|
286
src/index.php
286
src/index.php
@ -2,7 +2,7 @@
|
||||
|
||||
// Prevent multi-thread execution
|
||||
$semaphore = sem_get(
|
||||
crc32(__DIR__), 1
|
||||
crc32(__FILE__), 1
|
||||
);
|
||||
|
||||
if (false === sem_acquire($semaphore, true))
|
||||
@ -26,21 +26,21 @@ $config = json_decode(
|
||||
)
|
||||
);
|
||||
|
||||
// Init block
|
||||
$block = 0;
|
||||
// Init current block state
|
||||
$state = 1;
|
||||
|
||||
if (file_exists(__DIR__ . '/../.block'))
|
||||
if (file_exists(__DIR__ . '/../.state'))
|
||||
{
|
||||
$block = (int) file_get_contents(
|
||||
__DIR__ . '/../.block'
|
||||
$state = (int) file_get_contents(
|
||||
__DIR__ . '/../.state'
|
||||
);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
file_put_contents(
|
||||
__DIR__ . '/../.block',
|
||||
$block
|
||||
__DIR__ . '/../.state',
|
||||
$state
|
||||
);
|
||||
}
|
||||
|
||||
@ -115,11 +115,27 @@ if (isset($argv[1]))
|
||||
true
|
||||
);
|
||||
|
||||
file_put_contents(
|
||||
__DIR__ . '/../.state',
|
||||
1
|
||||
);
|
||||
|
||||
exit(
|
||||
_('Index dropped!')
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
// Index optimization request
|
||||
case 'optimize':
|
||||
|
||||
$index->optimize();
|
||||
|
||||
exit(
|
||||
_('Index optimized!')
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,16 +147,262 @@ if (false === $blocks = $kevacoin->getBlockCount())
|
||||
);
|
||||
}
|
||||
|
||||
for ($i = $block; $i <= $blocks; $i++)
|
||||
for ($block = $state; $block <= $blocks; $block++)
|
||||
{
|
||||
// Debug progress
|
||||
echo sprintf(
|
||||
"%d/%d\r",
|
||||
$i,
|
||||
$block,
|
||||
$blocks
|
||||
);
|
||||
|
||||
// Get block hash
|
||||
if (!$hash = $kevacoin->getBlockHash($block))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive "%d" block hash!'),
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Get block data
|
||||
if (!$data = $kevacoin->getBlock($hash))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive "%d" block data by hash "%s"!'),
|
||||
$block,
|
||||
$hash
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($data['tx']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive tx data in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Process each transaction in block
|
||||
foreach ((array) $data['tx'] as $transaction)
|
||||
{
|
||||
// Validate each transaction
|
||||
if (!$raw = $kevacoin->getRawTransaction($transaction))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive raw transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($raw['txid']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive txid of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset($raw['vout']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive vout of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($raw['time']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive time of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($raw['size']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Could not receive size of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Parse transaction data
|
||||
foreach((array) $raw['vout'] as $vout) {
|
||||
|
||||
if (!$vout || empty($vout['scriptPubKey']) || empty($vout['scriptPubKey']['asm']))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Invalid vout transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Parse space-separated fragments to array
|
||||
$asm = explode(
|
||||
' ',
|
||||
$vout['scriptPubKey']['asm']
|
||||
);
|
||||
|
||||
// Get operation ID required to continue
|
||||
if (empty($asm[0]))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Undefined operation of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Detect key / value
|
||||
switch ($asm[0]) {
|
||||
|
||||
case 'OP_KEVA_PUT':
|
||||
|
||||
if (empty($asm[1]) || empty($asm[2]) || empty($asm[3]))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Undefined namespace or key or value of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$namespace = \Kvazar\Crypto\Base58::encode(
|
||||
$asm[1], false, 0, false
|
||||
);
|
||||
|
||||
$key = \Kvazar\Crypto\Kevacoin::decode(
|
||||
$asm[2]
|
||||
);
|
||||
|
||||
$value = \Kvazar\Crypto\Kevacoin::decode(
|
||||
$asm[3]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'OP_KEVA_DELETE':
|
||||
|
||||
if (empty($asm[1]) || empty($asm[2]))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Undefined namespace or key of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$namespace = \Kvazar\Crypto\Base58::encode(
|
||||
$asm[1], false, 0, false
|
||||
);
|
||||
|
||||
$key = \Kvazar\Crypto\Kevacoin::decode(
|
||||
$asm[2]
|
||||
);
|
||||
|
||||
$value = '';
|
||||
|
||||
break;
|
||||
|
||||
case 'OP_KEVA_NAMESPACE':
|
||||
|
||||
if (empty($asm[1]) || empty($asm[2]))
|
||||
{
|
||||
exit(
|
||||
sprintf(
|
||||
_('Undefined namespace or value of transaction "%s" in block "%d"!'),
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$namespace = \Kvazar\Crypto\Base58::encode(
|
||||
$asm[1], false, 0, false
|
||||
);
|
||||
|
||||
$key = '_KEVA_NS_';
|
||||
|
||||
$value = \Kvazar\Crypto\Kevacoin::decode(
|
||||
$asm[2]
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'OP_HASH160': // @TODO not in use at this moment
|
||||
|
||||
/*
|
||||
[0] => OP_HASH160
|
||||
[1] => d03b0c06f8db322a2365e41385f2c8f6f89eebe3
|
||||
[2] => OP_EQUAL
|
||||
*/
|
||||
|
||||
continue 2;
|
||||
|
||||
break;
|
||||
|
||||
case 'OP_RETURN': // @TODO not in use at this moment
|
||||
|
||||
/*
|
||||
[0] => OP_RETURN
|
||||
[1] => aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf9
|
||||
*/
|
||||
|
||||
continue 2;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
exit(
|
||||
sprintf(
|
||||
_('Undefined operation "%s" of transaction "%s" in block "%d"!'),
|
||||
$asm[0],
|
||||
$transaction,
|
||||
$block
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Add index record @TODO
|
||||
}
|
||||
}
|
||||
|
||||
// Update current block indexed
|
||||
file_put_contents(
|
||||
__DIR__ . '/../.block',
|
||||
$i
|
||||
__DIR__ . '/../.state',
|
||||
$block
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user