refactor hash and address handling in wallet.

This commit is contained in:
Christopher Jeffrey 2016-05-05 04:30:45 -07:00
parent 079d82e80c
commit eea25052b6
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 113 additions and 95 deletions

View File

@ -157,23 +157,22 @@ Address.prototype.getScript = function getScript() {
if (this.type !== 'multisig') if (this.type !== 'multisig')
return; return;
if (this._script) if (!this._script) {
return this._script; assert(this.keys.length === this.n, 'Not all keys have been added.');
assert(this.keys.length === this.n, 'Not all keys have been added.'); redeem = bcoin.script.createMultisig(this.keys, this.m, this.n);
redeem = bcoin.script.createMultisig(this.keys, this.m, this.n); if (this.witness) {
if (redeem.getSize() > 10000)
throw new Error('Redeem script too large (10000 byte limit).');
} else {
if (redeem.getSize() > 520)
throw new Error('Redeem script too large (520 byte limit).');
}
if (this.witness) { this._script = redeem;
if (redeem.getSize() > 10000)
throw new Error('Redeem script too large (10000 byte limit).');
} else {
if (redeem.getSize() > 520)
throw new Error('Redeem script too large (520 byte limit).');
} }
this._script = redeem;
return this._script; return this._script;
}; };
@ -183,45 +182,45 @@ Address.prototype.getScript = function getScript() {
*/ */
Address.prototype.getProgram = function getProgram() { Address.prototype.getProgram = function getProgram() {
var program; var hash, program;
if (!this.witness) if (!this.witness)
return; return;
if (this._program) if (!this._program) {
return this._program; if (this.type === 'pubkeyhash') {
hash = Address.hash160(this.getPublicKey());
program = bcoin.script.createWitnessProgram(0, hash);
} else if (this.type === 'multisig') {
hash = Address.sha256(this.getScript().encode());
program = bcoin.script.createWitnessProgram(0, hash);
}
if (this.type === 'pubkeyhash') { assert(program);
program = bcoin.script.createWitnessProgram(
0, Address.hash160(this.getPublicKey())); this._program = program;
} else if (this.type === 'multisig') {
program = bcoin.script.createWitnessProgram(
0, Address.sha256(this.getScript().encode()));
} }
assert(program);
this._program = program;
return this._program; return this._program;
}; };
/** /**
* Get address' ripemd160 program scripthash * Get address' ripemd160 program scripthash
* (for witness programs behind a scripthash). * (for witness programs behind a scripthash).
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getProgramHash = function getProgramHash() { Address.prototype.getProgramHash = function getProgramHash(enc) {
if (!this.witness) if (!this.witness)
return; return;
if (this._programHash) if (!this._programHash)
return this._programHash; this._programHash = Address.hash160(this.getProgram().encode());
this._programHash = Address.hash160(this.getProgram().encode()); return enc === 'hex'
? this._programHash.toString('hex')
return this._programHash; : this._programHash;
}; };
/** /**
@ -230,59 +229,66 @@ Address.prototype.getProgramHash = function getProgramHash() {
*/ */
Address.prototype.getProgramAddress = function getProgramAddress() { Address.prototype.getProgramAddress = function getProgramAddress() {
var hash, address;
if (!this.witness) if (!this.witness)
return; return;
if (this._programAddress) if (!this._programAddress) {
return this._programAddress; hash = this.getProgramHash();
address = Address.compileHash(hash, 'scripthash');
this._programAddress = this._programAddress = address;
Address.compileHash(this.getProgramHash(), 'scripthash'); }
return this._programAddress; return this._programAddress;
}; };
/** /**
* Get scripthash. * Get scripthash.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getScriptHash = function getScriptHash() { Address.prototype.getScriptHash = function getScriptHash(enc) {
return this.getScriptHash160(); if (this.witness)
return this.getScriptHash256(enc);
return this.getScriptHash160(enc);
}; };
/** /**
* Get ripemd160 scripthash. * Get ripemd160 scripthash.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getScriptHash160 = function getScriptHash256() { Address.prototype.getScriptHash160 = function getScriptHash256(enc) {
if (this.type !== 'multisig') if (this.type !== 'multisig')
return; return;
if (this._scriptHash160) if (!this._scriptHash160)
return this._scriptHash160; this._scriptHash160 = Address.hash160(this.getScript().encode());
this._scriptHash160 = Address.hash160(this.getScript().encode()); return enc === 'hex'
? this._scriptHash160.toString('hex')
return this._scriptHash160; : this._scriptHash160;
}; };
/** /**
* Get sha256 scripthash. * Get sha256 scripthash.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getScriptHash256 = function getScriptHash256() { Address.prototype.getScriptHash256 = function getScriptHash256(enc) {
if (this.type !== 'multisig') if (this.type !== 'multisig')
return; return;
if (this._scriptHash256) if (!this._scriptHash256)
return this._scriptHash256; this._scriptHash256 = Address.sha256(this.getScript().encode());
this._scriptHash256 = Address.sha256(this.getScript().encode()); return enc === 'hex'
? this._scriptHash256.toString('hex')
return this._scriptHash256; : this._scriptHash256;
}; };
/** /**
@ -291,18 +297,20 @@ Address.prototype.getScriptHash256 = function getScriptHash256() {
*/ */
Address.prototype.getScriptAddress = function getScriptAddress() { Address.prototype.getScriptAddress = function getScriptAddress() {
var hash, address;
if (this.type !== 'multisig') if (this.type !== 'multisig')
return; return;
if (this._scriptAddress) if (!this._scriptAddress) {
return this._scriptAddress; if (this.witness) {
hash = this.getScriptHash256();
if (this.witness) { address = Address.compileHash(hash, 'witnessscripthash', 0);
this._scriptAddress = } else {
Address.compileHash(this.getScriptHash256(), 'witnessscripthash', 0); hash = this.getScriptHash160();
} else { address = Address.compileHash(hash, 'scripthash');
this._scriptAddress = }
Address.compileHash(this.getScriptHash160(), 'scripthash'); this._scriptAddress = address;
} }
return this._scriptAddress; return this._scriptAddress;
@ -310,16 +318,17 @@ Address.prototype.getScriptAddress = function getScriptAddress() {
/** /**
* Get public key hash. * Get public key hash.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getKeyHash = function getKeyHash() { Address.prototype.getKeyHash = function getKeyHash(enc) {
if (this._hash) if (!this._hash)
return this._hash; this._hash = Address.hash160(this.getPublicKey());
this._hash = Address.hash160(this.getPublicKey()); return enc === 'hex'
? this._hash.toString('hex')
return this._hash; : this._hash;
}; };
/** /**
@ -328,26 +337,30 @@ Address.prototype.getKeyHash = function getKeyHash() {
*/ */
Address.prototype.getKeyAddress = function getKeyAddress() { Address.prototype.getKeyAddress = function getKeyAddress() {
if (this._address) var hash, address;
return this._address;
if (this.witness) if (!this._address) {
this._address = Address.compileHash(this.getKeyHash(), 'witnesspubkeyhash', 0); hash = this.getKeyHash();
else if (this.witness)
this._address = Address.compileHash(this.getKeyHash(), 'pubkeyhash'); address = Address.compileHash(hash, 'witnesspubkeyhash', 0);
else
address = Address.compileHash(hash, 'pubkeyhash');
this._address = address;
}
return this._address; return this._address;
}; };
/** /**
* Get hash. * Get hash.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Address.prototype.getHash = function getHash() { Address.prototype.getHash = function getHash(enc) {
if (this.type === 'multisig') if (this.type === 'multisig')
return this.getScriptHash(); return this.getScriptHash(enc);
return this.getKeyHash(); return this.getKeyHash(enc);
}; };
/** /**
@ -362,18 +375,17 @@ Address.prototype.getAddress = function getAddress() {
}; };
Address.prototype._getAddressMap = function _getAddressMap() { Address.prototype._getAddressMap = function _getAddressMap() {
if (this.addressMap) if (!this.addressMap) {
return this.addressMap; this.addressMap = {};
this.addressMap = {}; this.addressMap[this.getKeyAddress()] = true;
this.addressMap[this.getKeyAddress()] = true; if (this.type === 'multisig')
this.addressMap[this.getScriptAddress()] = true;
if (this.type === 'multisig') if (this.witness)
this.addressMap[this.getScriptAddress()] = true; this.addressMap[this.getProgramAddress()] = true;
}
if (this.witness)
this.addressMap[this.getProgramAddress()] = true;
return this.addressMap; return this.addressMap;
}; };

View File

@ -1351,29 +1351,32 @@ Wallet.prototype.getScript = function getScript() {
/** /**
* Get scripthash for current receiving address. * Get scripthash for current receiving address.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getScriptHash = function getScriptHash() { Wallet.prototype.getScriptHash = function getScriptHash(enc) {
return this.receiveAddress.getScriptHash(); return this.receiveAddress.getScriptHash(enc);
}; };
/** /**
* Get ripemd160 scripthash for current receiving address. * Get ripemd160 scripthash for current receiving address.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getScriptHash160 = function getScriptHash160() { Wallet.prototype.getScriptHash160 = function getScriptHash160(enc) {
return this.receiveAddress.getScriptHash160(); return this.receiveAddress.getScriptHash160(enc);
}; };
/** /**
* Get sha256 scripthash for current receiving address. * Get sha256 scripthash for current receiving address.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getScriptHash256 = function getScriptHash256() { Wallet.prototype.getScriptHash256 = function getScriptHash256(enc) {
return this.receiveAddress.getScriptHash256(); return this.receiveAddress.getScriptHash256(enc);
}; };
/** /**
@ -1397,11 +1400,12 @@ Wallet.prototype.getProgram = function getProgram() {
/** /**
* Get current receiving address' ripemd160 program * Get current receiving address' ripemd160 program
* scripthash (for witness programs behind a scripthash). * scripthash (for witness programs behind a scripthash).
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getProgramHash = function getProgramHash() { Wallet.prototype.getProgramHash = function getProgramHash(enc) {
return this.receiveAddress.getProgramHash(); return this.receiveAddress.getProgramHash(enc);
}; };
/** /**
@ -1416,11 +1420,12 @@ Wallet.prototype.getProgramAddress = function getProgramAddress() {
/** /**
* Get public key hash for current receiving address. * Get public key hash for current receiving address.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getKeyHash = function getKeyHash() { Wallet.prototype.getKeyHash = function getKeyHash(enc) {
return this.receiveAddress.getKeyHash(); return this.receiveAddress.getKeyHash(enc);
}; };
/** /**
@ -1434,11 +1439,12 @@ Wallet.prototype.getKeyAddress = function getKeyAddress() {
/** /**
* Get hash for current receiving address. * Get hash for current receiving address.
* @param {String?} enc - `"hex"` or `null`.
* @returns {Buffer} * @returns {Buffer}
*/ */
Wallet.prototype.getHash = function getHash() { Wallet.prototype.getHash = function getHash(enc) {
return this.receiveAddress.getHash(); return this.receiveAddress.getHash(enc);
}; };
/** /**