forked from tornado-packages/ethers.js
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc2583ddd8 | ||
|
|
3be962f09d | ||
|
|
736b08e016 | ||
|
|
d8013cae37 | ||
|
|
b26b1b9c53 |
85
dist/ethers-wallet.js
vendored
85
dist/ethers-wallet.js
vendored
@@ -2,7 +2,6 @@
|
||||
(function (Buffer){
|
||||
'use strict';
|
||||
|
||||
var rlp = require('rlp');
|
||||
var scrypt = require('scrypt-js');
|
||||
|
||||
var Contract = require('./lib/contract.js');
|
||||
@@ -26,13 +25,7 @@ utils.defineProperty(exportUtils, 'Buffer', Buffer);
|
||||
utils.defineProperty(exportUtils, 'sha3', utils.sha3);
|
||||
utils.defineProperty(exportUtils, 'sha256', utils.sha256);
|
||||
|
||||
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
|
||||
utils.defineProperty(exportUtils, 'getContractAddress', function(transaction) {
|
||||
return utils.getAddress('0x' + utils.sha3(rlp.encode([
|
||||
utils.hexOrBuffer(utils.getAddress(transaction.from)),
|
||||
utils.hexOrBuffer(utils.hexlify(transaction.nonce, 'nonce'))
|
||||
])).slice(12).toString('hex'));
|
||||
});
|
||||
utils.defineProperty(exportUtils, 'getContractAddress', utils.getContractAddress);
|
||||
|
||||
module.exports = Wallet;
|
||||
|
||||
@@ -105,7 +98,7 @@ utils.defineProperty(Wallet, 'randomish', new Randomish());
|
||||
module.exports = Wallet;
|
||||
|
||||
}).call(this,require("buffer").Buffer)
|
||||
},{"./lib/contract.js":4,"./lib/providers.js":5,"./lib/randomish.js":6,"./lib/secret-storage.js":7,"./lib/signing-key.js":8,"./lib/units.js":9,"./lib/utils.js":10,"./lib/wallet.js":11,"buffer":41,"rlp":85,"scrypt-js":86}],2:[function(require,module,exports){
|
||||
},{"./lib/contract.js":4,"./lib/providers.js":5,"./lib/randomish.js":6,"./lib/secret-storage.js":7,"./lib/signing-key.js":8,"./lib/units.js":9,"./lib/utils.js":10,"./lib/wallet.js":11,"buffer":41,"scrypt-js":86}],2:[function(require,module,exports){
|
||||
(function (global,Buffer){
|
||||
'use strict';
|
||||
|
||||
@@ -1544,7 +1537,7 @@ utils.defineProperty(secretStorage, 'encrypt', function(privateKey, password, op
|
||||
|
||||
// See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
|
||||
var data = {
|
||||
address: address,
|
||||
address: address.substring(2).toLowerCase(),
|
||||
id: uuid.v4({random: uuidRandom}),
|
||||
version: 3,
|
||||
Crypto: {
|
||||
@@ -1589,6 +1582,7 @@ var utils = require('./utils.js');
|
||||
var secp256k1 = new (elliptic.ec)('secp256k1');
|
||||
|
||||
|
||||
|
||||
function SigningKey(privateKey) {
|
||||
if (!(this instanceof SigningKey)) { throw new Error('missing new'); }
|
||||
|
||||
@@ -1610,6 +1604,11 @@ function SigningKey(privateKey) {
|
||||
});
|
||||
}
|
||||
|
||||
utils.defineProperty(SigningKey, 'recover', function(digest, r, s, recoveryParam) {
|
||||
var publicKey = secp256k1.recoverPubKey(digest, {r: r, s: s}, recoveryParam);
|
||||
publicKey = (new Buffer(publicKey.encode('hex', false), 'hex')).slice(1);
|
||||
return utils.getAddress(utils.sha3(publicKey).slice(12).toString('hex'));
|
||||
});
|
||||
|
||||
module.exports = SigningKey;
|
||||
|
||||
@@ -1698,6 +1697,8 @@ module.exports = {
|
||||
(function (Buffer){
|
||||
'use strict';
|
||||
|
||||
var rlp = require('rlp');
|
||||
|
||||
var BN = require('../node_modules/elliptic/node_modules/bn.js/lib/bn.js');
|
||||
var hash = require('../node_modules/elliptic/node_modules/hash.js/lib/hash.js');
|
||||
|
||||
@@ -2010,6 +2011,14 @@ function getIcapAddress(address) {
|
||||
return 'XE' + ibanChecksum('XE00' + base36) + base36;
|
||||
}
|
||||
|
||||
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
|
||||
function getContractAddress(transaction) {
|
||||
return getAddress('0x' + sha3(rlp.encode([
|
||||
hexOrBuffer(getAddress(transaction.from)),
|
||||
hexOrBuffer(hexlify(transaction.nonce, 'nonce'))
|
||||
])).slice(12).toString('hex'));
|
||||
}
|
||||
|
||||
function cloneObject(object) {
|
||||
var clone = {};
|
||||
for (var key in object) { clone[key] = object[key]; }
|
||||
@@ -2075,6 +2084,8 @@ module.exports = {
|
||||
getAddress: getAddress,
|
||||
getIcapAddress: getIcapAddress,
|
||||
|
||||
getContractAddress: getContractAddress,
|
||||
|
||||
cloneObject: cloneObject,
|
||||
|
||||
bnToBuffer: bnToBuffer,
|
||||
@@ -2088,7 +2099,7 @@ module.exports = {
|
||||
}
|
||||
|
||||
}).call(this,require("buffer").Buffer)
|
||||
},{"../node_modules/elliptic/node_modules/bn.js/lib/bn.js":29,"../node_modules/elliptic/node_modules/hash.js/lib/hash.js":31,"buffer":41}],11:[function(require,module,exports){
|
||||
},{"../node_modules/elliptic/node_modules/bn.js/lib/bn.js":29,"../node_modules/elliptic/node_modules/hash.js/lib/hash.js":31,"buffer":41,"rlp":85}],11:[function(require,module,exports){
|
||||
(function (global,Buffer){
|
||||
'use strict';
|
||||
|
||||
@@ -2203,6 +2214,58 @@ function Wallet(privateKey, provider) {
|
||||
});
|
||||
}
|
||||
|
||||
utils.defineProperty(Wallet, 'parseTransaction', function(rawTransaction) {
|
||||
rawTransaction = utils.hexOrBuffer(rawTransaction, 'rawTransaction');
|
||||
var signedTransaction = rlp.decode(rawTransaction);
|
||||
|
||||
var raw = [];
|
||||
|
||||
var transaction = {};
|
||||
transactionFields.forEach(function(fieldInfo, index) {
|
||||
transaction[fieldInfo.name] = signedTransaction[index];
|
||||
raw.push(signedTransaction[index]);
|
||||
});
|
||||
|
||||
if (transaction.to) {
|
||||
if (transaction.to.length === 0) {
|
||||
delete transaction.to;
|
||||
} else {
|
||||
transaction.to = utils.getAddress('0x' + transaction.to.toString('hex'));
|
||||
}
|
||||
}
|
||||
|
||||
['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function(name) {
|
||||
if (!transaction[name]) { return; }
|
||||
if (transaction[name].length === 0) {
|
||||
transaction[name] = new utils.BN(0);
|
||||
} else {
|
||||
transaction[name] = new utils.BN(transaction[name].toString('hex'), 16);
|
||||
}
|
||||
});
|
||||
|
||||
/* @TODO: Maybe? In the future, all nonces stored as numbers? (obviously, major version change)
|
||||
if (transaction.nonce) {
|
||||
transaction.nonce = transaction.nonce.toNumber()
|
||||
}
|
||||
*/
|
||||
|
||||
if (signedTransaction.length > 6 && signedTransaction[6].length === 1 &&
|
||||
signedTransaction[7].length >= 1 && signedTransaction[7].length <= 32 &&
|
||||
signedTransaction[8].length >= 1 && signedTransaction[7].length <= 32) {
|
||||
|
||||
transaction.v = signedTransaction[6][0];
|
||||
transaction.r = signedTransaction[7];
|
||||
transaction.s = signedTransaction[8];
|
||||
|
||||
var digest = utils.sha3(rlp.encode(raw));
|
||||
try {
|
||||
transaction.from = SigningKey.recover(digest, transaction.r, transaction.s, transaction.v - 27);
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
return transaction;
|
||||
});
|
||||
|
||||
utils.defineProperty(Wallet.prototype, 'getBalance', function(blockNumber) {
|
||||
var provider = this._provider;
|
||||
|
||||
|
||||
4
dist/ethers-wallet.min.js
vendored
4
dist/ethers-wallet.min.js
vendored
File diff suppressed because one or more lines are too long
9
index.js
9
index.js
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var rlp = require('rlp');
|
||||
var scrypt = require('scrypt-js');
|
||||
|
||||
var Contract = require('./lib/contract.js');
|
||||
@@ -24,13 +23,7 @@ utils.defineProperty(exportUtils, 'Buffer', Buffer);
|
||||
utils.defineProperty(exportUtils, 'sha3', utils.sha3);
|
||||
utils.defineProperty(exportUtils, 'sha256', utils.sha256);
|
||||
|
||||
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
|
||||
utils.defineProperty(exportUtils, 'getContractAddress', function(transaction) {
|
||||
return utils.getAddress('0x' + utils.sha3(rlp.encode([
|
||||
utils.hexOrBuffer(utils.getAddress(transaction.from)),
|
||||
utils.hexOrBuffer(utils.hexlify(transaction.nonce, 'nonce'))
|
||||
])).slice(12).toString('hex'));
|
||||
});
|
||||
utils.defineProperty(exportUtils, 'getContractAddress', utils.getContractAddress);
|
||||
|
||||
module.exports = Wallet;
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ utils.defineProperty(secretStorage, 'encrypt', function(privateKey, password, op
|
||||
|
||||
// See: https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
|
||||
var data = {
|
||||
address: address,
|
||||
address: address.substring(2).toLowerCase(),
|
||||
id: uuid.v4({random: uuidRandom}),
|
||||
version: 3,
|
||||
Crypto: {
|
||||
|
||||
@@ -7,6 +7,7 @@ var utils = require('./utils.js');
|
||||
var secp256k1 = new (elliptic.ec)('secp256k1');
|
||||
|
||||
|
||||
|
||||
function SigningKey(privateKey) {
|
||||
if (!(this instanceof SigningKey)) { throw new Error('missing new'); }
|
||||
|
||||
@@ -28,5 +29,10 @@ function SigningKey(privateKey) {
|
||||
});
|
||||
}
|
||||
|
||||
utils.defineProperty(SigningKey, 'recover', function(digest, r, s, recoveryParam) {
|
||||
var publicKey = secp256k1.recoverPubKey(digest, {r: r, s: s}, recoveryParam);
|
||||
publicKey = (new Buffer(publicKey.encode('hex', false), 'hex')).slice(1);
|
||||
return utils.getAddress(utils.sha3(publicKey).slice(12).toString('hex'));
|
||||
});
|
||||
|
||||
module.exports = SigningKey;
|
||||
|
||||
12
lib/utils.js
12
lib/utils.js
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var rlp = require('rlp');
|
||||
|
||||
var BN = require('../node_modules/elliptic/node_modules/bn.js/lib/bn.js');
|
||||
var hash = require('../node_modules/elliptic/node_modules/hash.js/lib/hash.js');
|
||||
|
||||
@@ -312,6 +314,14 @@ function getIcapAddress(address) {
|
||||
return 'XE' + ibanChecksum('XE00' + base36) + base36;
|
||||
}
|
||||
|
||||
// http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
|
||||
function getContractAddress(transaction) {
|
||||
return getAddress('0x' + sha3(rlp.encode([
|
||||
hexOrBuffer(getAddress(transaction.from)),
|
||||
hexOrBuffer(hexlify(transaction.nonce, 'nonce'))
|
||||
])).slice(12).toString('hex'));
|
||||
}
|
||||
|
||||
function cloneObject(object) {
|
||||
var clone = {};
|
||||
for (var key in object) { clone[key] = object[key]; }
|
||||
@@ -377,6 +387,8 @@ module.exports = {
|
||||
getAddress: getAddress,
|
||||
getIcapAddress: getIcapAddress,
|
||||
|
||||
getContractAddress: getContractAddress,
|
||||
|
||||
cloneObject: cloneObject,
|
||||
|
||||
bnToBuffer: bnToBuffer,
|
||||
|
||||
@@ -111,6 +111,58 @@ function Wallet(privateKey, provider) {
|
||||
});
|
||||
}
|
||||
|
||||
utils.defineProperty(Wallet, 'parseTransaction', function(rawTransaction) {
|
||||
rawTransaction = utils.hexOrBuffer(rawTransaction, 'rawTransaction');
|
||||
var signedTransaction = rlp.decode(rawTransaction);
|
||||
|
||||
var raw = [];
|
||||
|
||||
var transaction = {};
|
||||
transactionFields.forEach(function(fieldInfo, index) {
|
||||
transaction[fieldInfo.name] = signedTransaction[index];
|
||||
raw.push(signedTransaction[index]);
|
||||
});
|
||||
|
||||
if (transaction.to) {
|
||||
if (transaction.to.length === 0) {
|
||||
delete transaction.to;
|
||||
} else {
|
||||
transaction.to = utils.getAddress('0x' + transaction.to.toString('hex'));
|
||||
}
|
||||
}
|
||||
|
||||
['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function(name) {
|
||||
if (!transaction[name]) { return; }
|
||||
if (transaction[name].length === 0) {
|
||||
transaction[name] = new utils.BN(0);
|
||||
} else {
|
||||
transaction[name] = new utils.BN(transaction[name].toString('hex'), 16);
|
||||
}
|
||||
});
|
||||
|
||||
/* @TODO: Maybe? In the future, all nonces stored as numbers? (obviously, major version change)
|
||||
if (transaction.nonce) {
|
||||
transaction.nonce = transaction.nonce.toNumber()
|
||||
}
|
||||
*/
|
||||
|
||||
if (signedTransaction.length > 6 && signedTransaction[6].length === 1 &&
|
||||
signedTransaction[7].length >= 1 && signedTransaction[7].length <= 32 &&
|
||||
signedTransaction[8].length >= 1 && signedTransaction[7].length <= 32) {
|
||||
|
||||
transaction.v = signedTransaction[6][0];
|
||||
transaction.r = signedTransaction[7];
|
||||
transaction.s = signedTransaction[8];
|
||||
|
||||
var digest = utils.sha3(rlp.encode(raw));
|
||||
try {
|
||||
transaction.from = SigningKey.recover(digest, transaction.r, transaction.s, transaction.v - 27);
|
||||
} catch (error) { }
|
||||
}
|
||||
|
||||
return transaction;
|
||||
});
|
||||
|
||||
utils.defineProperty(Wallet.prototype, 'getBalance', function(blockNumber) {
|
||||
var provider = this._provider;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ethers-wallet",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.5",
|
||||
"description": "Ethereum wallet library.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"address":"0x17c5185167401eD00cF5F5b2fc97D9BBfDb7D025","id":"01234567-8901-4345-a789-012345678901","version":3,"Crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"deadbeef1deadbeef2deadbeef301234"},"ciphertext":"cea502df4b9405fa2b6d8d19ec4e2953c5ce08e0e01d4c0292512ce62baef8f3","kdf":"scrypt","kdfparams":{"salt":"abcd1abcd2abcd3abcd4abcd5abcd6ef","n":1024,"dklen":32,"p":2,"r":4},"mac":"6e0a8e2409261d464e35a251f4b1fddd6ad0f7045a18d3957c127387f1c0de72"}}
|
||||
{"address":"17c5185167401ed00cf5f5b2fc97d9bbfdb7d025","id":"01234567-8901-4345-a789-012345678901","version":3,"Crypto":{"cipher":"aes-128-ctr","cipherparams":{"iv":"deadbeef1deadbeef2deadbeef301234"},"ciphertext":"cea502df4b9405fa2b6d8d19ec4e2953c5ce08e0e01d4c0292512ce62baef8f3","kdf":"scrypt","kdfparams":{"salt":"abcd1abcd2abcd3abcd4abcd5abcd6ef","n":1024,"dklen":32,"p":2,"r":4},"mac":"6e0a8e2409261d464e35a251f4b1fddd6ad0f7045a18d3957c127387f1c0de72"}}
|
||||
|
||||
@@ -3,8 +3,29 @@ var Wallet = require('../index.js');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
|
||||
module.exports = function(test) {
|
||||
|
||||
function equals(a, b) {
|
||||
if (typeof(a) !== typeof(b)) { return false; }
|
||||
if (Array.isArray(a)) {
|
||||
if (!Array.isArray(b)) { return false; }
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) { return false; }
|
||||
}
|
||||
} else if (typeof(a) === 'object') {
|
||||
if (!equals(Object.keys(a), Object.keys(b))) {
|
||||
return false;
|
||||
}
|
||||
for (var key in a) {
|
||||
if (!equals(a[key], b[key])) { return false; }
|
||||
}
|
||||
} else {
|
||||
return (a === b);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var crowdsale = [
|
||||
{
|
||||
address: '0x2e326fA404Fc3661de4F4361776ed9bBABDC26E3',
|
||||
@@ -87,7 +108,8 @@ module.exports = function(test) {
|
||||
uuid: '0x01234567890123456789012345678901',
|
||||
}).then(function(json) {
|
||||
var jsonWallet = fs.readFileSync('./test-wallets/wallet-test-life.json').toString();
|
||||
test.equal(json, jsonWallet, 'failed to encrypt wallet');
|
||||
test.ok(equals(JSON.parse(json), JSON.parse(jsonWallet)), 'failed to encrypt wallet')
|
||||
//test.equal(json, jsonWallet, 'failed to encrypt wallet');
|
||||
Wallet.decrypt(json, password).then(function(wallet) {
|
||||
test.equal(wallet.privateKey, '0x' + privateKey.toString('hex'), 'decryption failed');
|
||||
resolve();
|
||||
|
||||
@@ -17,9 +17,13 @@ module.exports = function(test) {
|
||||
rawTransaction.sign(privateKey);
|
||||
var ethereumLib = '0x' + rawTransaction.serialize().toString('hex');
|
||||
|
||||
var ethers = (new Wallet(privateKey)).sign(transaction);
|
||||
var wallet = new Wallet(privateKey);
|
||||
var ethers = wallet.sign(transaction);
|
||||
|
||||
test.equal(ethers, ethereumLib, 'invalid transaction');
|
||||
|
||||
// @TODO: More testing on parsed transaction.
|
||||
test.equal(wallet.address, Wallet.parseTransaction(ethers).from, 'invalid parseTransaction');
|
||||
}
|
||||
|
||||
for (var i = 0; i < 10000; i++) {
|
||||
|
||||
Reference in New Issue
Block a user