Provide ECMA5 setters for Address
This commit is contained in:
parent
76cf227513
commit
0cd386d65c
140
lib/address.js
140
lib/address.js
|
@ -23,21 +23,14 @@ function Address(opts) {
|
||||||
if (!(this instanceof Address)) {
|
if (!(this instanceof Address)) {
|
||||||
return new Address(opts);
|
return new Address(opts);
|
||||||
}
|
}
|
||||||
opts = opts || {};
|
opts = objectAssign({}, opts);
|
||||||
objectAssign(this, opts);
|
// Pull out version right away because it may be needed in setters.
|
||||||
this.version = this.version || 4;
|
this.version = popkey(opts, "version") || 4;
|
||||||
assert(this.version <= 4, "Version too high");
|
assert(this.version <= 4, "Version too high");
|
||||||
assert(this.version >= 1, "Version too low");
|
assert(this.version >= 1, "Version too low");
|
||||||
this.stream = this.stream || 1;
|
this.stream = popkey(opts, "stream") || 1;
|
||||||
if (this.ripe) {
|
// Merge remained values.
|
||||||
assertripelen(getripelen(this.ripe), this.version, this.ripe);
|
objectAssign(this, opts);
|
||||||
if (this.ripe.length < 20) {
|
|
||||||
var fullripe = new Buffer(20);
|
|
||||||
fullripe.fill(0);
|
|
||||||
this.ripe.copy(fullripe, 20 - this.ripe.length);
|
|
||||||
this.ripe = fullripe;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,46 +73,16 @@ function getaddrchecksum(data) {
|
||||||
return bmcrypto.sha512(bmcrypto.sha512(data)).slice(0, 4);
|
return bmcrypto.sha512(bmcrypto.sha512(data)).slice(0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get RIPEMD160(SHA512(SIGN_PUBLIC_KEY || ENC_PUBLIC_KEY)).
|
|
||||||
// Arguments could be either private or public keys. Private keys are
|
|
||||||
// **always** 32 bytes in length.
|
|
||||||
function keys2ripe(signKey, encKey) {
|
|
||||||
var signPublicKey, encPublicKey;
|
|
||||||
if (signKey.length === 32) {
|
|
||||||
signPublicKey = bmcrypto.getPublic(signKey);
|
|
||||||
} else {
|
|
||||||
signPublicKey = signKey;
|
|
||||||
}
|
|
||||||
if (encKey.length === 32) {
|
|
||||||
encPublicKey = bmcrypto.getPublic(encKey);
|
|
||||||
} else {
|
|
||||||
encPublicKey = encKey;
|
|
||||||
}
|
|
||||||
var dataToHash = Buffer.concat([signPublicKey, encPublicKey]);
|
|
||||||
return bmcrypto.ripemd160(bmcrypto.sha512(dataToHash));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the ripe hash of the address.
|
* Calculate the ripe hash of the address.
|
||||||
* @param {?Object} opts - Options
|
* @param {?Object} opts - Options
|
||||||
* @return {Buffer} Resulting ripe hash.
|
* @return {Buffer} Resulting ripe hash.
|
||||||
*/
|
*/
|
||||||
Address.prototype.getRipe = function(opts) {
|
Address.prototype.getRipe = function(opts) {
|
||||||
var ripe;
|
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
if (this.ripe) {
|
var ripe = this.ripe;
|
||||||
ripe = this.ripe;
|
|
||||||
} else {
|
|
||||||
var signKey = this.signPrivateKey || this.signPublicKey;
|
|
||||||
assert(signKey, "No signing key");
|
|
||||||
var encKey = this.encPrivateKey || this.encPublicKey;
|
|
||||||
assert(encKey, "No encryption key");
|
|
||||||
ripe = keys2ripe(signKey, encKey);
|
|
||||||
}
|
|
||||||
var ripelen = getripelen(ripe);
|
|
||||||
assertripelen(ripelen, this.version, ripe);
|
|
||||||
if (opts.short) {
|
if (opts.short) {
|
||||||
return ripe.slice(20 - ripelen);
|
return ripe.slice(20 - getripelen(ripe));
|
||||||
} else {
|
} else {
|
||||||
return ripe;
|
return ripe;
|
||||||
}
|
}
|
||||||
|
@ -231,13 +194,8 @@ Address.fromRandom = function(opts) {
|
||||||
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
||||||
len = getripelen(ripe);
|
len = getripelen(ripe);
|
||||||
if (len <= ripelen && checkripelen(len, version)) {
|
if (len <= ripelen && checkripelen(len, version)) {
|
||||||
// TODO(Kagami): Do we need to put all these properties or compute
|
|
||||||
// them manually via ECMA5 getters/setters instead?
|
|
||||||
opts.signPrivateKey = signPrivateKey;
|
opts.signPrivateKey = signPrivateKey;
|
||||||
opts.signPublicKey = signPublicKey;
|
|
||||||
opts.encPrivateKey = encPrivateKey;
|
opts.encPrivateKey = encPrivateKey;
|
||||||
opts.encPublicKey = encPublicKey;
|
|
||||||
opts.ripe = ripe;
|
|
||||||
return new Address(opts);
|
return new Address(opts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,13 +238,8 @@ Address.fromPassphrase = function(opts) {
|
||||||
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
ripe = bmcrypto.ripemd160(bmcrypto.sha512(keysbuf));
|
||||||
len = getripelen(ripe);
|
len = getripelen(ripe);
|
||||||
if (len <= ripelen && checkripelen(len, version)) {
|
if (len <= ripelen && checkripelen(len, version)) {
|
||||||
// TODO(Kagami): Do we need to put all these properties or compute
|
|
||||||
// them manually via ECMA5 getters/setters instead?
|
|
||||||
opts.signPrivateKey = signPrivateKey;
|
opts.signPrivateKey = signPrivateKey;
|
||||||
opts.signPublicKey = signPublicKey;
|
|
||||||
opts.encPrivateKey = encPrivateKey;
|
opts.encPrivateKey = encPrivateKey;
|
||||||
opts.encPublicKey = encPublicKey;
|
|
||||||
opts.ripe = ripe;
|
|
||||||
return new Address(opts);
|
return new Address(opts);
|
||||||
}
|
}
|
||||||
signnonce += 2;
|
signnonce += 2;
|
||||||
|
@ -294,4 +247,81 @@ Address.fromPassphrase = function(opts) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Object.defineProperty(Address.prototype, "signPrivateKey", {
|
||||||
|
get: function() {
|
||||||
|
return this._signPrivateKey;
|
||||||
|
},
|
||||||
|
set: function(signPrivateKey) {
|
||||||
|
this._signPrivateKey = signPrivateKey;
|
||||||
|
// Invalidate cached values;
|
||||||
|
delete this._signPublicKey;
|
||||||
|
delete this._ripe;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Address.prototype, "signPublicKey", {
|
||||||
|
get: function() {
|
||||||
|
if (this._signPublicKey) {
|
||||||
|
return this._signPublicKey;
|
||||||
|
} else if (this.signPrivateKey) {
|
||||||
|
this._signPublicKey = bmcrypto.getPublic(this.signPrivateKey);
|
||||||
|
return this._signPublicKey;
|
||||||
|
} else {
|
||||||
|
throw new Error("No signing key");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function(signPublicKey) {
|
||||||
|
this._signPublicKey = signPublicKey;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Address.prototype, "encPrivateKey", {
|
||||||
|
get: function() {
|
||||||
|
return this._encPrivateKey;
|
||||||
|
},
|
||||||
|
set: function(encPrivateKey) {
|
||||||
|
this._encPrivateKey = encPrivateKey;
|
||||||
|
// Invalidate cached values;
|
||||||
|
delete this._encPublicKey;
|
||||||
|
delete this._ripe;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Address.prototype, "encPublicKey", {
|
||||||
|
get: function() {
|
||||||
|
if (this._encPublicKey) {
|
||||||
|
return this._encPublicKey;
|
||||||
|
} else if (this.encPrivateKey) {
|
||||||
|
this._encPublicKey = bmcrypto.getPublic(this.encPrivateKey);
|
||||||
|
return this._encPublicKey;
|
||||||
|
} else {
|
||||||
|
throw new Error("No encryption key");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set: function(encPublicKey) {
|
||||||
|
this._encPublicKey = encPublicKey;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(Address.prototype, "ripe", {
|
||||||
|
get: function() {
|
||||||
|
if (this._ripe) {
|
||||||
|
return this._ripe;
|
||||||
|
}
|
||||||
|
var dataToHash = Buffer.concat([this.signPublicKey, this.encPublicKey]);
|
||||||
|
this._ripe = bmcrypto.ripemd160(bmcrypto.sha512(dataToHash));
|
||||||
|
return this._ripe;
|
||||||
|
},
|
||||||
|
set: function(ripe) {
|
||||||
|
assertripelen(getripelen(ripe), this.version, ripe);
|
||||||
|
if (ripe.length < 20) {
|
||||||
|
var fullripe = new Buffer(20);
|
||||||
|
fullripe.fill(0);
|
||||||
|
ripe.copy(fullripe, 20 - ripe.length);
|
||||||
|
ripe = fullripe;
|
||||||
|
}
|
||||||
|
this._ripe = ripe;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = Address;
|
module.exports = Address;
|
||||||
|
|
14
test.js
14
test.js
|
@ -581,6 +581,20 @@ describe("High-level classes", function() {
|
||||||
expect(Address.decode(addr)).to.equal(addr);
|
expect(Address.decode(addr)).to.equal(addr);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should provide setters for keys and ripe", function() {
|
||||||
|
var addr = Address();
|
||||||
|
expect(function(){addr.ripe}).to.throw(Error);
|
||||||
|
addr.signPrivateKey = Buffer("71c95d26c716a5e85e9af9efe26fb5f744dc98005a13d05d23ee92c77e038d9f", "hex");
|
||||||
|
expect(addr.signPublicKey.toString("hex")).to.equal("042d391543f574608cbcdfd12a37cc4c74dd36e54510b13a6a1d8b7b1498fb96c92873d33ca17586dace7f5ad0f4532a954061ac06bc5230aed9c8374072546571");
|
||||||
|
expect(function(){addr.ripe}).to.throw(Error);
|
||||||
|
addr.encPrivateKey = Buffer("9f9969c93c2d186787a7653f70e49be34c03c4a853e6ad0c867db0946bc433c6", "hex");
|
||||||
|
expect(addr.encPublicKey.toString("hex")).to.equal("04c6ed1b56f2da97fec1b762d43364566faf082c1e4918ae1dbb41757cad41b03b2cc5087f341414e63f6eee72a1fbf0b5f346a1bb3ba944cad204ca597db2bfc8");
|
||||||
|
expect(addr.ripe.toString("hex")).to.equal("003ab6655de4bd8c603eba9b00dd5970725fdd56");
|
||||||
|
expect(addr.getRipe({short: true}).toString("hex")).to.equal("3ab6655de4bd8c603eba9b00dd5970725fdd56");
|
||||||
|
addr.encPrivateKey = Buffer("009969c93c2d186787a7653f70e49be34c03c4a853e6ad0c867db0946bc433c6", "hex");
|
||||||
|
expect(addr.getRipe({short: true}).toString("hex")).to.equal("69617ddb1946dc327cadffcf33889fed587fc1e7");
|
||||||
|
});
|
||||||
|
|
||||||
// FIXME(Kagami): Don't run it in browser currently because it's
|
// FIXME(Kagami): Don't run it in browser currently because it's
|
||||||
// very slow. This need to be fixed.
|
// very slow. This need to be fixed.
|
||||||
if (allTests && typeof window === "undefined") {
|
if (allTests && typeof window === "undefined") {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user