123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389 |
- <?php
- /**
- * TronAPI
- *
- * @author Shamsudin Serderov <steein.shamsudin@gmail.com>
- * @license https://github.com/iexbase/tron-api/blob/master/LICENSE (MIT License)
- * @version 1.3.4
- * @link https://github.com/iexbase/tron-api
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- declare(strict_types=1);
- namespace IEXBase\TronAPI;
- use Elliptic\EC;
- use IEXBase\TronAPI\Exception\TRC20Exception;
- use IEXBase\TronAPI\Support\Base58;
- use IEXBase\TronAPI\Support\Base58Check;
- use IEXBase\TronAPI\Support\Crypto;
- use IEXBase\TronAPI\Support\Hash;
- use IEXBase\TronAPI\Support\Keccak;
- use IEXBase\TronAPI\Support\Utils;
- use IEXBase\TronAPI\Provider\HttpProviderInterface;
- use IEXBase\TronAPI\Exception\TronException;
- /**
- * A PHP API for interacting with the Tron (TRX)
- *
- * @package TronAPI
- * @author Shamsudin Serderov <steein.shamsudin@gmail.com>
- * @since 1.0.0
- */
- class Tron implements TronInterface
- {
- use TronAwareTrait,
- Concerns\ManagesUniversal,
- Concerns\ManagesTronscan;
- const ADDRESS_SIZE = 34;
- const ADDRESS_PREFIX = "41";
- const ADDRESS_PREFIX_BYTE = 0x41;
- /**
- * Default Address:
- * Example:
- * - base58: T****
- * - hex: 41****
- *
- * @var array
- */
- public $address = [
- 'base58' => null,
- 'hex' => null
- ];
- /**
- * Private key
- *
- * @var string
- */
- protected $privateKey;
- /**
- * Default block
- *
- * @var string|integer|bool
- */
- protected $defaultBlock = 'latest';
- /**
- * Transaction Builder
- *
- * @var TransactionBuilder
- */
- protected $transactionBuilder;
- /**
- * Transaction Builder
- *
- * @var TransactionBuilder
- */
- protected $trc20Contract;
- /**
- * Provider manager
- *
- * @var TronManager
- */
- protected $manager;
- /**
- * Object Result
- *
- * @var bool
- */
- protected $isObject = false;
- /**
- * Create a new Tron object
- *
- * @param HttpProviderInterface $fullNode
- * @param HttpProviderInterface $solidityNode
- * @param HttpProviderInterface|null $eventServer
- * @param HttpProviderInterface|null $signServer
- * @param HttpProviderInterface|null $explorer
- * @param string $privateKey
- * @throws TronException
- */
- public function __construct(?HttpProviderInterface $fullNode = null,
- ?HttpProviderInterface $solidityNode = null,
- ?HttpProviderInterface $eventServer = null,
- ?HttpProviderInterface $signServer = null,
- ?HttpProviderInterface $explorer = null,
- ?string $privateKey = null)
- {
- if(!is_null($privateKey)) {
- $this->setPrivateKey($privateKey);
- }
- $this->setManager(new TronManager($this, [
- 'fullNode' => $fullNode,
- 'solidityNode' => $solidityNode,
- 'eventServer' => $eventServer,
- 'signServer' => $signServer,
- ]));
- $this->transactionBuilder = new TransactionBuilder($this);
- }
- /**
- * Create a new tron instance if the value isn't one already.
- *
- * @param HttpProviderInterface|null $fullNode
- * @param HttpProviderInterface|null $solidityNode
- * @param HttpProviderInterface|null $eventServer
- * @param HttpProviderInterface|null $signServer
- * @param string|null $privateKey
- * @return static
- * @throws TronException
- */
- public static function make(?HttpProviderInterface $fullNode = null,
- ?HttpProviderInterface $solidityNode = null,
- ?HttpProviderInterface $eventServer = null,
- ?HttpProviderInterface $signServer = null,
- string $privateKey = null) {
- return new static($fullNode, $solidityNode, $eventServer, $signServer, $privateKey);
- }
- /**
- * Фасад для Laravel
- *
- * @return Tron
- */
- public function getFacade(): Tron {
- return $this;
- }
- /**
- * Enter the link to the manager nodes
- *
- * @param $providers
- */
- public function setManager($providers) {
- $this->manager = $providers;
- }
- /**
- * Get provider manager
- *
- * @return TronManager
- */
- public function getManager(): TronManager {
- return $this->manager;
- }
- /**
- * Contract module
- *
- * @param string $contractAddress
- * @param string|null $abi
- * @return TRC20Contract
- */
- public function contract(string $contractAddress, string $abi = null)
- {
- return new TRC20Contract($this, $contractAddress, $abi);
- }
- /**
- * Set is object
- *
- * @param bool $value
- * @return Tron
- */
- public function setIsObject(bool $value)
- {
- $this->isObject = boolval($value);
- return $this;
- }
- /**
- * Get Transaction Builder
- *
- * @return TransactionBuilder
- */
- public function getTransactionBuilder(): TransactionBuilder
- {
- return $this->transactionBuilder;
- }
- /**
- * Check connected provider
- *
- * @param $provider
- * @return bool
- */
- public function isValidProvider($provider): bool
- {
- return ($provider instanceof HttpProviderInterface);
- }
- /**
- * Enter the default block
- *
- * @param bool $blockID
- * @return void
- * @throws TronException
- */
- public function setDefaultBlock($blockID = false): void
- {
- if($blockID === false || $blockID == 'latest' || $blockID == 'earliest' || $blockID === 0) {
- $this->defaultBlock = $blockID;
- return;
- }
- if(!is_integer($blockID)) {
- throw new TronException('Invalid block ID provided');
- }
- $this->defaultBlock = abs($blockID);
- }
- /**
- * Get default block
- *
- * @return string|integer|bool
- */
- public function getDefaultBlock()
- {
- return $this->defaultBlock;
- }
- /**
- * Enter your private account key
- *
- * @param string $privateKey
- */
- public function setPrivateKey(string $privateKey): void
- {
- $this->privateKey = $privateKey;
- }
- /**
- * Enter your account address
- *
- * @param string $address
- */
- public function setAddress(string $address): void
- {
- $_toHex = $this->address2HexString($address);
- $_fromHex = $this->hexString2Address($address);
- $this->address = [
- 'hex' => $_toHex,
- 'base58' => $_fromHex
- ];
- }
- /**
- * Get account address
- *
- * @return array
- */
- public function getAddress(): array
- {
- return $this->address;
- }
- /**
- * Get customized provider data
- *
- * @return array
- */
- public function providers(): array
- {
- return $this->manager->getProviders();
- }
- /**
- * Check Connection Providers
- *
- * @return array
- */
- public function isConnected(): array
- {
- return $this->manager->isConnected();
- }
- /**
- * Last block number
- *
- * @return array
- * @throws TronException
- */
- public function getCurrentBlock(): array
- {
- return $this->manager->request('wallet/getnowblock');
- }
- /**
- * Will return all events matching the filters.
- *
- * @param $contractAddress
- * @param int $sinceTimestamp
- * @param string|null $eventName
- * @param int $blockNumber
- * @return array
- * @throws TronException
- */
- public function getEventResult($contractAddress, int $sinceTimestamp = 0, string $eventName = null, int $blockNumber = 0)
- {
- if (!$this->isValidProvider($this->manager->eventServer())) {
- throw new TronException('No event server configured');
- }
- $routeParams = [];
- if($eventName && !$contractAddress) {
- throw new TronException('Usage of event name filtering requires a contract address');
- }
- if($blockNumber && !$eventName)
- throw new TronException('Usage of block number filtering requires an event name');
- if($contractAddress) {
- array_push($routeParams, $contractAddress);
- }
- if($eventName) {
- array_push($routeParams, $eventName);
- }
- if($blockNumber) {
- array_push($routeParams, $blockNumber);
- }
- $routeParams = implode('/', $routeParams);
- return $this->manager->request("event/contract/{$routeParams}?since={$sinceTimestamp}");
- }
- /**
- * Will return all events within a transactionID.
- *
- * @param string $transactionID
- * @return array
- * @throws TronException
- */
- public function getEventByTransactionID(string $transactionID)
- {
- if (!$this->isValidProvider($this->manager->eventServer())) {
- throw new TronException('No event server configured');
- }
- return $this->manager->request("event/transaction/{$transactionID}");
- }
- /**
- * Get block details using HashString or blockNumber
- *
- * @param null $block
- * @return array
- * @throws TronException
- */
- public function getBlock($block = null): array
- {
- $block = (is_null($block) ? $this->defaultBlock : $block);
- if($block === false) {
- throw new TronException('No block identifier provided');
- }
- if($block == 'earliest') {
- $block = 0;
- }
- if($block == 'latest') {
- return $this->getCurrentBlock();
- }
- if(Utils::isHex($block)) {
- return $this->getBlockByHash($block);
- }
- return $this->getBlockByNumber($block);
- }
- /**
- * Query block by ID
- *
- * @param $hashBlock
- * @return array
- * @throws TronException
- */
- public function getBlockByHash(string $hashBlock): array
- {
- return $this->manager->request('wallet/getblockbyid', [
- 'value' => $hashBlock
- ]);
- }
- /**
- * Query block by height
- *
- * @param $blockID
- * @return array
- * @throws TronException
- */
- public function getBlockByNumber(int $blockID): array
- {
- if(!is_integer($blockID) || $blockID < 0) {
- throw new TronException('Invalid block number provided');
- }
- $response = $this->manager->request('wallet/getblockbynum', [
- 'num' => intval($blockID)
- ]);
- if (empty($response)) {
- throw new TronException('Block not found');
- }
- return $response;
- }
- /**
- * Total number of transactions in a block
- *
- * @param $block
- * @return int
- * @throws TronException
- */
- public function getBlockTransactionCount($block): int
- {
- $transaction = $this->getBlock($block)['transactions'];
- if(!$transaction) {
- return 0;
- }
- return count($transaction);
- }
- /**
- * Get transaction details from Block
- *
- * @param null $block
- * @param int $index
- * @return array | string
- * @throws TronException
- */
- public function getTransactionFromBlock($block = null, $index = 0)
- {
- if(!is_integer($index) || $index < 0) {
- throw new TronException('Invalid transaction index provided');
- }
- $transactions = $this->getBlock($block)['transactions'];
- if(!$transactions || count($transactions) < $index) {
- throw new TronException('Transaction not found in block');
- }
- return $transactions[$index];
- }
- /**
- * Query transaction based on id
- *
- * @param $transactionID
- * @return array
- * @throws TronException
- */
- public function getTransaction(string $transactionID): array
- {
- $response = $this->manager->request('wallet/gettransactionbyid', [
- 'value' => $transactionID
- ]);
- if(!$response) {
- throw new TronException('Transaction not found');
- }
- return $response;
- }
- /**
- * Query transaction fee based on id
- *
- * @param $transactionID
- * @return array
- * @throws TronException
- */
- public function getTransactionInfo(string $transactionID): array
- {
- return $this->manager->request('walletsolidity/gettransactioninfobyid', [
- 'value' => $transactionID
- ]);
- }
- /**
- * Query the list of transactions received by an address
- *
- * @param string $address
- * @param int $limit
- * @param int $offset
- * @return array
- * @throws TronException
- */
- public function getTransactionsToAddress(string $address, int $limit = 30, int $offset = 0)
- {
- return $this->getTransactionsRelated($address,'to', $limit, $offset);
- }
- /**
- * Query the list of transactions sent by an address
- *
- * @param string $address
- * @param int $limit
- * @param int $offset
- * @return array
- * @throws TronException
- */
- public function getTransactionsFromAddress(string $address, int $limit = 30, int $offset = 0)
- {
- return $this->getTransactionsRelated($address,'from', $limit, $offset);
- }
- /**
- * Query information about an account
- *
- * @param $address
- * @return array
- * @throws TronException
- */
- public function getAccount(string $address = null): array
- {
- $address = (!is_null($address) ? $this->toHex($address) : $this->address['hex']);
- return $this->manager->request('walletsolidity/getaccount', [
- 'address' => $address
- ]);
- }
- /**
- * Getting a balance
- *
- * @param string $address
- * @param bool $fromTron
- * @return float
- * @throws TronException
- */
- public function getBalance(string $address = null, bool $fromTron = false): float
- {
- $account = $this->getAccount($address);
- if(!array_key_exists('balance', $account)) {
- return 0;
- }
- return ($fromTron == true ?
- $this->fromTron($account['balance']) :
- $account['balance']);
- }
- /**
- * Get token balance
- *
- * @param string $address
- * @param int $tokenId
- * @param bool $fromTron
- * @return array|int
- * @throws TronException
- */
- public function getTokenBalance(int $tokenId, string $address, bool $fromTron = false)
- {
- $account = $this->getAccount($address);
- if(isset($account['assetV2']) and !empty($account['assetV2']) )
- {
- $value = array_filter($account['assetV2'], function($item) use ($tokenId) {
- return $item['key'] == $tokenId;
- });
- if(empty($value)) {
- throw new TronException('Token id not found');
- }
- $first = array_shift($value);
- return ($fromTron == true ? $this->fromTron($first['value']) : $first['value']);
- }
- return 0;
- }
- /**
- * Query bandwidth information.
- *
- * @param $address
- * @return array
- * @throws TronException
- */
- public function getBandwidth(string $address = null)
- {
- $address = (!is_null($address) ? $this->toHex($address) : $this->address['hex']);
- return $this->manager->request('wallet/getaccountnet', [
- 'address' => $address
- ]);
- }
- /**
- * Getting data in the "from","to" directions
- *
- * @param string $address
- * @param string $direction
- * @param int $limit
- * @param int $offset
- * @return array
- * @throws TronException
- */
- public function getTransactionsRelated(string $address, string $direction = 'to', int $limit = 30, int $offset = 0)
- {
- if(!in_array($direction, ['to', 'from'])) {
- throw new TronException('Invalid direction provided: Expected "to", "from"');
- }
- if(!is_integer($limit) || $limit < 0 || ($offset && $limit < 1)) {
- throw new TronException('Invalid limit provided');
- }
- if(!is_integer($offset) || $offset < 0) {
- throw new TronException('Invalid offset provided');
- }
- $response = $this->manager->request(sprintf('walletextension/gettransactions%sthis', $direction), [
- 'account' => ['address' => $this->toHex($address)],
- 'limit' => $limit,
- 'offset' => $offset
- ]);
- return array_merge($response, ['direction' => $direction]);
- }
- /**
- * Count all transactions on the network
- *
- * @return integer
- * @throws TronException
- */
- public function getTransactionCount(): int
- {
- $response = $this->manager->request('wallet/totaltransaction');
- return $response['num'];
- }
- /**
- * Send transaction to Blockchain
- *
- * @param string $to
- * @param float $amount
- * @param string|null $message
- * @param string $from
- *
- * @return array
- * @throws TronException
- */
- public function sendTransaction(string $to, float $amount, string $message= null, string $from = null): array
- {
- if (is_null($from)) {
- $from = $this->address['hex'];
- }
- $transaction = $this->transactionBuilder->sendTrx($to, $amount, $from);
- $signedTransaction = $this->signTransaction($transaction, $message);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Send token transaction to Blockchain
- *
- * @param string $to
- * @param float $amount
- * @param int $tokenID
- * @param string $from
- *
- * @return array
- * @throws TronException
- */
- public function sendTokenTransaction(string $to, float $amount, int $tokenID = null, string $from = null): array
- {
- if (is_null($from)) {
- $from = $this->address['hex'];
- }
- $transaction = $this->transactionBuilder->sendToken($to, $this->toTron($amount), (string)$tokenID, $from);
- $signedTransaction = $this->signTransaction($transaction);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Sign the transaction, the api has the risk of leaking the private key,
- * please make sure to call the api in a secure environment
- *
- * @param $transaction
- * @param string|null $message
- * @return array
- * @throws TronException
- */
- public function signTransaction($transaction, string $message = null): array
- {
- if(!$this->privateKey) {
- throw new TronException('Missing private key');
- }
- if(!is_array($transaction)) {
- throw new TronException('Invalid transaction provided');
- }
- if(isset($transaction['Error']))
- throw new TronException($transaction['Error']);
- if(isset($transaction['signature'])) {
- throw new TronException('Transaction is already signed');
- }
- if(!is_null($message)) {
- $transaction['raw_data']['data'] = $this->stringUtf8toHex($message);
- }
- $signature = Support\Secp::sign($transaction['txID'], $this->privateKey);
- $transaction['signature'] = [$signature];
- return $transaction;
- }
- /**
- * Broadcast the signed transaction
- *
- * @param $signedTransaction
- * @return array
- * @throws TronException
- */
- public function sendRawTransaction($signedTransaction): array
- {
- if(!is_array($signedTransaction)) {
- throw new TronException('Invalid transaction provided');
- }
- if(!array_key_exists('signature', $signedTransaction) || !is_array($signedTransaction['signature'])) {
- throw new TronException('Transaction is not signed');
- }
- return $this->manager->request('wallet/broadcasttransaction',
- $signedTransaction);
- }
- /**
- * Modify account name
- * Note: Username is allowed to edit only once.
- *
- * @param $address
- * @param $account_name
- * @return array
- * @throws TronException
- */
- public function changeAccountName(string $address = null, string $account_name)
- {
- $address = (!is_null($address) ? $address : $this->address['hex']);
- $transaction = $this->manager->request('wallet/updateaccount', [
- 'account_name' => $this->stringUtf8toHex($account_name),
- 'owner_address' => $this->toHex($address)
- ]);
- $signedTransaction = $this->signTransaction($transaction);
- $response = $this->sendRawTransaction($signedTransaction);
- return $response;
- }
- /**
- * Send funds to the Tron account (option 2)
- *
- * @param array $args
- * @return array
- * @throws TronException
- */
- public function send(...$args): array {
- return $this->sendTransaction(...$args);
- }
- /**
- * Send funds to the Tron account (option 3)
- *
- * @param array $args
- * @return array
- * @throws TronException
- */
- public function sendTrx(...$args): array {
- return $this->sendTransaction(...$args);
- }
- /**
- * Creating a new token based on Tron
- *
- * @param array token {
- * "owner_address": "41e552f6487585c2b58bc2c9bb4492bc1f17132cd0",
- * "name": "0x6173736574497373756531353330383934333132313538",
- * "abbr": "0x6162627231353330383934333132313538",
- * "total_supply": 4321,
- * "trx_num": 1,
- * "num": 1,
- * "start_time": 1530894315158,
- * "end_time": 1533894312158,
- * "description": "007570646174654e616d6531353330363038383733343633",
- * "url": "007570646174654e616d6531353330363038383733343633",
- * "free_asset_net_limit": 10000,
- * "public_free_asset_net_limit": 10000,
- * "frozen_supply": { "frozen_amount": 1, "frozen_days": 2 }
- *
- * @return array
- * @throws TronException
- */
- public function createToken($token = [])
- {
- return $this->manager->request('wallet/createassetissue', [
- 'owner_address' => $this->toHex($token['owner_address']),
- 'name' => $this->stringUtf8toHex($token['name']),
- 'abbr' => $this->stringUtf8toHex($token['abbr']),
- 'description' => $this->stringUtf8toHex($token['description']),
- 'url' => $this->stringUtf8toHex($token['url']),
- 'total_supply' => $token['total_supply'],
- 'trx_num' => $token['trx_num'],
- 'num' => $token['num'],
- 'start_time' => $token['start_time'],
- 'end_time' => $token['end_time'],
- 'free_asset_net_limit' => $token['free_asset_net_limit'],
- 'public_free_asset_net_limit' => $token['public_free_asset_net_limit'],
- 'frozen_supply' => $token['frozen_supply']
- ]);
- }
- /**
- * Create an account.
- * Uses an already activated account to create a new account
- *
- * @param $address
- * @param $newAccountAddress
- * @return array
- * @throws TronException
- */
- public function registerAccount(string $address, string $newAccountAddress): array
- {
- return $this->manager->request('wallet/createaccount', [
- 'owner_address' => $this->toHex($address),
- 'account_address' => $this->toHex($newAccountAddress)
- ]);
- }
- /**
- * Apply to become a super representative
- *
- * @param $address
- * @param $url
- * @return array
- * @throws TronException
- */
- public function applyForSuperRepresentative(string $address, string $url)
- {
- return $this->manager->request('wallet/createwitness', [
- 'owner_address' => $this->toHex($address),
- 'url' => $this->stringUtf8toHex($url)
- ]);
- }
- /**
- * Transfer Token
- *
- * @param $to
- * @param $amount
- * @param $tokenID
- * @param $from
- * @return array
- * @throws TronException
- */
- public function sendToken(string $to, int $amount, string $tokenID, string $from = null)
- {
- if($from == null) {
- $from = $this->address['hex'];
- }
- $transfer = $this->transactionBuilder->sendToken($to, $amount, $tokenID, $from);
- $signedTransaction = $this->signTransaction($transfer);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Purchase a Token
- * @param $issuerAddress
- * @param $tokenID
- * @param $amount
- * @param null $buyer
- * @return array
- * @throws TronException
- */
- public function purchaseToken($issuerAddress, $tokenID, $amount, $buyer = null)
- {
- if($buyer == null) {
- $buyer = $this->address['hex'];
- }
- $purchase = $this->transactionBuilder->purchaseToken($issuerAddress, $tokenID, $amount, $buyer);
- $signedTransaction = $this->signTransaction($purchase);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Freezes an amount of TRX.
- * Will give bandwidth OR Energy and TRON Power(voting rights) to the owner of the frozen tokens.
- *
- * @param float $amount
- * @param int $duration
- * @param string $resource
- * @param string $owner_address
- * @return array
- * @throws TronException
- */
- public function freezeBalance(float $amount = 0, int $duration = 3, string $resource = 'BANDWIDTH', string $owner_address = null)
- {
- if($owner_address == null) {
- $owner_address = $this->address['hex'];
- }
- $freeze = $this->transactionBuilder->freezeBalance($amount, $duration, $resource, $owner_address);
- $signedTransaction = $this->signTransaction($freeze);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Unfreeze TRX that has passed the minimum freeze duration.
- * Unfreezing will remove bandwidth and TRON Power.
- *
- * @param string $resource
- * @param string $owner_address
- * @return array
- * @throws TronException
- */
- public function unfreezeBalance(string $resource = 'BANDWIDTH', string $owner_address = null)
- {
- if($owner_address == null) {
- $owner_address = $this->address['hex'];
- }
- $unfreeze = $this->transactionBuilder->unfreezeBalance($resource, $owner_address);
- $signedTransaction = $this->signTransaction($unfreeze);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Withdraw Super Representative rewards, useable every 24 hours.
- *
- * @param string $owner_address
- * @return array
- * @throws TronException
- */
- public function withdrawBlockRewards(string $owner_address = null)
- {
- if($owner_address == null) {
- $owner_address = $this->address['hex'];
- }
- $withdraw = $this->transactionBuilder->withdrawBlockRewards($owner_address);
- $signedTransaction = $this->signTransaction($withdraw);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Update a Token's information
- *
- * @param string $description
- * @param string $url
- * @param int $freeBandwidth
- * @param int $freeBandwidthLimit
- * @param $owner_address
- * @return array
- * @throws TronException
- */
- public function updateToken(string $description,
- string $url,
- int $freeBandwidth = 0,
- int $freeBandwidthLimit = 0,
- string $owner_address = null)
- {
- if($owner_address == null) {
- $owner_address = $this->address['hex'];
- }
- $withdraw = $this->transactionBuilder->updateToken($description, $url, $freeBandwidth, $freeBandwidthLimit, $owner_address);
- $signedTransaction = $this->signTransaction($withdraw);
- $response = $this->sendRawTransaction($signedTransaction);
- return array_merge($response, $signedTransaction);
- }
- /**
- * Node list
- *
- * @return array
- * @throws TronException
- */
- public function listNodes(): array
- {
- $nodes = $this->manager->request('wallet/listnodes');
- return array_map(function($item) {
- $address = $item['address'];
- return sprintf('%s:%s', $this->toUtf8($address['host']), $address['port']);
- }, $nodes['nodes']);
- }
- /**
- * List the tokens issued by an account.
- *
- * @param string $address
- * @return array
- * @throws TronException
- */
- public function getTokensIssuedByAddress(string $address = null)
- {
- $address = (!is_null($address) ? $this->toHex($address) : $this->address['hex']);
- return $this->manager->request('wallet/getassetissuebyaccount',[
- 'address' => $address
- ]);
- }
- /**
- * Query token by name.
- *
- * @param $tokenID
- * @return array
- * @throws TronException
- */
- public function getTokenFromID($tokenID = null)
- {
- return $this->manager->request('wallet/getassetissuebyname', [
- 'value' => $this->stringUtf8toHex($tokenID)
- ]);
- }
- /**
- * Query a range of blocks by block height
- *
- * @param int $start
- * @param int $end
- * @return array
- * @throws TronException
- */
- public function getBlockRange(int $start = 0, int $end = 30)
- {
- if(!is_integer($start) || $start < 0) {
- throw new TronException('Invalid start of range provided');
- }
- if(!is_integer($end) || $end <= $start) {
- throw new TronException('Invalid end of range provided');
- }
- return $this->manager->request('wallet/getblockbylimitnext', [
- 'startNum' => intval($start),
- 'endNum' => intval($end) + 1
- ])['block'];
- }
- /**
- * Query the latest blocks
- *
- * @param int $limit
- * @return array
- * @throws TronException
- */
- public function getLatestBlocks(int $limit = 1): array
- {
- if(!is_integer($limit) || $limit <= 0) {
- throw new TronException('Invalid limit provided');
- }
- return $this->manager->request('wallet/getblockbylatestnum', [
- 'num' => $limit
- ])['block'];
- }
- /**
- * Query the list of Super Representatives
- *
- * @return array
- * @throws TronException
- */
- public function listSuperRepresentatives(): array
- {
- return $this->manager->request('wallet/listwitnesses')['witnesses'];
- }
- /**
- * Query the list of Tokens with pagination
- *
- * @param int $limit
- * @param int $offset
- * @return array
- * @throws TronException
- */
- public function listTokens(int $limit = 0, int $offset = 0)
- {
- if(!is_integer($limit) || $limit < 0 || ($offset && $limit < 1)) {
- throw new TronException('Invalid limit provided');
- }
- if(!is_integer($offset) || $offset < 0) {
- throw new TronException('Invalid offset provided');
- }
- if(!$limit) {
- return $this->manager->request('wallet/getassetissuelist')['assetIssue'];
- }
- return $this->manager->request('wallet/getpaginatedassetissuelist', [
- 'offset' => intval($offset),
- 'limit' => intval($limit)
- ])['assetIssue'];
- }
- /**
- * Get the time of the next Super Representative vote
- *
- * @return float
- * @throws TronException
- */
- public function timeUntilNextVoteCycle(): float
- {
- $num = $this->manager->request('wallet/getnextmaintenancetime')['num'];
- if($num == -1) {
- throw new TronException('Failed to get time until next vote cycle');
- }
- return floor($num / 1000);
- }
- /**
- * Validate address
- *
- * @param string $address
- * @param bool $hex
- * @return array
- * @throws TronException
- */
- public function validateAddress(string $address = null, bool $hex = false): array
- {
- $address = (!is_null($address) ? $address : $this->address['hex']);
- if($hex) {
- $address = $this->toHex($address);
- }
- return $this->manager->request('wallet/validateaddress', [
- 'address' => $address
- ]);
- }
- /**
- * Validate Tron Address (Locale)
- *
- * @param string|null $address
- * @return bool
- */
- public function isAddress(string $address = null): bool
- {
- if(strlen($address) !== self::ADDRESS_SIZE)
- return false;
- $address = Base58Check::decode($address, 0, 0, false);
- $utf8 = hex2bin($address);
- if(strlen($utf8) !== 25) return false;
- if(strpos($utf8 , chr(self::ADDRESS_PREFIX_BYTE)) !== 0) return false;
- $checkSum = substr($utf8, 21);
- $address = substr($utf8, 0, 21);
- $hash0 = Hash::SHA256($address);
- $hash1 = Hash::SHA256($hash0);
- $checkSum1 = substr($hash1, 0, 4);
- if ($checkSum === $checkSum1)
- return true;
- return false;
- }
- /**
- * Deploys a contract
- *
- * @param $abi
- * @param $bytecode
- * @param $feeLimit
- * @param $address
- * @param int $callValue
- * @param int $bandwidthLimit
- * @return array
- * @throws TronException
- */
- public function deployContract($abi, $bytecode, $feeLimit, $address, $callValue = 0, $bandwidthLimit = 0)
- {
- $payable = array_filter(json_decode($abi, true), function($v)
- {
- if($v['type'] == 'constructor' && $v['payable']) {
- return $v['payable'];
- }
- return null;
- });
- if($feeLimit > 1000000000) {
- throw new TronException('fee_limit must not be greater than 1000000000');
- }
- if($payable && $callValue == 0) {
- throw new TronException('call_value must be greater than 0 if contract is type payable');
- }
- if(!$payable && $callValue > 0) {
- throw new TronException('call_value can only equal to 0 if contract type isn‘t payable');
- }
- return $this->manager->request('wallet/deploycontract', [
- 'owner_address' => $this->toHex($address),
- 'fee_limit' => $feeLimit,
- 'call_value' => $callValue,
- 'consume_user_resource_percent' => $bandwidthLimit,
- 'abi' => $abi,
- 'bytecode' => $bytecode
- ]);
- }
- /**
- * Get a list of exchanges
- *
- * @return array
- * @throws TronException
- */
- public function listExchanges()
- {
- return $this->manager->request('/wallet/listexchanges', []);
- }
- /**
- * Query the resource information of the account
- *
- * @param string $address
- * @return array
- * @throws TronException
- */
- public function getAccountResources(string $address = null)
- {
- $address = (!is_null($address) ? $address : $this->address['hex']);
- return $this->manager->request('/wallet/getaccountresource', [
- 'address' => $this->toHex($address)
- ]);
- }
- /**
- * Create a new account
- *
- * @return TronAddress
- * @throws TronException
- */
- public function createAccount(): TronAddress
- {
- return $this->generateAddress();
- }
- public function getAddressHex(string $pubKeyBin): string
- {
- if (strlen($pubKeyBin) == 65) {
- $pubKeyBin = substr($pubKeyBin, 1);
- }
- $hash = Keccak::hash($pubKeyBin, 256);
- return self::ADDRESS_PREFIX . substr($hash, 24);
- }
- public function getBase58CheckAddress(string $addressBin): string
- {
- $hash0 = Hash::SHA256($addressBin);
- $hash1 = Hash::SHA256($hash0);
- $checksum = substr($hash1, 0, 4);
- $checksum = $addressBin . $checksum;
- return Base58::encode(Crypto::bin2bc($checksum));
- }
- /**
- * Generate new address
- *
- * @return TronAddress
- * @throws TronException
- */
- public function generateAddress(): TronAddress
- {
- $ec = new EC('secp256k1');
- // Generate keys
- $key = $ec->genKeyPair();
- $priv = $ec->keyFromPrivate($key->priv);
- $pubKeyHex = $priv->getPublic(false, "hex");
- $pubKeyBin = hex2bin($pubKeyHex);
- $addressHex = $this->getAddressHex($pubKeyBin);
- $addressBin = hex2bin($addressHex);
- $addressBase58 = $this->getBase58CheckAddress($addressBin);
- return new TronAddress([
- 'private_key' => $priv->getPrivate('hex'),
- 'public_key' => $pubKeyHex,
- 'address_hex' => $addressHex,
- 'address_base58' => $addressBase58
- ]);
- }
- /**
- * Helper function that will convert HEX to UTF8
- *
- * @param $str
- * @return string
- */
- public function toUtf8($str): string {
- return pack('H*', $str);
- }
- /**
- * Query token by id.
- *
- * @param string $token_id
- * @return array
- * @throws TronException
- */
- public function getTokenByID(string $token_id): array
- {
- if(!is_string($token_id))
- throw new TronException('Invalid token ID provided');
- return $this->manager->request('/wallet/getassetissuebyid', [
- 'value' => $token_id
- ]);
- }
- }
|