Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ vendor
clover.xml
.php_cs.cache
.phpunit.result.cache
.phpunit.cache
.coverage
coverage.xml
.php-cs-fixer.cache
Expand Down
10 changes: 0 additions & 10 deletions src/Enums/Constants.php

This file was deleted.

15 changes: 3 additions & 12 deletions src/Transactions/Builder/AbstractTransactionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace ArkEcosystem\Crypto\Transactions\Builder;

use ArkEcosystem\Crypto\Configuration\Network;
use ArkEcosystem\Crypto\Identities\PrivateKey;
use ArkEcosystem\Crypto\Transactions\Types\AbstractTransaction;
use Brick\Math\BigDecimal;
Expand All @@ -19,9 +18,8 @@ public function __construct(?array $data = null)
'value' => BigDecimal::zero(),
'senderPublicKey' => '',
'gasPrice' => '5',
'gasLimit' => 1_000_000,
'nonce' => '1',
'network' => Network::get()->chainId(),
'gas' => 1_000_000,
'data' => '',
]);
}
Expand All @@ -36,9 +34,9 @@ public static function new(?array $data = null): static
return new static($data);
}

public function gas(BigDecimal $gas): static
public function gasLimit(BigDecimal $gasLimit): static
{
$this->transaction->data['gas'] = $gas;
$this->transaction->data['gasLimit'] = $gasLimit;

return $this;
}
Expand All @@ -64,13 +62,6 @@ public function nonce(string $nonce): static
return $this;
}

public function network(int $network): static
{
$this->transaction->data['network'] = $network;

return $this;
}

public function sign(string $passphrase): static
{
$privateKey = PrivateKey::fromPassphrase($passphrase);
Expand Down
31 changes: 16 additions & 15 deletions src/Transactions/Deserializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
namespace ArkEcosystem\Crypto\Transactions;

use ArkEcosystem\Crypto\ByteBuffer\ByteBuffer;
use ArkEcosystem\Crypto\Configuration\Network;
use ArkEcosystem\Crypto\Enums\AbiFunction;
use ArkEcosystem\Crypto\Enums\Constants;
use ArkEcosystem\Crypto\Enums\ContractAbiType;
use ArkEcosystem\Crypto\Helpers;
use ArkEcosystem\Crypto\Transactions\Types\AbstractTransaction;
Expand Down Expand Up @@ -42,7 +42,7 @@ public function __construct(string $serialized)
? ByteBuffer::fromHex($serialized)
: ByteBuffer::fromBinary($serialized);

$this->encodedRlp = '0x'.mb_substr($this->buffer->toString('hex'), 2);
$this->encodedRlp = '0x'.$this->buffer->toString('hex');
}

/**
Expand All @@ -62,23 +62,24 @@ public function deserialize(): AbstractTransaction

$data = [];

$data['network'] = $this->parseNumber($decodedRlp[0]);
$data['nonce'] = $this->parseBigNumber($decodedRlp[1]);
$data['gasPrice'] = $this->parseNumber($decodedRlp[3]);
$data['gas'] = $this->parseNumber($decodedRlp[4]);
$data['to'] = $this->parseAddress($decodedRlp[5]);
$data['value'] = $this->parseBigNumber($decodedRlp[6]);
$data['data'] = $this->parseHex($decodedRlp[7]);

if (count($decodedRlp) === 12) {
$data['v'] = $this->parseNumber($decodedRlp[9]) + 27;
$data['r'] = $this->parseHex($decodedRlp[10]);
$data['s'] = $this->parseHex($decodedRlp[11]);
$data['nonce'] = $this->parseBigNumber($decodedRlp[0]);
$data['gasPrice'] = $this->parseNumber($decodedRlp[1]);
$data['gasLimit'] = $this->parseNumber($decodedRlp[2]);
$data['to'] = $this->parseAddress($decodedRlp[3]);
$data['value'] = $this->parseBigNumber($decodedRlp[4]);
$data['data'] = $this->parseHex($decodedRlp[5]);

if (count($decodedRlp) >= 9) {
$data['v'] = $this->parseNumber($decodedRlp[6]) - (Network::get()->chainId() * 2 + 35);
$data['r'] = $this->parseHex($decodedRlp[7]);
$data['s'] = $this->parseHex($decodedRlp[8]);
}

// TODO: second signature handling

$transaction = $this->guessTransactionFromData($data);

$serializedHex = sprintf('%s%s', Constants::EIP_1559_PREFIX, mb_substr($this->encodedRlp, 2));
$serializedHex = mb_substr($this->encodedRlp, 2);

$transaction->serialized = new Buffer(hex2bin($serializedHex));

Expand Down
8 changes: 3 additions & 5 deletions src/Transactions/Types/AbstractTransaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace ArkEcosystem\Crypto\Transactions\Types;

use ArkEcosystem\Crypto\Configuration\Network;
use ArkEcosystem\Crypto\Helpers;
use ArkEcosystem\Crypto\Identities\Address;
use ArkEcosystem\Crypto\Identities\PrivateKey;
Expand Down Expand Up @@ -52,7 +51,7 @@ public function sign(PrivateKey $privateKey): static
// Extract the recovery ID (an integer between 0 and 3) from the signature
$recoveryId = $signature->getRecoveryId();

$this->data['v'] = $recoveryId + 27;
$this->data['v'] = $recoveryId;
$this->data['r'] = Helpers::gmpToHex($signature->getR());
$this->data['s'] = Helpers::gmpToHex($signature->getS());

Expand Down Expand Up @@ -96,9 +95,8 @@ public function toArray(): array
{
return array_filter([
'gasPrice' => $this->data['gasPrice'],
'network' => $this->data['network'] ?? Network::get()->chainId(),
'gasLimit' => $this->data['gasLimit'],
'hash' => $this->data['hash'],
'gas' => $this->data['gas'],
'nonce' => $this->data['nonce'],
'senderPublicKey' => $this->data['senderPublicKey'],
'to' => $this->data['to'] ?? null,
Expand Down Expand Up @@ -136,7 +134,7 @@ private function getSignature(): CompactSignatureInterface
Bitcoin::getGenerator()
);

$recoverId = $this->data['v'] - 27;
$recoverId = $this->data['v'];
$r = gmp_init($this->data['r'], 16);
$s = gmp_init($this->data['s'], 16);

Expand Down
7 changes: 3 additions & 4 deletions src/Utils/Abi/ArgumentDecoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ final class ArgumentDecoder

public function __construct(string $bytes)
{
try {
$bytes = hex2bin($bytes);
} catch (\Throwable $e) {
// Handle the case where hex2bin fails, e.g., invalid hex string
if (! ctype_xdigit($bytes) || strlen($bytes) % 2 !== 0) {
$bytes = false;
} else {
$bytes = hex2bin($bytes);
}

if ($bytes === false) {
Expand Down
4 changes: 2 additions & 2 deletions src/Utils/AbiBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ abstract class AbiBase
{
protected array $abi;

public function __construct(ContractAbiType $type = ContractAbiType::CONSENSUS, string $path = null)
public function __construct(ContractAbiType $type = ContractAbiType::CONSENSUS, ?string $path = null)
{
$abiFilePath = $this->contractAbiPath($type, $path);

Expand Down Expand Up @@ -75,7 +75,7 @@ protected function toFunctionSelector(array $abiItem): string
return $selector;
}

private function contractAbiPath(ContractAbiType $type, string $path = null): ?string
private function contractAbiPath(ContractAbiType $type, ?string $path = null): ?string
{
switch ($type) {
case ContractAbiType::CONSENSUS:
Expand Down
2 changes: 1 addition & 1 deletion src/Utils/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public static function sign(string $message, string $passphrase): self

$r = Helpers::gmpToHex($signature->getR());
$s = Helpers::gmpToHex($signature->getS());
$v = dechex($signature->getRecoveryId() + 27);
$v = str_pad(dechex($signature->getRecoveryId()), 2, '0', STR_PAD_LEFT);

return static::new([
'publicKey' => $privateKey->publicKey,
Expand Down
26 changes: 14 additions & 12 deletions src/Utils/TransactionUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace ArkEcosystem\Crypto\Utils;

use ArkEcosystem\Crypto\Enums\Constants;
use ArkEcosystem\Crypto\Configuration\Network;
use BI\BigInteger;
use BitWasp\Buffertools\Buffer;
use BitWasp\Buffertools\BufferInterface;
Expand All @@ -22,30 +22,32 @@ class TransactionUtils
public static function toBuffer(array $transaction, bool $skipSignature = false): Buffer
{
$fields = [
self::toBeArray($transaction['network'] ?? 0),
self::toBeArray(isset($transaction['nonce']) ? $transaction['nonce'] : 0),
self::toBeArray(0),
self::toBeArray($transaction['gasPrice'] ?? 0),
self::toBeArray($transaction['gas'] ?? 0),
self::toBeArray($transaction['gasLimit'] ?? 0),
$transaction['to'] ?? '0x',
self::toBeArray(isset($transaction['value']) ? $transaction['value'] : 0),
isset($transaction['data']) && str_starts_with($transaction['data'], '0x')
? $transaction['data']
: ('0x'.($transaction['data'] ?? '')),
[],
];

if (! $skipSignature) {
if (isset($transaction['v'], $transaction['r'], $transaction['s'])) {
$fields[] = self::toBeArray($transaction['v'] - 27);
$fields[] = '0x'.$transaction['r'];
$fields[] = '0x'.$transaction['s'];
}
if (! $skipSignature && isset($transaction['v'], $transaction['r'], $transaction['s']) && $transaction['v'] !== '') {
$fields[] = self::toBeArray($transaction['v'] + Network::get()->chainId() * 2 + 35);
$fields[] = '0x'.$transaction['r'];
$fields[] = '0x'.$transaction['s'];
} else {
// Push chainId + 0s for r and s
$fields[] = self::toBeArray(Network::get()->chainId());
$fields[] = self::toBeArray(0);
$fields[] = self::toBeArray(0);
}

// TODO: second signature handling

$encoded = RlpEncoder::encode($fields);

$payload = Constants::EIP_1559_PREFIX.substr($encoded, 2);
$payload = substr($encoded, 2);

return new Buffer(hex2bin($payload));
}
Expand Down
7 changes: 3 additions & 4 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace ArkEcosystem\Tests\Crypto;

use ArkEcosystem\Crypto\Configuration\Network;
use ArkEcosystem\Crypto\Networks\Mainnet;
use ArkEcosystem\Crypto\Networks\Testnet;
use ArkEcosystem\Crypto\Transactions\Deserializer;
use ArkEcosystem\Crypto\Transactions\Types\AbstractTransaction;
use PHPUnit\Framework\TestCase as BaseTestCase;
Expand All @@ -30,18 +30,17 @@ abstract class TestCase extends BaseTestCase

protected function setUp(): void
{
Network::set(Mainnet::new());
Network::set(Testnet::new());
}

protected function assertTransaction(array $fixture): AbstractTransaction
{
$actual = $this->assertDeserialized($fixture, [
'hash',
'network',
'nonce',
'value',
'gasPrice',
'gas',
'gasLimit',
'contractId',
'senderPublicKey',
'from',
Expand Down
12 changes: 4 additions & 8 deletions tests/Unit/Transactions/Builder/EvmCallBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@

$builder = EvmCallBuilder::new()
->gasPrice(UnitConverter::parseUnits($fixture['data']['gasPrice'], 'wei'))
->gasLimit(UnitConverter::parseUnits($fixture['data']['gasLimit'], 'wei'))
->nonce($fixture['data']['nonce'])
->network($fixture['data']['network'])
->payload($fixture['data']['data'])
->gas(UnitConverter::parseUnits($fixture['data']['gas'], 'wei'))
->to('0xE536720791A7DaDBeBdBCD8c8546fb0791a11901')
->sign($this->passphrase);

Expand All @@ -25,10 +24,9 @@

$builder = EvmCallBuilder::new()
->gasPrice(UnitConverter::parseUnits($fixture['data']['gasPrice'], 'wei'))
->gasLimit(UnitConverter::parseUnits($fixture['data']['gasLimit'], 'wei'))
->nonce($fixture['data']['nonce'])
->network($fixture['data']['network'])
->payload($fixture['data']['data'])
->gas(UnitConverter::parseUnits($fixture['data']['gas'], 'wei'))
->to('0xE536720791A7DaDBeBdBCD8c8546fb0791a11901')
->sign($this->passphrase);

Expand All @@ -40,18 +38,16 @@

$builder = EvmCallBuilder::new()
->gasPrice(UnitConverter::parseUnits($fixture['data']['gasPrice'], 'wei'))
->gasLimit(UnitConverter::parseUnits($fixture['data']['gasLimit'], 'wei'))
->nonce($fixture['data']['nonce'])
->network($fixture['data']['network'])
->payload($fixture['data']['data'])
->gas(UnitConverter::parseUnits($fixture['data']['gas'], 'wei'))
->to('0xE536720791A7DaDBeBdBCD8c8546fb0791a11901')
->sign($this->passphrase);

expect($builder->toArray())->toBe([
'gasPrice' => $builder->transaction->data['gasPrice'],
'network' => $builder->transaction->data['network'],
'gasLimit' => $builder->transaction->data['gasLimit'],
'hash' => $builder->transaction->data['hash'],
'gas' => $builder->transaction->data['gas'],
'nonce' => $builder->transaction->data['nonce'],
'senderPublicKey' => $builder->transaction->data['senderPublicKey'],
'to' => '0xE536720791A7DaDBeBdBCD8c8546fb0791a11901',
Expand Down
Loading
Loading