Support instantation with public keys

This commit is contained in:
Alex Beregszaszi 2016-03-23 00:39:20 +00:00
parent 155513d8e9
commit ecbf109a71
3 changed files with 51 additions and 6 deletions

View File

@ -22,7 +22,8 @@ Features not supported:
Constructors:
* `generate([icap])` - create an instance based on a new random key (setting `icap` to true will generate an address suitable for the `ICAP Direct mode`)
* `fromPrivateKey(input)` - create an instance based on a raw key
* `fromPrivateKey(input)` - create an instance based on a raw private key
* `fromPublicKey(input)` - create an instance based on a public key (certain methods will not be available)
* `fromV1(input, password)` - import a wallet (Version 1 of the Ethereum wallet format)
* `fromV3(input, password, [nonStrict])` - import a wallet (Version 3 of the Ethereum wallet format). Set `nonStrict` true to accept files with mixed-caps.
* `fromEthSale(input, password)` - import an Ethereum Pre Sale wallet

View File

@ -13,13 +13,30 @@ function decipherBuffer (decipher, data) {
return Buffer.concat([ decipher.update(data), decipher.final() ])
}
var Wallet = function (priv) {
if (!ethUtil.isValidPrivate(priv)) {
var Wallet = function (priv, pub) {
if (priv && !ethUtil.isValidPrivate(priv)) {
throw new Error('Private key does not satisfy the curve requirements (ie. it is invalid)')
}
this.privKey = priv
this._privKey = priv
this._pubKey = pub
}
Object.defineProperty(Wallet.prototype, 'privKey', {
get: function () {
assert(this._privKey, 'This is a public key only wallet')
return this._privKey
}
})
Object.defineProperty(Wallet.prototype, 'pubKey', {
get: function () {
if (!this._pubKey) {
this._pubKey = ethUtil.privateToPublic(this.privKey)
}
return this._pubKey
}
})
Wallet.generate = function (icapDirect) {
if (icapDirect) {
while (true) {
@ -42,7 +59,7 @@ Wallet.prototype.getPrivateKeyString = function () {
}
Wallet.prototype.getPublicKey = function () {
return ethUtil.privateToPublic(this.privKey)
return this.pubKey
}
Wallet.prototype.getPublicKeyString = function () {
@ -50,7 +67,7 @@ Wallet.prototype.getPublicKeyString = function () {
}
Wallet.prototype.getAddress = function () {
return ethUtil.privateToAddress(this.privKey)
return ethUtil.publicToAddress(this.pubKey)
}
Wallet.prototype.getAddressString = function () {
@ -63,6 +80,8 @@ Wallet.prototype.getChecksumAddressString = function () {
// https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
Wallet.prototype.toV3 = function (password, opts) {
assert(this._privKey, 'This is a public key only wallet')
opts = opts || {}
var salt = opts.salt || crypto.randomBytes(32)
var iv = opts.iv || crypto.randomBytes(16)
@ -140,6 +159,10 @@ Wallet.prototype.toV3String = function (password, opts) {
return JSON.stringify(this.toV3(password, opts))
}
Wallet.fromPublicKey = function (pub) {
return new Wallet(null, pub)
}
Wallet.fromPrivateKey = function (priv) {
return new Wallet(priv)
}

View File

@ -52,6 +52,27 @@ describe('.getChecksumAddressString()', function () {
})
})
describe('public key only wallet', function () {
var pubKey = new Buffer('5d4392f450262b276652c1fc037606abac500f3160830ce9df53aa70d95ce7cfb8b06010b2f3691c78c65c21eb4cf3dfdbfc0745d89b664ee10435bb3a0f906c', 'hex')
it('.fromPublicKey() should work', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getPublicKey().toString('hex'),
'5d4392f450262b276652c1fc037606abac500f3160830ce9df53aa70d95ce7cfb8b06010b2f3691c78c65c21eb4cf3dfdbfc0745d89b664ee10435bb3a0f906c')
})
it('.getAddress() should work', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getAddress().toString('hex'), 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c')
})
it('.getPrivateKey() should fail', function () {
assert.throws(function () {
Wallet.fromPublicKey(pubKey).getPrivateKey()
})
})
it('.toV3() should fail', function () {
assert.throws(function () {
Wallet.fromPublicKey(pubKey).toV3()
})
})
})
describe('.generate()', function () {
it('should generate an account', function () {
assert.equal(Wallet.generate().getPrivateKey().length, 32)