Browse Source

* Fixes address.js to be able to deal with testnet P2SH addresses

* Enhanced address.js testsuite...now also verifies address versions
* Enhances README to show how to run test suite
hk-custom-address
xnova 11 years ago
parent
commit
786198f130
  1. 6
      README.md
  2. 2
      src/address.js
  3. 15
      src/script.js
  4. 51
      test/address.js

6
README.md

@ -18,6 +18,12 @@ Bitcoin library for node.js and browsers.
`npm run-script compile` `npm run-script compile`
## Run the test suite
First install `mocha` (e.g. `npm install -g mocha` ).
Then, just run `mocha` at the root of the `bitcoinjs-lib` checkout directory.
# Usage # Usage
## node.js ## node.js

2
src/address.js

@ -12,7 +12,7 @@ var Address = function (bytes, version) {
} }
else if (typeof bytes === 'string') { else if (typeof bytes === 'string') {
this.hash = this.hash =
bytes.length <= 34 ? base58.checkDecode(bytes) bytes.length <= 35 ? base58.checkDecode(bytes)
: bytes.length <= 40 ? conv.hexToBytes(bytes) : bytes.length <= 40 ? conv.hexToBytes(bytes)
: util.error('Bad input'); : util.error('Bad input');

15
src/script.js

@ -2,6 +2,7 @@ var Opcode = require('./opcode');
var util = require('./util'); var util = require('./util');
var conv = require('./convert'); var conv = require('./convert');
var Address = require('./address'); var Address = require('./address');
var network = require('./network');
var Script = function(data) { var Script = function(data) {
this.buffer = data || []; this.buffer = data || [];
@ -295,19 +296,19 @@ Script.prototype.writeBytes = function(data) {
Script.createOutputScript = function(address) { Script.createOutputScript = function(address) {
var script = new Script(); var script = new Script();
address = new Address(address); address = new Address(address);
// Standard pay-to-pubkey-hash if (address.version == network.mainnet.p2shVersion || address.version == network.testnet.p2shVersion) {
if (!address.version) { // Standard pay-to-script-hash
script.writeOp(Opcode.map.OP_DUP);
script.writeOp(Opcode.map.OP_HASH160); script.writeOp(Opcode.map.OP_HASH160);
script.writeBytes(address.hash); script.writeBytes(address.hash);
script.writeOp(Opcode.map.OP_EQUALVERIFY); script.writeOp(Opcode.map.OP_EQUAL);
script.writeOp(Opcode.map.OP_CHECKSIG);
} }
// Standard pay-to-script-hash
else { else {
// Standard pay-to-pubkey-hash
script.writeOp(Opcode.map.OP_DUP);
script.writeOp(Opcode.map.OP_HASH160); script.writeOp(Opcode.map.OP_HASH160);
script.writeBytes(address.hash); script.writeBytes(address.hash);
script.writeOp(Opcode.map.OP_EQUAL); script.writeOp(Opcode.map.OP_EQUALVERIFY);
script.writeOp(Opcode.map.OP_CHECKSIG);
} }
return script; return script;
}; };

51
test/address.js

@ -1,6 +1,7 @@
/* global describe, it */ /* global describe, it */
var assert = require('assert'); var assert = require('assert');
var Address = require('../src/address.js'); var Address = require('../src/address.js');
var network = require('../src/network.js');
describe('Address', function() { describe('Address', function() {
describe('toString', function() { describe('toString', function() {
@ -12,41 +13,47 @@ describe('Address', function() {
describe('validate', function() { describe('validate', function() {
it('validates known good addresses', function() { it('validates known good addresses', function() {
function validate(addr) { function validate(addr, expectedVersion) {
assert.ok(Address.validate(addr)); assert.ok(Address.validate(addr));
var address = new Address(addr);
assert.ok(address.version == expectedVersion);
} }
validate('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'); validate('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', network.mainnet.addressVersion);
// validate('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'mainnet'); validate('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', network.testnet.addressVersion);
validate('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef');
// validate('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', 'testnet');
validate('12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP'); validate('12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP', network.mainnet.addressVersion);
validate('12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y'); validate('12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y', network.mainnet.addressVersion);
validate('1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs'); validate('1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs', network.mainnet.addressVersion);
validate('1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez'); validate('1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez', network.mainnet.addressVersion);
validate('116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd'); validate('116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd', network.mainnet.addressVersion);
// p2sh addresses // p2sh addresses
validate('3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt'); validate('3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt', network.mainnet.p2shVersion);
// validate('3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt', 'mainnet'); validate('2MxKEf2su6FGAUfCEAHreGFQvEYrfYNHvL7', network.testnet.p2shVersion);
validate('2MxKEf2su6FGAUfCEAHreGFQvEYrfYNHvL7');
// validate('2MxKEf2su6FGAUfCEAHreGFQvEYrfYNHvL7', 'testnet');
}) })
it('does not validate illegal examples', function() { it('does not validate illegal examples', function() {
function invalid(addr) { function invalid(addr) {
assert.ok(!Address.validate(addr)); assert.ok(!Address.validate(addr));
} }
function invalidNetwork(addr, unexpectedVersion) {
assert.ok(Address.validate(addr)); //must be a valid address itself
if(addr.length >= 34 && unexpectedVersion !== undefined) {
var address = new Address(addr);
if(unexpectedVersion !== undefined)
assert.ok(address.version != unexpectedVersion);
}
}
invalid(''); invalid(''); //empty should be invalid
invalid('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhe'); invalid('%%@'); // invalid base58 string
invalid('1A1zP1eP5QGefi2DzPTf2L5SLmv7DivfNz'); // bad address (doesn't checksum)
// invalid('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'testnet'); invalid('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhe'); // bad address (doesn't checksum)
// invalid('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', 'mainnet');
//and test for the wrong networks
// invalid base58 string invalidNetwork('mzBc4XEFSdzCDcTxAgf6EZXgsZWpztRhef', network.mainnet.addressVersion);
invalid('%%@'); invalidNetwork('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', network.testnet.addressVersion);
}) })
}) })
}) })

Loading…
Cancel
Save