diff --git a/composer.json b/composer.json index 464b714..19e7ce3 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "description": "Library for interacting with the Tron blockchain through Tron-Grid", "type": "library", "require": { + "ext-bcmath": "*", "guzzlehttp/guzzle": "^6.3" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 3d174c5..ce80cd4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,62 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fcb5772d169571c50a08df6a7394bb6d", + "content-hash": "032b98fb00877518dfb134815d0bfa06", "packages": [ - { - "name": "doctrine/instantiator", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "^6.2.3", - "squizlabs/php_codesniffer": "^3.0.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2017-07-22T11:58:36+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "6.3.3", @@ -241,6 +187,112 @@ ], "time": "2017-03-20T17:10:46+00:00" }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.8.1", @@ -811,16 +863,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", - "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", + "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", "shasum": "" }, "require": { @@ -856,7 +908,7 @@ "keywords": [ "tokenizer" ], - "time": "2018-02-01T13:16:43+00:00" + "time": "2018-10-30T05:52:18+00:00" }, { "name": "phpunit/phpunit", @@ -942,56 +994,6 @@ ], "time": "2018-10-23T05:57:41+00:00" }, - { - "name": "psr/http-message", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", - "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" - ], - "time": "2016-08-06T14:39:51+00:00" - }, { "name": "sebastian/code-unit-reverse-lookup", "version": "1.0.1", @@ -1646,12 +1648,13 @@ "time": "2018-01-29T19:49:41+00:00" } ], - "packages-dev": [], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, - "platform": [], + "platform": { + "ext-bcmath": "*" + }, "platform-dev": [] } diff --git a/src/Support/Base58.php b/src/Support/Base58.php new file mode 100644 index 0000000..08995a1 --- /dev/null +++ b/src/Support/Base58.php @@ -0,0 +1,21 @@ + 256) { + die("Invalid Base: " . $base); + } + + bcscale(0); + $value = ""; + + if (!$digits) { + $digits = self::digits($base); + } + + while ($dec > $base - 1) { + $rest = bcmod($dec, $base); + $dec = bcdiv($dec, $base); + $value = $digits[$rest] . $value; + } + $value = $digits[intval($dec)] . $value; + + return (string)$value; + } + + public static function base2dec($value, $base, $digits = false) + { + if ($base < 2 || $base > 256) { + die("Invalid Base: " . $base); + } + + bcscale(0); + + if ($base < 37) { + $value = strtolower($value); + } + if (!$digits) { + $digits = self::digits($base); + } + + $size = strlen($value); + $dec = "0"; + + for ($loop = 0; $loop < $size; $loop++) { + $element = strpos($digits, $value[$loop]); + $power = bcpow($base, $size - $loop - 1); + $dec = bcadd($dec, bcmul($element, $power)); + } + + return (string)$dec; + } + + public static function digits($base) + { + if ($base > 64) { + $digits = ""; + for ($loop = 0; $loop < 256; $loop++) { + $digits .= chr($loop); + } + } else { + $digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + $digits .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; + } + $digits = substr($digits, 0, $base); + + return (string)$digits; + } + + public static function bin2bc($num) + { + return self::base2dec($num, 256); + } +} diff --git a/src/Support/Hash.php b/src/Support/Hash.php new file mode 100644 index 0000000..6dcb688 --- /dev/null +++ b/src/Support/Hash.php @@ -0,0 +1,24 @@ +hexString2Address($string); + } + + return $this->hexString2Utf8($string); + } + + /** + * Convert to Hex + * + * @param $str + * @return string + */ + public function toHex($str) + { + if (mb_strlen($str) == 34 && mb_substr($str, 0, 1) === 'T') { + return $this->address2HexString($str); + }; + + return $this->stringUtf8toHex($str); + } + + /** + * Check the address before converting to Hex + * + * @param $sHexAddress + * @return string + */ + public function address2HexString($sHexAddress) + { + if (strlen($sHexAddress) == 42 && mb_strpos($sHexAddress, '41') == 0) { + return $sHexAddress; + } + return Base58Check::decode($sHexAddress, 0, 3); + } + + /** + * Check Hex address before converting to Base58 + * + * @param $sHexString + * @return string + */ + public function hexString2Address($sHexString) + { + if (strlen($sHexString) < 2 || (strlen($sHexString) & 1) != 0) { + return ''; + } + + return Base58Check::encode($sHexString, 0, false); + } + + /** + * Convert string to hex + * + * @param $sUtf8 + * @return string + */ + public function stringUtf8toHex($sUtf8) + { + return bin2hex($sUtf8); + } + + /** + * Convert hex to string + * + * @param $sHexString + * @return string + */ + public function hexString2Utf8($sHexString) + { + return hex2bin($sHexString); + } + + /** + * Convert to great value + * + * @param $str + * @return BigInteger + */ + public function toBigNumber($str) + { + return new BigInteger($str); + } + + /** + * Convert trx to float + * + * @param $amount + * @return float + */ + public function fromTron($amount): float + { + return (float)bcdiv((string)$amount, (string)1e6, 8); + } + + /** + * Convert float to trx format + * + * @param $double + * @return int + */ + public function toTron($double): int + { + return (int)bcmul((string)$double, (string)1e6, 0); + } +} \ No newline at end of file diff --git a/src/Wallet.php b/src/Wallet.php index ecb2a49..983e49b 100644 --- a/src/Wallet.php +++ b/src/Wallet.php @@ -4,6 +4,7 @@ use mattvb91\TronTrx\Exceptions\TransactionException; use mattvb91\TronTrx\Interfaces\WalletInterface; +use mattvb91\TronTrx\Traits\TronAwareTrait; /** * Class Wallet @@ -11,6 +12,8 @@ */ class Wallet implements WalletInterface { + use TronAwareTrait; + private $_api; public function __construct(Api $_api) diff --git a/tests/integration/WalletTest.php b/tests/integration/WalletTest.php index e41338f..e3a437d 100644 --- a/tests/integration/WalletTest.php +++ b/tests/integration/WalletTest.php @@ -44,6 +44,18 @@ public function testGenerateAddress() return $address; } + /** + * @depends testGenerateAddress + */ + public function testSignatureHexSigning(Address $address) + { + $wallet = new mattvb91\TronTrx\Wallet($this->_api); + + $toHex = $wallet->toHex($address->address); + $this->assertEquals($address->hexAddress, $toHex); + $this->assertEquals($address->address, $wallet->hexString2Address($toHex)); + } + /** * @depends testGenerateAddress * @covers \mattvb91\TronTrx\Wallet::validateAddress @@ -148,7 +160,7 @@ public function testBroadcastTransaction(Transaction $transaction) $wallet = new \mattvb91\TronTrx\Wallet($this->_api); $hexAddress = $transaction->raw_data->contract[0]->parameter->value->owner_address; - $address = new Address(hex2bin($hexAddress), '', $hexAddress); + $address = new Address($wallet->fromHex($hexAddress), '', $hexAddress); $beforeTransactionAccunt = $wallet->getAccount($address); $this->assertNotNull($beforeTransactionAccunt);