From 50cfe64a23938fd9112240dbab52697a5990dc73 Mon Sep 17 00:00:00 2001 From: sergeyzhuk Date: Mon, 20 Oct 2025 21:05:41 +0300 Subject: [PATCH] feat: use BigInteger --- composer.json | 1 + src/Module/Accounts/Accounts.php | 3 ++- .../Accounts/Model/NormalTransaction.php | 4 +++- .../Proxy/Model/TransactionByHashInfo.php | 4 +++- src/Module/Proxy/Model/TransactionReceipt.php | 4 +++- .../Proxy/Model/TransactionReceiptLog.php | 4 +++- src/Module/Proxy/Proxy.php | 23 ++++++++++--------- tests/Module/AccountsTest.php | 5 ++-- tests/Module/ProxyTest.php | 17 +++++++------- 9 files changed, 39 insertions(+), 26 deletions(-) diff --git a/composer.json b/composer.json index 1353ccc..288726c 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,7 @@ "php-http/discovery": "^1.0", "php-http/guzzle7-adapter": "^1.1", "php-http/httplug": "^2.0", + "phpseclib/phpseclib": "^3.0", "psr/http-client-implementation": "^1.0", "psr/http-factory-implementation": "^1.0" }, diff --git a/src/Module/Accounts/Accounts.php b/src/Module/Accounts/Accounts.php index 0fd827c..e9d0f5e 100644 --- a/src/Module/Accounts/Accounts.php +++ b/src/Module/Accounts/Accounts.php @@ -5,6 +5,7 @@ namespace seregazhuk\EtherscanApi\Module\Accounts; use InvalidArgumentException; +use phpseclib3\Math\BigInteger; use seregazhuk\EtherscanApi\EtherscanClient; use seregazhuk\EtherscanApi\Module\Accounts\Model\AccountBalanceTag; use seregazhuk\EtherscanApi\Module\Accounts\Model\AddressFundedInfo; @@ -99,7 +100,7 @@ public function getTransactions(string $address, int $page = 1, int $offset = 10 $json = json_decode($response->getBody()->getContents(), true); return array_map(fn(array $tx): NormalTransaction => new NormalTransaction( - $tx['blockNumber'], + new BigInteger($tx['blockNumber'], 16), $tx['timeStamp'], $tx['hash'], $tx['nonce'], diff --git a/src/Module/Accounts/Model/NormalTransaction.php b/src/Module/Accounts/Model/NormalTransaction.php index aba2db6..06c6b39 100644 --- a/src/Module/Accounts/Model/NormalTransaction.php +++ b/src/Module/Accounts/Model/NormalTransaction.php @@ -4,10 +4,12 @@ namespace seregazhuk\EtherscanApi\Module\Accounts\Model; +use phpseclib3\Math\BigInteger; + final class NormalTransaction { public function __construct( - public readonly string $blockNumber, + public readonly BigInteger $blockNumber, public readonly string $timestamp, public readonly string $hash, public readonly string $nonce, diff --git a/src/Module/Proxy/Model/TransactionByHashInfo.php b/src/Module/Proxy/Model/TransactionByHashInfo.php index d61a185..433fccc 100644 --- a/src/Module/Proxy/Model/TransactionByHashInfo.php +++ b/src/Module/Proxy/Model/TransactionByHashInfo.php @@ -4,11 +4,13 @@ namespace seregazhuk\EtherscanApi\Module\Proxy\Model; +use phpseclib3\Math\BigInteger; + final class TransactionByHashInfo { public function __construct( public readonly string $blockHash, - public readonly string $blockNumber, + public readonly BigInteger $blockNumber, public readonly string $from, public readonly string $gas, public readonly string $gasPrice, diff --git a/src/Module/Proxy/Model/TransactionReceipt.php b/src/Module/Proxy/Model/TransactionReceipt.php index 3856627..1b20f28 100644 --- a/src/Module/Proxy/Model/TransactionReceipt.php +++ b/src/Module/Proxy/Model/TransactionReceipt.php @@ -4,11 +4,13 @@ namespace seregazhuk\EtherscanApi\Module\Proxy\Model; +use phpseclib3\Math\BigInteger; + final class TransactionReceipt { public function __construct( public readonly string $blockHash, - public readonly string $blockNumber, + public readonly BigInteger $blockNumber, public readonly ?string $contractAddress, public readonly string $cumulativeGasUsed, public readonly string $from, diff --git a/src/Module/Proxy/Model/TransactionReceiptLog.php b/src/Module/Proxy/Model/TransactionReceiptLog.php index aa18e03..dc7ad02 100644 --- a/src/Module/Proxy/Model/TransactionReceiptLog.php +++ b/src/Module/Proxy/Model/TransactionReceiptLog.php @@ -4,6 +4,8 @@ namespace seregazhuk\EtherscanApi\Module\Proxy\Model; +use phpseclib3\Math\BigInteger; + final class TransactionReceiptLog { public function __construct( @@ -11,7 +13,7 @@ public function __construct( /** @var string[] $topics */ public readonly array $topics, public readonly string $data, - public readonly string $blockNumber, + public readonly BigInteger $blockNumber, public readonly string $transactionHash, public readonly string $transactionIndex, public readonly string $logIndex, diff --git a/src/Module/Proxy/Proxy.php b/src/Module/Proxy/Proxy.php index 36a2b7a..c6922d0 100644 --- a/src/Module/Proxy/Proxy.php +++ b/src/Module/Proxy/Proxy.php @@ -4,6 +4,7 @@ namespace seregazhuk\EtherscanApi\Module\Proxy; +use phpseclib3\Math\BigInteger; use seregazhuk\EtherscanApi\EtherscanClient; use seregazhuk\EtherscanApi\Module\Proxy\Model\BlockInfo; use seregazhuk\EtherscanApi\Module\Proxy\Model\TransactionByHashInfo; @@ -46,7 +47,7 @@ public function getTransactionByHash(string $hash): TransactionByHashInfo return new TransactionByHashInfo( $json['result']['blockHash'], - $json['result']['blockNumber'], + new BigInteger($json['result']['blockNumber'], 16), $json['result']['from'], $json['result']['gas'], $json['result']['gasPrice'], @@ -65,13 +66,13 @@ public function getTransactionByHash(string $hash): TransactionByHashInfo /** * @see https://docs.etherscan.io/api-endpoints/geth-parity-proxy#eth_blocknumber */ - public function getBlockNumber(): int + public function getBlockNumber(): BigInteger { $response = $this->client->sendRequest(self::MODULE_NAME, 'eth_blockNumber'); /** @var array{result: string} $json */ $json = json_decode($response->getBody()->getContents(), true); - return (int) hexdec($json['result']); + return new BigInteger($json['result'], 16); } /** @@ -149,25 +150,25 @@ public function sendRawTransaction(string $hex): string /** * @see https://docs.etherscan.io/api-endpoints/geth-parity-proxy#eth_getblocktransactioncountbynumber */ - public function getTransactionCountByNumber(string $hexBlockNumber): int + public function getTransactionCountByNumber(string $hexBlockNumber): BigInteger { $response = $this->client->sendRequest(self::MODULE_NAME, 'eth_getBlockTransactionCountByNumber', ['tag' => $hexBlockNumber]); /** @var array{result: string} $json */ $json = json_decode($response->getBody()->getContents(), true); - return (int) hexdec($json['result']); + return new BigInteger($json['result'], 16); } /** * @see https://docs.etherscan.io/api-endpoints/geth-parity-proxy#eth_gettransactioncount */ - public function getTransactionCount(string $address): int + public function getTransactionCount(string $address): BigInteger { $response = $this->client->sendRequest(self::MODULE_NAME, 'eth_getTransactionCount', ['address' => $address]); /** @var array{result: string} $json */ $json = json_decode($response->getBody()->getContents(), true); - return (int) hexdec($json['result']); + return new BigInteger($json['result'], 16); } /** @@ -205,7 +206,7 @@ public function getTransactionReceipt(string $hash): TransactionReceipt return new TransactionReceipt( $json['result']['blockHash'], - $json['result']['blockNumber'], + new BigInteger($json['result']['blockNumber'], 16), $json['result']['contractAddress'], $json['result']['cumulativeGasUsed'], $json['result']['from'], @@ -214,7 +215,7 @@ public function getTransactionReceipt(string $hash): TransactionReceipt $log['address'], $log['topics'], $log['data'], - $log['blockNumber'], + new BigInteger($log['blockNumber'], 16), $log['transactionHash'], $log['transactionIndex'], $log['logIndex'], @@ -233,12 +234,12 @@ public function getTransactionReceipt(string $hash): TransactionReceipt /** * @see https://docs.etherscan.io/api-endpoints/geth-parity-proxy#eth_gasprice */ - public function getGasPrice(): string + public function getGasPrice(): BigInteger { $response = $this->client->sendRequest(self::MODULE_NAME, 'eth_gasPrice'); /** @var array{result: string} $json */ $json = json_decode($response->getBody()->getContents(), true); - return (string) hexdec($json['result']); + return new BigInteger($json['result'], 16); } } diff --git a/tests/Module/AccountsTest.php b/tests/Module/AccountsTest.php index b40cd64..425b78e 100644 --- a/tests/Module/AccountsTest.php +++ b/tests/Module/AccountsTest.php @@ -7,6 +7,7 @@ use GuzzleHttp\Psr7\Response; use Http\Discovery\Psr17FactoryDiscovery; use InvalidArgumentException; +use phpseclib3\Math\BigInteger; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -202,7 +203,7 @@ public function it_retrieves_account_normal_transactions(): void $transactions = $this->accounts->getTransactions('0xc5102fE9359FD9a28f877a67E36B0F050d81a3CC'); $this->assertCount(2, $transactions); - $this->assertSame('14923678', $transactions[0]->blockNumber); + $this->assertTrue((new BigInteger('14923678', 16))->equals($transactions[0]->blockNumber)); $this->assertSame('0xc52783ad354aecc04c670047754f062e3d6d04e8f5b24774472651f9c3882c60', $transactions[0]->hash); $this->assertSame('0x61016060', $transactions[0]->methodId); $this->assertSame('', $transactions[0]->functionName); @@ -224,7 +225,7 @@ public function it_retrieves_account_normal_transactions(): void $this->assertSame('122485', $transactions[0]->confirmations); $this->assertSame('0x61016060', $transactions[0]->methodId); - $this->assertSame('14923692', $transactions[1]->blockNumber); + $this->assertTrue((new BigInteger('14923692', 16))->equals($transactions[1]->blockNumber)); $this->assertSame('0xaa45b4858ba44230a5fce5a29570a5dec2bf1f0ba95bacdec4fe8f2c4fa99338', $transactions[1]->hash); $this->assertSame('transfer(address _to, uint256 _value)', $transactions[1]->functionName); } diff --git a/tests/Module/ProxyTest.php b/tests/Module/ProxyTest.php index 7a8616b..592dce4 100644 --- a/tests/Module/ProxyTest.php +++ b/tests/Module/ProxyTest.php @@ -6,6 +6,7 @@ use GuzzleHttp\Psr7\Response; use Http\Discovery\Psr17FactoryDiscovery; +use phpseclib3\Math\BigInteger; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -88,7 +89,7 @@ public function it_retrieves_transaction_by_hash(): void '0xf850331061196b8f2b67e1f43aaa9e69504c059d3d3fb9547b04f9ed4d141ab7', $transaction->blockHash, ); - $this->assertSame('0xcf2420', $transaction->blockNumber); + $this->assertTrue((new BigInteger('0xcf2420', 16))->equals($transaction->blockNumber)); $this->assertSame('0x00192fb10df37c9fb26829eb2cc623cd1bf599e8', $transaction->from); $this->assertSame('0x5208', $transaction->gas); $this->assertSame('0x19f017ef49', $transaction->gasPrice); @@ -155,7 +156,7 @@ public function it_retrieves_transaction_by_hash_with_nullable_fields(): void '0xf850331061196b8f2b67e1f43aaa9e69504c059d3d3fb9547b04f9ed4d141ab7', $transaction->blockHash, ); - $this->assertSame('0xcf2420', $transaction->blockNumber); + $this->assertTrue((new BigInteger('0xcf2420', 16))->equals($transaction->blockNumber)); $this->assertSame('0x00192fb10df37c9fb26829eb2cc623cd1bf599e8', $transaction->from); $this->assertSame('0x5208', $transaction->gas); $this->assertSame('0x19f017ef49', $transaction->gasPrice); @@ -196,7 +197,7 @@ public function it_retrieves_block_number(): void ) ->willReturn(new Response(200, [], $json)); $result = $this->proxy->getBlockNumber(); - $this->assertSame(12806953, $result); + $this->assertTrue((new BigInteger('0xc36b29', 16))->equals($result)); } #[Test] @@ -345,7 +346,7 @@ public function it_retrieves_transaction_count_for_block(): void ) ->willReturn(new Response(200, [], $json)); $result = $this->proxy->getTransactionCountByNumber('0x10FB78'); - $this->assertSame(3, $result); + $this->assertTrue((new BigInteger('0x3', 16))->equals($result)); } #[Test] @@ -374,7 +375,7 @@ public function it_retrieves_transaction_count_for_address(): void ) ->willReturn(new Response(200, [], $json)); $result = $this->proxy->getTransactionCount('0x4bd5900Cb274ef15b153066D736bf3e83A9ba44e'); - $this->assertSame(68, $result); + $this->assertTrue((new BigInteger('0x44', 16))->equals($result)); } #[Test] @@ -436,7 +437,7 @@ public function it_retrieves_transaction_receipt(): void $result = $this->proxy->getTransactionReceipt('0xf75e354c5edc8efed9b59ee9f67a80845ade7d0c'); $this->assertSame('0x07c17710dbb7514e92341c9f83b4aab700c5dba7c4fb98caadd7926a32e47799', $result->blockHash); - $this->assertSame('0xcf2427', $result->blockNumber); + $this->assertTrue((new BigInteger('0xcf2427', 16))->equals($result->blockNumber)); $this->assertSame('0x292f04a44506c2fd49bac032e1ca148c35a478c8', $result->from); $this->assertSame('0xb41d', $result->gasUsed); $this->assertSame('0xdac17f958d2ee523a2206206994597c13d831ec7', $result->logs[0]->address); @@ -455,7 +456,7 @@ public function it_retrieves_transaction_receipt(): void // Logs $this->assertSame('0x00000000000000000000000000000000000000000000000000000000013f81a6', $result->logs[0]->data); - $this->assertSame('0xcf2427', $result->logs[0]->blockNumber); + $this->assertTrue((new BigInteger('0xcf2427', 16))->equals($result->logs[0]->blockNumber)); $this->assertSame( '0xadb8aec59e80db99811ac4a0235efa3e45da32928bcff557998552250fa672eb', $result->logs[0]->transactionHash, @@ -507,6 +508,6 @@ public function it_retrieves_gas_price(): void ) ->willReturn(new Response(200, [], $json)); $result = $this->proxy->getGasPrice(); - $this->assertSame('18000000000', $result); + $this->assertTrue((new BigInteger('0x430e23400', 16))->equals($result)); } }