Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
php-node-client
6 лет назад

Обход бага spec256k1-php с помощью PHP-хака и другое[php-graphene-node-client v3.1.0]

php-graphene-node-client

Это PHP API клиент для Steem/GOLOS блокчейнов

Код доступен на Github или packagist под MIT лицензией. Автор @t3ran13, активный помочник @semasping

В релизе v3.1.0

  • spec256k1-php обход "бага"
  • обновлен Transaction:init()
  • обновлены классы операций brodcast Op*.php
  • обновлен readme

spec256k1-php обход "бага"

Транзакции подписываются spec256k1-php функцией secp256k1_ecdsa_sign_recoverable($context, $signatureRec, $msg32, $privateKey) и если подпись не каноничная с первого раза, вы должны создать транзакцию для другого блока. Для поиска канонической подписи функция должна поддерживать еще два параметра, но они не реализованы в либе spec256k1-php.

Проблема каноничности подписей (в либе остуствуют 2 параметра через которые можно добиваться каноничности) решена PHP-хаком Transaction::sign() - к expiration времени транзакции мы добавляем по 1 секунде каждый раз когда не получаем каноничности в подписи и пытаемся подписать все заново. СТоит ограничение до 200 попыток.

...
// если подпись не каноничная,мы должны изменить сообщение и попытаться подписать снова, 
// для этого в один из параметров транзакции - время истечения - увеличиваем на 1 секунду
$nTries = 0;
while (true) {
    $nTries++;
    $msg = self::getTxMsg($chainName, $trxData);
    echo '<pre>' . print_r($trxData->getParams(), true) . '<pre>'; //FIXME delete it

    try {
        foreach ($privateWIFs as $keyName => $privateWif) {
            $index = count($trxData->getParams()[0]['signatures']);

            /** @var CommandQueryData $trxData */
            $trxData->setParamByKey('0:signatures:' . $index, self::signOperation($msg, $privateWif));
        }
        break;
    } catch (TransactionSignException $e) {
        if ($nTries > 200) {
            //stop tries to find canonical sign
            throw $e;
            break;
        } else {
            /** @var CommandQueryData $trxData */
            $params = $trxData->getParams();
            foreach ($params as $key => $tx) {
                $tx['expiration'] = (new \DateTime($tx['expiration']))
                    ->add(new \DateInterval('PT0M1S'))
                    ->format('Y-m-d\TH:i:s\.000');
                $params[$key] = $tx;
            }
            $trxData->setParams($params);
        }
    }
...

Transaction:init()

Теперь мы должны передовать connector(он должен включать ConnectorInterface) вместо параметра ChainName в функцию как в примере ниже

<?php

use GrapheneNodeClient\Tools\Transaction;
use GrapheneNodeClient\Connectors\Http\SteemitHttpConnector;
use GrapheneNodeClient\Connectors\WebSocket\GolosWSConnector;

$connector = new SteemitHttpConnector();
//$connector = new GolosWSConnector();

/** @var CommandQueryData $tx */
$tx = Transaction::init($connector);
$tx->setParamByKey(
    '0:operations:0',
    [
        'vote',
        [
            'voter'    => $voter,
            'author'   => $author,
            'permlink' => $permlink,
            'weight'   => $weight
        ]
    ]
);

$command = new BroadcastTransactionSynchronousCommand($connector);
Transaction::sign($chainName, $tx, ['posting' => $publicWif]);

$answer = $command->execute(
    $tx
);

классы операций brodcast Op*.php

Теперь мы должны передовать connector(он должен включать ConnectorInterface) вместо параметра ChainName в функцию как в примере ниже

<?php

use GrapheneNodeClient\Tools\ChainOperations\OpVote;
use GrapheneNodeClient\Connectors\Http\SteemitHttpConnector;
use GrapheneNodeClient\Connectors\WebSocket\GolosWSConnector;

$connector = new SteemitHttpConnector();
//$connector = new GolosWSConnector();

$answer = OpVote::doSynchronous(
    $connector,
    'guest123',
    '5JRaypasxMx1L97ZUX7YuC5Psb5EAbF821kkAGtBj7xCJFQcbLg',
    'firepower',
    'steemit-veni-vidi-vici-steemfest-2016-together-we-made-it-happen-thank-you-steemians',
    10000
);

// example of answer
//Array
//(
//    [id] => 5
//    [result] => Array
//        (
//            [id] => a2c52988ea870e446480782ff046994de2666e0d
//            [block_num] => 17852337
//            [trx_num] => 1
//            [expired] =>
//        )
//
//)


Код доступен на Github или packagist под MIT лицензией. Автор @t3ran13, активный помочник @semasping

С каждым коммитом мир становится лучше!

7
0.269 GOLOS
На Golos с March 2017
Комментарии (3)
Сортировать по:
Сначала старые