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. 49
      test/address.js

6
README.md

@ -18,6 +18,12 @@ Bitcoin library for node.js and browsers.
`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
## node.js

2
src/address.js

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

15
src/script.js

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

49
test/address.js

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

Loading…
Cancel
Save