Skip to content

Commit

Permalink
Change methods to fix eip 155
Browse files Browse the repository at this point in the history
Change
* sign
* serialize
* hash
* Add eip 155 test
  • Loading branch information
sc0Vu committed May 23, 2018
1 parent 8a2e6fb commit 8ffcb74
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 47 deletions.
53 changes: 37 additions & 16 deletions src/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,8 @@ public function getTxData()
* @param string $value
* @return string
*/
public function sha3($value)
public function sha3(string $value)
{
if (!is_string($value)) {
throw new InvalidArgumentException('The value to sha3 function must be string.');
}
$hash = Keccak::hash($value, 256);

if ($hash === $this::SHA3_NULL_HASH) {
Expand All @@ -226,22 +223,19 @@ public function sha3($value)
/**
* serialize
*
* @return string
* @return \Web3p\RLP\RLP\Buffer
*/
public function serialize()
{
$chainId = $this->offsetGet('chainId');

// sort tx data
if (ksort($this->txData) !== true) {
throw new RuntimeException('Cannot sort tx data by keys.');
}
if ($chainId && $chainId > 0) {
$v = (int) $chainId;
$this->offsetSet('v', $v);
$this->offsetSet('r', 0);
$this->offsetSet('s', 0);
$txData = array_fill(0, 9, '');
} else {
$txData = array_fill(0, 6, '');
}

foreach ($this->txData as $key => $data) {
if ($key >= 0) {
$txData[$key] = $data;
Expand All @@ -258,8 +252,8 @@ public function serialize()
*/
public function sign(string $privateKey)
{
$txHash = $this->hash();
$key = $this->secp256k1->keyFromPrivate($privateKey);
$txHash = $this->hash(false);
$key = $this->secp256k1->keyFromPrivate($privateKey, 'hex');
$signature = $key->sign($txHash);
$r = $signature->r;
$s = $signature->s;
Expand All @@ -281,11 +275,38 @@ public function sign(string $privateKey)
/**
* hash
*
* @param bool $includeSignature
* @return string
*/
public function hash()
public function hash($includeSignature=false)
{
$serializedTx = $this->serialize()->toString('utf8');
$chainId = $this->offsetGet('chainId');

// sort tx data
if (ksort($this->txData) !== true) {
throw new RuntimeException('Cannot sort tx data by keys.');
}
if ($includeSignature) {
$txData = $this->txData;
} else {
if ($chainId && $chainId > 0) {
$v = (int) $chainId;
$this->offsetSet('r', '');
$this->offsetSet('s', '');
$this->offsetSet('v', $v);
$txData = array_fill(0, 9, '');
} else {
$txData = array_fill(0, 6, '');
}

foreach ($this->txData as $key => $data) {
if ($key >= 0) {
$txData[$key] = $data;
}
}
}
$serializedTx = $this->rlp->encode($txData)->toString('utf8');

return $this->sha3($serializedTx);
}
}
75 changes: 44 additions & 31 deletions test/unit/TransactionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ public function testSet()
}

/**
* testSerialize
* testSha3
*
* @return void
*/
public function testSerialize()
public function testSha3()
{
$transaction = new Transaction([
'nonce' => '0x01',
Expand All @@ -113,32 +113,33 @@ public function testSerialize()
'gas' => '0x76c0',
'gasPrice' => '0x9184e72a000',
'value' => '0x9184e72a',
'chainId' => 4,
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
]);

$this->assertEquals('f852018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675258080', $transaction->serialize()->toString('hex'));
$this->assertNull($transaction->sha3(''));
$this->assertEquals('47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad', $transaction->sha3('hello world'));
}

/**
* testHash
*
* @return void
*/
public function testHash()
{
$transaction = new Transaction([
'nonce' => '0x01',
'from' => '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
'to' => '0xd46e8dd67c5d32be8058bb8eb970870f07244567',
'gas' => '0x76c0',
'gasPrice' => '0x9184e72a000',
'value' => '0x9184e72a',
'chainId' => 4,
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
]);

$this->assertEquals('f852018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f0724456752b8080', $transaction->serialize()->toString('hex'));
}
$this->assertEquals('79617051b33e38636c12fb761abf62c20a9dd5a743ca5f338f04f2cf5f2ec6bd', $transaction->hash());

/**
* testSha3
*
* @return void
*/
public function testSha3()
{
$transaction = new Transaction([
'nonce' => '0x01',
'from' => '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
Expand All @@ -150,16 +151,15 @@ public function testSha3()
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
]);

$this->assertNull($transaction->sha3(''));
$this->assertEquals('47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad', $transaction->sha3('hello world'));
$this->assertEquals('8aace0c8df439c9cc9f313b116f1db03e0811ca07e582d351aad1c9d6542c23d', (string) $transaction);
}

/**
* testHash
* testSign
*
* @return void
*/
public function testHash()
public function testSign()
{
$transaction = new Transaction([
'nonce' => '0x01',
Expand All @@ -170,39 +170,52 @@ public function testHash()
'value' => '0x9184e72a',
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
]);
$this->assertEquals('f892018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567523a0a48d3ce9c68bb49825aea5335bd07432823e858e8a504767d08290c28aafddf8a0416c7abc3a67080db0ad07c42de82db4e05518f99595119677398c68d431ab37', $transaction->sign($this->testPrivateKey));
}

$this->assertEquals('710aee292b0f1749aaa0cfef67111e2f716afbdb475e7f250bdb80c6655b0a66', $transaction->hash());

/**
* testSerialize
*
* @return void
*/
public function testSerialize()
{
$transaction = new Transaction([
'nonce' => '0x01',
'from' => '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
'to' => '0xd46e8dd67c5d32be8058bb8eb970870f07244567',
'gas' => '0x76c0',
'gasPrice' => '0x9184e72a000',
'value' => '0x9184e72a',
'chainId' => 4,
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
]);

$this->assertEquals('dd4238507087c6d354079ea5a4c8da7abde43252f0accf79601d0fa1a10300d8', (string) $transaction);
$this->assertEquals('f84f018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675', $transaction->serialize()->toString('hex'));

// sign tx
$transaction->sign($this->testPrivateKey);

$this->assertEquals('f892018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567523a0a48d3ce9c68bb49825aea5335bd07432823e858e8a504767d08290c28aafddf8a0416c7abc3a67080db0ad07c42de82db4e05518f99595119677398c68d431ab37', $transaction->serialize()->toString('hex'));
}

/**
* testSign
* testEIP155
* you can find test case here: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
*
* @return void
*/
public function testSign()
public function testEIP155()
{
$transaction = new Transaction([
'nonce' => '0x01',
'from' => '0xb60e8dd61c5d32be8058bb8eb970870f07233155',
'to' => '0xd46e8dd67c5d32be8058bb8eb970870f07244567',
'gas' => '0x76c0',
'gasPrice' => '0x9184e72a000',
'value' => '0x9184e72a',
'data' => '0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675'
'nonce' => '0x09',
'to' => '0x3535353535353535353535353535353535353535',
'gas' => '0x5208',
'gasPrice' => '0x4a817c800',
'value' => '0xde0b6b3a7640000',
'chainId' => 1,
'data' => ''
]);
$this->assertEquals('f892018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72aa9d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f07244567525a08d8bfd01c48454b5b3fed2361cbd0e8c3282d5bd2e26762e4c9dfbe1ef35f325a06d6a5dc397934b5544835f34ff24263cbc00bdd516b6f0df3f29cdf6c779ccfb', $transaction->sign($this->testPrivateKey));
$this->assertEquals('daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53', $transaction->hash(false));
$this->assertEquals('f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83', $transaction->sign('0x4646464646464646464646464646464646464646464646464646464646464646'));
}
}

0 comments on commit 8ffcb74

Please sign in to comment.