'use strict'; /* jshint maxstatements: 30 */ var should = require('chai').should(); var bitcore = require('..'); var PublicKey = bitcore.PublicKey; var Address = bitcore.Address; var Script = bitcore.Script; var Networks = bitcore.Networks; describe('Address', function() { var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex'); var buf = Buffer.concat([new Buffer([0]), pubkeyhash]); var str = '16VZnHwRhwrExfeHFHGjwrgEMq8VcYPs9r'; it('should throw an error because of missing data', function() { (function() { return new Address(); }).should.throw('First argument is required, please include address data.'); }); it('should throw an error because of bad network param', function() { (function(){ return new Address(PKHLivenet[0], 'main', 'pubkeyhash'); }).should.throw('Second argument must be "livenet" or "testnet".'); }); it('should throw an error because of bad type param', function() { (function() { return new Address(PKHLivenet[0], 'livenet', 'pubkey'); }).should.throw('Third argument must be "pubkeyhash" or "scripthash"'); }); // livenet valid var PKHLivenet = [ '15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', '1A6ut1tWnUq1SEQLMr4ttDh24wcbJ5o9TT', '1BpbpfLdY7oBS9gK7aDXgvMgr1DPvNhEB2', '1Jz2yCRd5ST1p2gUqFB5wsSQfdm3jaFfg7' ]; // livenet p2sh var P2SHLivenet = [ '342ftSRCvFHfCeFFBuz4xwbeqnDw6BGUey', '33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk', '37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3', '3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy' ]; // testnet p2sh var P2SHTestnet = [ '2N7FuwuUuoTBrDFdrAZ9KxBmtqMLxce9i1C', '2NEWDzHWwY5ZZp8CQWbB7ouNMLqCia6YRda', '2MxgPqX1iThW3oZVk9KoFcE5M4JpiETssVN', '2NB72XtkjpnATMggui83aEtPawyyKvnbX2o' ]; //livenet bad checksums var badChecksums = [ '15vkcKf7gB23wLAnZLmbVuMiiVDc3nq4a2', '1A6ut1tWnUq1SEQLMr4ttDh24wcbj4w2TT', '1BpbpfLdY7oBS9gK7aDXgvMgr1DpvNH3B2', '1Jz2yCRd5ST1p2gUqFB5wsSQfdmEJaffg7' ]; //livenet non-base58 var nonBase58 = [ '15vkcKf7g#23wLAnZLmb$uMiiVDc3nq4a2', '1A601ttWnUq1SEQLMr4ttDh24wcbj4w2TT', '1BpbpfLdY7oBS9gK7aIXgvMgr1DpvNH3B2', '1Jz2yCRdOST1p2gUqFB5wsSQfdmEJaffg7' ]; //testnet valid var PKHTestnet = [ 'n28S35tqEMbt6vNad7A5K3mZ7vdn8dZ86X', 'n45x3R2w2jaSC62BMa9MeJCd3TXxgvDEmm', 'mursDVxqNQmmwWHACpM9VHwVVSfTddGsEM', 'mtX8nPZZdJ8d3QNLRJ1oJTiEi26Sj6LQXS' ]; describe('validation', function() { it('should describe this livenet address as an invalid testnet address', function() { var error = Address.getValidationError('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo', 'testnet'); should.exist(error); }); it('should should return a true boolean', function(){ var valid = Address.isValid('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo', 'livenet'); valid.should.equal(true); }); it('should should return a false boolean', function(){ var valid = Address.isValid('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo', 'testnet'); valid.should.equal(false); }); it('should validate addresses', function() { for (var i = 0; i < PKHLivenet.length; i++) { var error = Address.getValidationError(PKHLivenet[i]); should.not.exist(error); } }); it('should validate p2sh addresses', function() { for (var i = 0; i < P2SHLivenet.length; i++) { var error = Address.getValidationError(P2SHLivenet[i]); should.not.exist(error); } }); it('should validate testnet p2sh addresses', function() { for (var i = 0; i < P2SHTestnet.length; i++) { var error = Address.getValidationError(P2SHTestnet[i], 'testnet'); should.not.exist(error); } }); it('should not validate addresses with params', function() { for (var i = 0; i < PKHLivenet.length; i++) { var error = Address.getValidationError(PKHLivenet[i], 'testnet'); should.exist(error); } }); it('should validate addresses with params', function() { for (var i = 0; i < PKHLivenet.length; i++) { var error = Address.getValidationError(PKHLivenet[i], 'livenet'); should.not.exist(error); } }); it('should not validate because of an invalid checksum', function() { for (var i = 0; i < badChecksums.length; i++) { var error = Address.getValidationError(badChecksums[i], 'livenet', 'pubkeyhash'); should.exist(error); error.message.should.equal('Checksum mismatch'); } }); it('should not validate because of mismatched network', function() { for (var i = 0; i < PKHLivenet.length; i++) { var error = Address.getValidationError(PKHLivenet[i], 'testnet', 'pubkeyhash'); should.exist(error); error.message.should.equal('Address has mismatched network type.'); } }); it('should not validate because of a mismatched type', function() { for (var i = 0; i < PKHLivenet.length; i++) { var error = Address.getValidationError(PKHLivenet[i], 'livenet', 'scripthash'); should.exist(error); error.message.should.equal('Address has mismatched type.'); } }); it('should not validate because of non-base58 characters', function() { for (var i = 0; i < nonBase58.length; i++) { var error = Address.getValidationError(nonBase58[i], 'livenet', 'pubkeyhash'); should.exist(error); error.message.should.equal('Non-base58 character'); } }); it('should not validate addresses', function() { for (var i = 0; i < badChecksums.length; i++) { var error = Address.getValidationError(badChecksums[i]); should.exist(error); } }); it('should validate testnet addresses', function() { for (var i = 0; i < PKHTestnet.length; i++) { var error = Address.getValidationError(PKHTestnet[i], 'testnet'); should.not.exist(error); } }); it('should not validate testnet addresses because of mismatched network', function() { for (var i = 0; i < PKHTestnet.length; i++) { var error = Address.getValidationError(PKHTestnet[i], 'livenet', 'pubkeyhash'); should.exist(error); error.message.should.equal('Address has mismatched network type.'); } }); }); describe('encodings', function() { it('should make an address from a buffer', function() { Address.fromBuffer(buf).toString().should.equal(str); new Address(buf).toString().should.equal(str); Address(buf).toString().should.equal(str); }); it('should make an address from a string', function() { Address.fromString(str).toString().should.equal(str); new Address(str).toString().should.equal(str); }); it('should make an address using a non-string network', function() { Address.fromString(str, Networks.livenet).toString().should.equal(str); }); it('should error because of unrecognized data format', function() { (function() { return new Address(new Error()); }).should.throw('First argument is an unrecognized data format.'); }); it('should error because of incorrect format for pubkey hash', function() { (function() { return new Address.fromPublicKeyHash('notahash'); }).should.throw('Address supplied is not a buffer.'); }); it('should error because of incorrect format for script hash', function() { (function() { return new Address.fromScriptHash('notascript'); }).should.throw('Address supplied is not a buffer.'); }); it('should error because of incorrect type for transform buffer', function() { (function() { return Address._transformBuffer('notabuffer'); }).should.throw('Address supplied is not a buffer.'); }); it('should error because of incorrect length buffer for transform buffer', function() { (function() { return Address._transformBuffer(new Buffer(20)); }).should.throw('Address buffers must be exactly 21 bytes.'); }); it('should error because of incorrect type for pubkey transform', function() { (function() { return Address._transformPublicKey(new Buffer(20)); }).should.throw('Address must be an instance of PublicKey.'); }); it('should error because of incorrect type for script transform', function() { (function() { return Address._transformScript(new Buffer(20)); }).should.throw('Address must be an instance of Script.'); }); it('should error because of incorrect type for string transform', function() { (function() { return Address._transformString(new Buffer(20)); }).should.throw('Address supplied is not a string.'); }); it('should make an address from a pubkey hash buffer', function() { var hash = pubkeyhash; //use the same hash Address.fromPublicKeyHash(hash).toString().should.equal(str); var b = Address.fromPublicKeyHash(hash, 'testnet'); b.network.should.equal(Networks.testnet); b.type.should.equal('pubkeyhash'); new Address(hash).toString().should.equal(str); }); it('should make an address using the default network', function() { var hash = pubkeyhash; //use the same hash var a = Address.fromPublicKeyHash(hash); a.network.should.equal(Networks.livenet); // change the default Networks.defaultNetwork = Networks.testnet; var b = Address.fromPublicKeyHash(hash); b.network.should.equal(Networks.testnet); // restore the default Networks.defaultNetwork = Networks.livenet; }); it('should throw an error for invalid length hashBuffer', function() { (function() { return Address.fromPublicKeyHash(buf); }).should.throw('Address hashbuffers must be exactly 20 bytes.'); }); it('should make this address from a compressed pubkey', function() { var pubkey = PublicKey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex')); var address = Address.fromPublicKey(pubkey); address.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke'); }); it('should make this address from an uncompressed pubkey', function() { var pubkey = PublicKey.fromDER(new Buffer('0485e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004833fef26c8be4c4823754869ff4e46755b85d851077771c220e2610496a29d98', 'hex')); var a = Address.fromPublicKey(pubkey, 'livenet'); a.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); var b = new Address(pubkey, 'livenet', 'pubkeyhash'); b.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX'); }); it('should make this address from a script', function() { var s = Script.fromString('OP_CHECKMULTISIG'); var buf = s.toBuffer(); var a = Address.fromScript(s); a.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm'); var b = new Address(s); b.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm'); var c = Address.fromScriptHash(bitcore.crypto.Hash.sha256ripemd160(buf)); c.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm'); }); it('should make this address from other script', function() { var s = Script.fromString('OP_CHECKSIG OP_HASH160'); var a = Address.fromScript(s); a.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7'); var b = new Address(s); b.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7'); }); it('should derive from this known address string livenet', function() { var address = new Address(str); var buffer = address.toBuffer(); var slice = buffer.slice(1); var sliceString = slice.toString('hex'); sliceString.should.equal(pubkeyhash.toString('hex')); }); it('should derive from this known address string testnet', function() { var a = new Address(PKHTestnet[0], 'testnet'); var b = new Address(a.toString()); b.toString().should.equal(PKHTestnet[0]); b.network.should.equal(Networks.testnet); }); it('should derive from this known address string livenet scripthash', function() { var a = new Address(P2SHLivenet[0], 'livenet', 'scripthash'); var b = new Address(a.toString()); b.toString().should.equal(P2SHLivenet[0]); }); it('should derive from this known address string testnet scripthash', function() { var address = new Address(P2SHTestnet[0], 'testnet', 'scripthash'); address = new Address(address.toString()); address.toString().should.equal(P2SHTestnet[0]); }); }); describe('#toBuffer', function() { it('should output this known hash', function() { var address = new Address(str); address.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex')); }); }); describe('#toString', function() { it('should output a livenet pubkeyhash address', function() { var address = new Address(str); address.toString().should.equal(str); }); it('should output a scripthash address', function() { var address = new Address(P2SHLivenet[0]); address.toString().should.equal(P2SHLivenet[0]); }); it('should output a testnet scripthash address', function() { var address = new Address(P2SHTestnet[0]); address.toString().should.equal(P2SHTestnet[0]); }); it('should output a testnet pubkeyhash address', function() { var address = new Address(PKHTestnet[0]); address.toString().should.equal(PKHTestnet[0]); }); }); describe('#inspect', function() { it('should output formatted output correctly', function() { var address = new Address(str); var output = ''; address.inspect().should.equal(output); }); }); describe('questions about the address', function() { it('should detect a P2SH address', function() { new Address(P2SHLivenet[0]).isPayToScriptHash().should.equal(true); new Address(P2SHLivenet[0]).isPayToPublicKeyHash().should.equal(false); new Address(P2SHTestnet[0]).isPayToScriptHash().should.equal(true); new Address(P2SHTestnet[0]).isPayToPublicKeyHash().should.equal(false); }); it('should detect a Pay To PubkeyHash address', function() { new Address(PKHLivenet[0]).isPayToPublicKeyHash().should.equal(true); new Address(PKHLivenet[0]).isPayToScriptHash().should.equal(false); new Address(PKHTestnet[0]).isPayToPublicKeyHash().should.equal(true); new Address(PKHTestnet[0]).isPayToScriptHash().should.equal(false); }); }); });