Новые операции в 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
С каждым коммитом мир становится лучше!