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

Новые операции в Broadcastи как добавлять новые [php-graphene-node-client v3.0.1]

php-graphene-node-client

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

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

В релизе v3.0.1

  • новые операции бродкаста
    • transfer
    • comment
  • новая структура у operation serializer

Операции в бродкаст и как добавлять новые

В бродкасте php-graphene-node-client реализовано 3 операции

  • vote/flag/downvote
  • transfer
  • comment

Их легко использовать

<?php

use GrapheneNodeClient\Tools\ChainOperations\OpVote;
use GrapheneNodeClient\Tools\ChainOperations\OpTransfer;
use GrapheneNodeClient\Tools\ChainOperations\OpComment;
use GrapheneNodeClient\Tools\Transaction;

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

// пример ответа
//Array
//(
//    [id] => 5
//    [result] => Array
//        (
//            [id] => a2c52988ea870e446480782ff046994de2666e0d
//            [block_num] => 17852337
//            [trx_num] => 1
//            [expired] =>
//        )
//
//)



//тоже самое для transfer
$answer = OpTransfer::doSynchronous( //or OpTransfer::do()
    Transaction::CHAIN_STEEM,
    '5JRaypasxMx1L97ZUX7YuC5Psb5EAbF821kkAGtBj7xCJFQcbLg',
    'guest123',
    'php-node-client',
    '0.010 SBD',
    'test php transfer of SBD'
);


//создание поста/статьи
$answer = OpComment::doSynchronous(
    Transaction::CHAIN_STEEM,
    '5JRaypasxMx1L97ZUX7YuC5Psb5EAbF821kkAGtBj7xCJFQcbLg',
    'guest123',
    strtolower(str_replace(' ', '-', 'Test posting from php client')),
    'Test posting from php client',
    '## h2 ' .
    '<br> details in blog @php-node-client',
    json_encode(['tags' => ['test', 'php']]), //'{"tags":["test","php"]}',
    'test',
    ''
);

Как добавить свою бродкаст операцию

Есть список операций которые могут быть оправлены в блокчейн golos/steem, их можно увидеть тут(steem) и тут(golos).

Например, добавим transfer операцию для steem(для голоса тожесамое), требуется обновить OperationSerializer.php (GrapheneNodeClient\Tools\ChainOperations\OperationSerializer) и добавить новый класс OpTransfer (GrapheneNodeClient\Tools\ChainOperations) чб использовать как шаблон для удобства

OperationSerializer.php

Чб добавить в OperationSerializer.php операцию transfer нужно посмотреть поля и их типы в steem-js тут

let transfer = new Serializer( 
    "transfer", {
    from: string,
    to: string,
    amount: asset,
    memo: string
}
);

Проверяем, что OperationSerializer.php имеет все нужные типы: string и asset. Например, нам нужно добавить тип "asset", тогда мы должны создать новую константу TYPE_ASSET и обновить функцию serializeType добавив обработчик (смотрите детали обработки типа в steem-js тут), как ниже

<?php

namespace GrapheneNodeClient\Tools\ChainOperations;

use t3ran13\ByteBuffer\ByteBuffer;

class OperationSerializer
{

    const TYPE_ASSET  = 'asset';
    ...

    /**
     * @param string     $type
     * @param mixed      $value
     * @param ByteBuffer $byteBuffer
     *
     * @return mixed
     */
    public static function serializeType($type, $value, $byteBuffer)
    {
        ...
        } elseif ($type === self::TYPE_ASSET) {
            list($amount, $symbol) = explode(' ', $value);

            //TODO FIXME have to be writeInt64
            $byteBuffer->writeInt32LE(str_replace('.', '', $amount));
            $byteBuffer->writeInt32LE(0);

            $dot = strpos($amount, '.');
            $precision = $dot === false ? 0 : strlen($amount) - $dot - 1;
            $byteBuffer->writeInt8($precision);

            $byteBuffer->writeVStringLE(strtoupper($symbol));
            for ($i = 0; $i < 7 - strlen($symbol); $i++) {
                $byteBuffer->writeInt8(0);
            }
        }

        return $byteBuffer;
    }

}

После дрбавляем операцию transfer в список

<?php

namespace GrapheneNodeClient\Tools\ChainOperations;

use t3ran13\ByteBuffer\ByteBuffer;

class OperationSerializer
{
    ...

    const OPERATIONS_FIELDS_TYPES = [
        ...
        ChainOperations::OPERATION_TRANSFER => [
            'from'   => self::TYPE_STRING,
            'to'     => self::TYPE_STRING,
            'amount' => self::TYPE_ASSET,
            'memo'   => self::TYPE_STRING
        ]
    ];

}
Добавляем класс OpTransfer как шаблон операции для удобства

Создаем новый файл GrapheneNodeClient\Tools\ChainOperations и называем OpTransfer(Op+Operation_name), см ниже

<?php

namespace GrapheneNodeClient\Tools\ChainOperations;

use GrapheneNodeClient\Commands\Broadcast\BroadcastTransactionCommand;
use GrapheneNodeClient\Commands\Broadcast\BroadcastTransactionSynchronousCommand;
use GrapheneNodeClient\Commands\CommandQueryData;
use GrapheneNodeClient\Connectors\WebSocket\GolosWSConnector;
use GrapheneNodeClient\Connectors\WebSocket\SteemitWSConnector;
use GrapheneNodeClient\Tools\Transaction;

class OpTransfer
{
    /**
     * @param string  $chainName
     * @param string  $from
     * @param string  $privateActiveWif
     * @param string  $to
     * @param string  $amountWithAsset
     * @param string $memo
     *
     * @return mixed
     * @throws \Exception
     */
    public static function do($chainName, $privateActiveWif, $from, $to, $amountWithAsset, $memo)
    {
        /** @var CommandQueryData $tx */
        $tx = Transaction::init($chainName);
        $tx->setParamByKey(
            '0:operations:0',
            [
                'transfer',
                [
                    'from'   => $from,
                    'to'     => $to,
                    'amount' => $amountWithAsset,
                    'memo'   => $memo
                ]
            ]
        );

        if (Transaction::CHAIN_GOLOS === $chainName) {
            $connector = new GolosWSConnector();
        } elseif (Transaction::CHAIN_STEEM === $chainName) {
            $connector = new SteemitWSConnector();
        }
        $command = new BroadcastTransactionCommand($connector);
        Transaction::sign($chainName, $tx, ['active' => $privateActiveWif]);

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

        return $answer;
    }

    /**
     * @param string  $chainName
     * @param string  $from
     * @param string  $privateActiveWif
     * @param string  $to
     * @param string  $amountWithAsset
     * @param string $memo
     *
     * @return mixed
     * @throws \Exception
     */
    public static function doSynchronous($chainName, $privateActiveWif, $from, $to, $amountWithAsset, $memo)
    {
        /** @var CommandQueryData $tx */
        $tx = Transaction::init($chainName);
        $tx->setParamByKey(
            '0:operations:0',
            [
                'transfer',
                [
                    'from'   => $from,
                    'to'     => $to,
                    'amount' => $amountWithAsset,
                    'memo'   => $memo
                ]
            ]
        );

        if (Transaction::CHAIN_GOLOS === $chainName) {
            $connector = new GolosWSConnector();
        } elseif (Transaction::CHAIN_STEEM === $chainName) {
            $connector = new SteemitWSConnector();
        }
        $command = new BroadcastTransactionSynchronousCommand($connector);
        Transaction::sign($chainName, $tx, ['active' => $privateActiveWif]);

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

        return $answer;
    }


}

Теперь смотрите ниже как легко использовать операцию transfer в коде

<?php

...

use GrapheneNodeClient\Tools\ChainOperations\OpTransfer;
use GrapheneNodeClient\Tools\Transaction;

$answer = OpTransfer::doSynchronous( //or OpTransfer::do()
    Transaction::CHAIN_STEEM,
    '5JRaypasxMx1L97ZUX7YuC5Psb5EAbF821kkAGtBj7xCJFQcbLg',
    'guest123',
    'php-node-client',
    '0.010 SBD',
    'test php transfer of SBD'
);

Если добавили новые операции - не забудте селать pull request



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

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

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