Merge pull request #864 from eordano/feature/getAddress
Add toAddress(network) functionality to scripts
This commit is contained in:
commit
6d1c5d39a3
|
@ -234,9 +234,17 @@ Address._transformScript = function(script, network){
|
|||
if (!script.constructor || (script.constructor.name && script.constructor.name !== 'Script')) {
|
||||
throw new TypeError('Address must be an instance of Script.');
|
||||
}
|
||||
info.network = network || Networks.defaultNetwork;
|
||||
if (script.isScriptHashOut()) {
|
||||
info.hashBuffer = script.getData();
|
||||
info.type = Address.PayToScriptHash;
|
||||
} else if (script.isPublicKeyHashOut()) {
|
||||
info.hashBuffer = script.getData();
|
||||
info.type = Address.PayToPublicKeyHash;
|
||||
} else {
|
||||
info.hashBuffer = Hash.sha256ripemd160(script.toBuffer());
|
||||
info.type = Address.PayToScriptHash;
|
||||
}
|
||||
info.network = network || Networks.defaultNetwork;
|
||||
return info;
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ var Hash = require('../crypto/hash');
|
|||
var Opcode = require('../opcode');
|
||||
var PublicKey = require('../publickey');
|
||||
var Signature = require('../crypto/signature');
|
||||
var Networks = require('../networks');
|
||||
|
||||
var $ = require('../util/preconditions');
|
||||
var _ = require('lodash');
|
||||
|
@ -213,7 +214,7 @@ Script.prototype.inspect = function() {
|
|||
// script classification methods
|
||||
|
||||
/**
|
||||
* @returns true if this is a pay to pubkey hash output script
|
||||
* @returns {boolean} if this is a pay to pubkey hash output script
|
||||
*/
|
||||
Script.prototype.isPublicKeyHashOut = function() {
|
||||
return !!(this.chunks.length === 5 &&
|
||||
|
@ -225,7 +226,7 @@ Script.prototype.isPublicKeyHashOut = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is a pay to public key hash input script
|
||||
* @returns {boolean} if this is a pay to public key hash input script
|
||||
*/
|
||||
Script.prototype.isPublicKeyHashIn = function() {
|
||||
return this.chunks.length === 2 &&
|
||||
|
@ -241,7 +242,7 @@ Script.prototype.getPublicKeyHash = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is a public key output script
|
||||
* @returns {boolean} if this is a public key output script
|
||||
*/
|
||||
Script.prototype.isPublicKeyOut = function() {
|
||||
return this.chunks.length === 2 &&
|
||||
|
@ -251,7 +252,7 @@ Script.prototype.isPublicKeyOut = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is a pay to public key input script
|
||||
* @returns {boolean} if this is a pay to public key input script
|
||||
*/
|
||||
Script.prototype.isPublicKeyIn = function() {
|
||||
return this.chunks.length === 1 &&
|
||||
|
@ -261,7 +262,7 @@ Script.prototype.isPublicKeyIn = function() {
|
|||
|
||||
|
||||
/**
|
||||
* @returns true if this is a p2sh output script
|
||||
* @returns {boolean} if this is a p2sh output script
|
||||
*/
|
||||
Script.prototype.isScriptHashOut = function() {
|
||||
var buf = this.toBuffer();
|
||||
|
@ -272,7 +273,7 @@ Script.prototype.isScriptHashOut = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is a p2sh input script
|
||||
* @returns {boolean} if this is a p2sh input script
|
||||
* Note that these are frequently indistinguishable from pubkeyhashin
|
||||
*/
|
||||
Script.prototype.isScriptHashIn = function() {
|
||||
|
@ -293,7 +294,7 @@ Script.prototype.isScriptHashIn = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is a mutlsig output script
|
||||
* @returns {boolean} if this is a mutlsig output script
|
||||
*/
|
||||
Script.prototype.isMultisigOut = function() {
|
||||
return (this.chunks.length > 3 &&
|
||||
|
@ -307,7 +308,7 @@ Script.prototype.isMultisigOut = function() {
|
|||
|
||||
|
||||
/**
|
||||
* @returns true if this is a multisig input script
|
||||
* @returns {boolean} if this is a multisig input script
|
||||
*/
|
||||
Script.prototype.isMultisigIn = function() {
|
||||
return this.chunks.length >= 2 &&
|
||||
|
@ -320,7 +321,7 @@ Script.prototype.isMultisigIn = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if this is an OP_RETURN data script
|
||||
* @returns {boolean} if this is an OP_RETURN data script
|
||||
*/
|
||||
Script.prototype.isDataOut = function() {
|
||||
return this.chunks.length >= 1 &&
|
||||
|
@ -349,7 +350,7 @@ Script.prototype.getData = function() {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if the script is only composed of data pushing
|
||||
* @returns {boolean} if the script is only composed of data pushing
|
||||
* opcodes or small int opcodes (OP_0, OP_1, ..., OP_16)
|
||||
*/
|
||||
Script.prototype.isPushOnly = function() {
|
||||
|
@ -397,7 +398,7 @@ Script.prototype.classify = function() {
|
|||
|
||||
|
||||
/**
|
||||
* @returns true if script is one of the known types
|
||||
* @returns {boolean} if script is one of the known types
|
||||
*/
|
||||
Script.prototype.isStandard = function() {
|
||||
// TODO: Add BIP62 compliance
|
||||
|
@ -530,7 +531,7 @@ Script.prototype.removeCodeseparators = function() {
|
|||
// high level script builder methods
|
||||
|
||||
/**
|
||||
* @returns a new Multisig output script for given public keys,
|
||||
* @returns {Script} a new Multisig output script for given public keys,
|
||||
* requiring m of those public keys to spend
|
||||
* @param {PublicKey[]} publicKeys - list of all public keys controlling the output
|
||||
* @param {number} threshold - amount of required signatures to spend the output
|
||||
|
@ -568,7 +569,7 @@ Script.buildMultisigOut = function(publicKeys, threshold, opts) {
|
|||
* @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default)
|
||||
* @param {Script=} opts.cachedMultisig don't recalculate the redeemScript
|
||||
*
|
||||
* @returns Script
|
||||
* @returns {Script}
|
||||
*/
|
||||
Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) {
|
||||
$.checkArgument(_.isArray(pubkeys));
|
||||
|
@ -585,7 +586,7 @@ Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns a new pay to public key hash output for the given
|
||||
* @returns {Script} a new pay to public key hash output for the given
|
||||
* address or public key
|
||||
* @param {(Address|PublicKey)} to - destination address or public key
|
||||
*/
|
||||
|
@ -607,7 +608,7 @@ Script.buildPublicKeyHashOut = function(to) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns a new pay to public key output for the given
|
||||
* @returns {Script} a new pay to public key output for the given
|
||||
* public key
|
||||
*/
|
||||
Script.buildPublicKeyOut = function(pubkey) {
|
||||
|
@ -619,7 +620,7 @@ Script.buildPublicKeyOut = function(pubkey) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns a new OP_RETURN script with data
|
||||
* @returns {Script} a new OP_RETURN script with data
|
||||
* @param {(string|Buffer)} to - the data to embed in the output
|
||||
*/
|
||||
Script.buildDataOut = function(data) {
|
||||
|
@ -638,7 +639,7 @@ Script.buildDataOut = function(data) {
|
|||
/**
|
||||
* @param {Script|Address} script - the redeemScript for the new p2sh output.
|
||||
* It can also be a p2sh address
|
||||
* @returns Script new pay to script hash script for given script
|
||||
* @returns {Script} new pay to script hash script for given script
|
||||
*/
|
||||
Script.buildScriptHashOut = function(script) {
|
||||
$.checkArgument(script instanceof Script ||
|
||||
|
@ -674,21 +675,21 @@ Script.buildPublicKeyHashIn = function(publicKey, signature, sigtype) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns Script an empty script
|
||||
* @returns {Script} an empty script
|
||||
*/
|
||||
Script.empty = function() {
|
||||
return new Script();
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns Script a new pay to script hash script that pays to this script
|
||||
* @returns {Script} a new pay to script hash script that pays to this script
|
||||
*/
|
||||
Script.prototype.toScriptHashOut = function() {
|
||||
return Script.buildScriptHashOut(this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return Script a script built from the address
|
||||
* @return {Script} a script built from the address
|
||||
*/
|
||||
Script.fromAddress = function(address) {
|
||||
address = Address(address);
|
||||
|
@ -700,6 +701,18 @@ Script.fromAddress = function(address) {
|
|||
throw new errors.Script.UnrecognizedAddress(address);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Address} the associated address for this script
|
||||
*/
|
||||
Script.prototype.toAddress = function(network) {
|
||||
network = Networks.get(network);
|
||||
$.checkArgument(network, 'Must provide a network');
|
||||
if (this.isPublicKeyHashOut() || this.isScriptHashOut()) {
|
||||
return new Address(this, network);
|
||||
}
|
||||
throw new Error('The script type needs to be PayToPublicKeyHash or PayToScriptHash');
|
||||
};
|
||||
|
||||
/**
|
||||
* Analagous to bitcoind's FindAndDelete. Find and delete equivalent chunks,
|
||||
* typically used with push data chunks. Note that this will find and delete
|
||||
|
@ -725,8 +738,8 @@ Script.prototype.findAndDelete = function(script) {
|
|||
};
|
||||
|
||||
/**
|
||||
* @returns true if the chunk {i} is the smallest way to push that particular data.
|
||||
* Comes from bitcoind's script interpreter CheckMinimalPush function
|
||||
* @returns {boolean} if the chunk {i} is the smallest way to push that particular data.
|
||||
*/
|
||||
Script.prototype.checkMinimalPush = function(i) {
|
||||
var chunk = this.chunks[i];
|
||||
|
|
|
@ -320,6 +320,7 @@ describe('Address', function() {
|
|||
b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
|
||||
});
|
||||
|
||||
describe('from a script', function() {
|
||||
it('should make this address from a script', function() {
|
||||
var s = Script.fromString('OP_CHECKMULTISIG');
|
||||
var buf = s.toBuffer();
|
||||
|
@ -339,6 +340,18 @@ describe('Address', function() {
|
|||
b.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7');
|
||||
});
|
||||
|
||||
it('returns the same address if the script is a pay to public key hash out', function() {
|
||||
var address = '16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX';
|
||||
var script = Script.buildPublicKeyHashOut(new Address(address));
|
||||
Address(script, Networks.livenet).toString().should.equal(address);
|
||||
});
|
||||
it('returns the same address if the script is a pay to script hash out', function() {
|
||||
var address = '3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm';
|
||||
var script = Script.buildScriptHashOut(new Address(address));
|
||||
Address(script, Networks.livenet).toString().should.equal(address);
|
||||
});
|
||||
});
|
||||
|
||||
it('should derive from this known address string livenet', function() {
|
||||
var address = new Address(str);
|
||||
var buffer = address.toBuffer();
|
||||
|
|
|
@ -6,6 +6,7 @@ var bitcore = require('../..');
|
|||
|
||||
var BufferUtil = bitcore.util.buffer;
|
||||
var Script = bitcore.Script;
|
||||
var Networks = bitcore.Networks;
|
||||
var Opcode = bitcore.Opcode;
|
||||
var PublicKey = bitcore.PublicKey;
|
||||
var Address = bitcore.Address;
|
||||
|
@ -590,4 +591,24 @@ describe('Script', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('toAddress', function() {
|
||||
it('for a P2PKH address', function() {
|
||||
var stringAddress = '1NaTVwXDDUJaXDQajoa9MqHhz4uTxtgK14';
|
||||
var address = new Address(stringAddress);
|
||||
var script = new Script(address);
|
||||
script.toAddress(Networks.livenet).toString().should.equal(stringAddress);
|
||||
});
|
||||
it('for a P2SH address', function() {
|
||||
var stringAddress = '3GhtMmAbWrUf6Y8vDxn9ETB14R6V7Br3mt';
|
||||
var address = new Address(stringAddress);
|
||||
var script = new Script(address);
|
||||
script.toAddress(Networks.livenet).toString().should.equal(stringAddress);
|
||||
});
|
||||
it('fails if content is not recognized', function() {
|
||||
expect(function() {
|
||||
return Script().toAddress(Networks.livenet);
|
||||
}).to.throw();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue