Skip to content

Commit d8013ca

Browse files
committed
Added transaction parsing with address recovery.
1 parent b26b1b9 commit d8013ca

File tree

6 files changed

+63
-4
lines changed

6 files changed

+63
-4
lines changed

dist/ethers-wallet.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,6 +1582,7 @@ var utils = require('./utils.js');
15821582
var secp256k1 = new (elliptic.ec)('secp256k1');
15831583

15841584

1585+
15851586
function SigningKey(privateKey) {
15861587
if (!(this instanceof SigningKey)) { throw new Error('missing new'); }
15871588

@@ -1603,6 +1604,11 @@ function SigningKey(privateKey) {
16031604
});
16041605
}
16051606

1607+
utils.defineProperty(SigningKey, 'recover', function(digest, r, s, recoveryParam) {
1608+
var publicKey = secp256k1.recoverPubKey(digest, {r: r, s: s}, recoveryParam);
1609+
publicKey = (new Buffer(publicKey.encode('hex', false), 'hex')).slice(1);
1610+
return utils.getAddress(utils.sha3(publicKey).slice(12).toString('hex'));
1611+
});
16061612

16071613
module.exports = SigningKey;
16081614

@@ -2208,6 +2214,28 @@ function Wallet(privateKey, provider) {
22082214
});
22092215
}
22102216

2217+
utils.defineProperty(Wallet, 'parseTransaction', function(rawTransaction) {
2218+
rawTransaction = utils.hexOrBuffer(rawTransaction, 'rawTransaction');
2219+
var signedTransaction = rlp.decode(rawTransaction);
2220+
2221+
var raw = [];
2222+
2223+
var transaction = {};
2224+
transactionFields.forEach(function(fieldInfo, index) {
2225+
transaction[fieldInfo.name] = signedTransaction[index];
2226+
raw.push(signedTransaction[index]);
2227+
});
2228+
2229+
transaction.v = signedTransaction[6];
2230+
transaction.r = signedTransaction[7];
2231+
transaction.s = signedTransaction[8];
2232+
2233+
var digest = utils.sha3(rlp.encode(raw));
2234+
transaction.from = SigningKey.recover(digest, transaction.r, transaction.s, transaction.v[0] - 27);
2235+
2236+
return transaction;
2237+
});
2238+
22112239
utils.defineProperty(Wallet.prototype, 'getBalance', function(blockNumber) {
22122240
var provider = this._provider;
22132241

dist/ethers-wallet.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/signing-key.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ var utils = require('./utils.js');
77
var secp256k1 = new (elliptic.ec)('secp256k1');
88

99

10+
1011
function SigningKey(privateKey) {
1112
if (!(this instanceof SigningKey)) { throw new Error('missing new'); }
1213

@@ -28,5 +29,10 @@ function SigningKey(privateKey) {
2829
});
2930
}
3031

32+
utils.defineProperty(SigningKey, 'recover', function(digest, r, s, recoveryParam) {
33+
var publicKey = secp256k1.recoverPubKey(digest, {r: r, s: s}, recoveryParam);
34+
publicKey = (new Buffer(publicKey.encode('hex', false), 'hex')).slice(1);
35+
return utils.getAddress(utils.sha3(publicKey).slice(12).toString('hex'));
36+
});
3137

3238
module.exports = SigningKey;

lib/wallet.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,28 @@ function Wallet(privateKey, provider) {
111111
});
112112
}
113113

114+
utils.defineProperty(Wallet, 'parseTransaction', function(rawTransaction) {
115+
rawTransaction = utils.hexOrBuffer(rawTransaction, 'rawTransaction');
116+
var signedTransaction = rlp.decode(rawTransaction);
117+
118+
var raw = [];
119+
120+
var transaction = {};
121+
transactionFields.forEach(function(fieldInfo, index) {
122+
transaction[fieldInfo.name] = signedTransaction[index];
123+
raw.push(signedTransaction[index]);
124+
});
125+
126+
transaction.v = signedTransaction[6];
127+
transaction.r = signedTransaction[7];
128+
transaction.s = signedTransaction[8];
129+
130+
var digest = utils.sha3(rlp.encode(raw));
131+
transaction.from = SigningKey.recover(digest, transaction.r, transaction.s, transaction.v[0] - 27);
132+
133+
return transaction;
134+
});
135+
114136
utils.defineProperty(Wallet.prototype, 'getBalance', function(blockNumber) {
115137
var provider = this._provider;
116138

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ethers-wallet",
3-
"version": "1.0.2",
3+
"version": "1.0.3",
44
"description": "Ethereum wallet library.",
55
"main": "index.js",
66
"scripts": {

tests/test-transactions.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ module.exports = function(test) {
1717
rawTransaction.sign(privateKey);
1818
var ethereumLib = '0x' + rawTransaction.serialize().toString('hex');
1919

20-
var ethers = (new Wallet(privateKey)).sign(transaction);
20+
var wallet = new Wallet(privateKey);
21+
var ethers = wallet.sign(transaction);
2122

2223
test.equal(ethers, ethereumLib, 'invalid transaction');
24+
25+
test.equal(wallet.address, Wallet.parseTransaction(ethers).from, 'invalid parseTransaction');
2326
}
2427

2528
for (var i = 0; i < 10000; i++) {

0 commit comments

Comments
 (0)