Skip to content

Commit

Permalink
Add getFromAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
sc0Vu committed May 23, 2018
1 parent 8ffcb74 commit 8fea86d
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 2 deletions.
56 changes: 54 additions & 2 deletions src/Transaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use kornrunner\Keccak;
use Web3p\RLP\RLP;
use Elliptic\EC;
use Elliptic\EC\KeyPair;
use ArrayAccess;

class Transaction implements ArrayAccess
Expand Down Expand Up @@ -68,6 +69,13 @@ class Transaction implements ArrayAccess
*/
protected $secp256k1;

/**
* privateKey
*
* @var \Elliptic\EC\KeyPair
*/
protected $privateKey;

/**
* construct
*
Expand Down Expand Up @@ -253,8 +261,8 @@ public function serialize()
public function sign(string $privateKey)
{
$txHash = $this->hash(false);
$key = $this->secp256k1->keyFromPrivate($privateKey, 'hex');
$signature = $key->sign($txHash);
$privateKey = $this->secp256k1->keyFromPrivate($privateKey, 'hex');
$signature = $privateKey->sign($txHash);
$r = $signature->r;
$s = $signature->s;
$v = $signature->recoveryParam + 35;
Expand All @@ -268,6 +276,7 @@ public function sign(string $privateKey)
$this->offsetSet('r', '0x' . $r->toString(16));
$this->offsetSet('s', '0x' . $s->toString(16));
$this->offsetSet('v', $v);
$this->privateKey = $privateKey;

return $this->serialize()->toString('hex');
}
Expand Down Expand Up @@ -309,4 +318,47 @@ public function hash($includeSignature=false)

return $this->sha3($serializedTx);
}

/**
* getFromAddress
*
* @return string
*/
public function getFromAddress()
{
$from = $this->offsetGet('from');

if ($from) {
var_dump(1);
return $from;
}
if (!isset($this->privateKey) || !($this->privateKey instanceof KeyPair)) {
// recover from hash
$r = $this->offsetGet('r');
$s = $this->offsetGet('s');
$v = $this->offsetGet('v');
$chainId = $this->offsetGet('chainId');

if (!$r || !$s) {
throw new RuntimeException('Invalid signature r and s.');
}
$txHash = $this->hash(false);

if ($chainId && $chainId > 0) {
$v -= ($chainId * 2);
}
$v -= 35;
$publicKey = $this->secp256k1->recoverPubKey($txHash, [
'r' => $r,
's' => $s
], $v);
$publicKey = $publicKey->encode('hex');
} else {
$publicKey = $this->privateKey->getPublic(false, 'hex');
}
$from = '0x' . substr($this->sha3(substr(hex2bin($publicKey), 1)), 24);

$this->offsetSet('from', $from);
return $from;
}
}
61 changes: 61 additions & 0 deletions test/unit/TransactionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,65 @@ public function testEIP155()
$this->assertEquals('daf5a779ae972f972197303d7b574746c7ef83eadac0f2791ad23db92e4c8e53', $transaction->hash(false));
$this->assertEquals('f86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83', $transaction->sign('0x4646464646464646464646464646464646464646464646464646464646464646'));
}

/**
* testGetFromAddress
* 0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f
*
* @return void
*/
public function testGetFromAddress()
{
$transaction = new Transaction([
'nonce' => '0x09',
'to' => '0x3535353535353535353535353535353535353535',
'gas' => '0x5208',
'gasPrice' => '0x4a817c800',
'value' => '0xde0b6b3a7640000',
'chainId' => 1,
'data' => ''
]);
// sign tx
$transaction->sign('0x4646464646464646464646464646464646464646464646464646464646464646');
$r = $transaction['r'];
$s = $transaction['s'];
$v = $transaction['v'];

// get from privatekey
$fromA = $transaction->getFromAddress();

$transaction = new Transaction([
'nonce' => '0x09',
'to' => '0x3535353535353535353535353535353535353535',
'gas' => '0x5208',
'gasPrice' => '0x4a817c800',
'value' => '0xde0b6b3a7640000',
'chainId' => 1,
'data' => ''
]);
$transaction['r'] = $r;
$transaction['s'] = $s;
$transaction['v'] = $v;

// get from r, s, v
$fromB = $transaction->getFromAddress();

$transaction = new Transaction([
'from' => '0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f',
'nonce' => '0x09',
'to' => '0x3535353535353535353535353535353535353535',
'gas' => '0x5208',
'gasPrice' => '0x4a817c800',
'value' => '0xde0b6b3a7640000',
'chainId' => 1,
'data' => ''
]);

// get from transaction
$fromC = $transaction->getFromAddress();

$this->assertEquals('0x9d8a62f656a8d1615c1294fd71e9cfb3e4855a4f', $fromA);
$this->assertEquals($fromA, $fromB);
$this->assertEquals($fromB, $fromC);
}
}

0 comments on commit 8fea86d

Please sign in to comment.