Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 44 additions & 27 deletions src/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,69 @@ var base58check = require('bs58check')
var networks = require('./networks')
var scripts = require('./scripts')

function fromOutputScript(script, network) {
network = network || networks.bitcoin

var type = scripts.classifyOutput(script)
var version
var hash

if (type === 'pubkeyhash') {
version = network.pubKeyHash
hash = script.chunks[2]

} else if (type === 'scripthash') {
version = network.scriptHash
hash = script.chunks[1]

} else {
assert(false, type + ' has no matching Address')
}

function encode(version, hash) {
var payload = new Buffer(21)
payload.writeUInt8(version, 0)
hash.copy(payload, 1)

return base58check.encode(payload)
}

function toOutputScript(address) {
function decode(address) {
var payload = base58check.decode(address)
var version = payload.readUInt8(0)
var hash = payload.slice(1)
var network

for (var networkName in networks) {
var network = networks[networkName]
var network2 = networks[networkName]

if (version === network.pubKeyHash) {
return scripts.pubKeyHashOutput(hash)

} else if (version === network.scriptHash) {
return scripts.scriptHashOutput(hash)
if (version === network2.pubKeyHash || version === network2.scriptHash) {
network = network2
break
}
}

return {
hash: payload.slice(1),
network: network,
version: version
}
}

function fromOutputScript(script, network) {
network = network || networks.bitcoin

var type = scripts.classifyOutput(script)

switch (type) {
case 'pubkeyhash':
return encode(network.pubKeyHash, script.chunks[2])

case 'scripthash':
return encode(network.scriptHash, script.chunks[1])
}

assert(false, type + ' has no matching Address')
}

function toOutputScript(address) {
var decoded = decode(address)
var network = decoded.network || {}

switch (decoded.version) {
case network.pubKeyHash:
return scripts.pubKeyHashOutput(decoded.hash)

case network.scriptHash:
return scripts.scriptHashOutput(decoded.hash)
}

assert(false, address + ' has no matching Script')
}

module.exports = {
decode: decode,
encode: encode,
fromOutputScript: fromOutputScript,
toOutputScript: toOutputScript
}
7 changes: 2 additions & 5 deletions src/ecpair.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var address = require('./address')
var assert = require('assert')
var base58check = require('bs58check')
var bcrypto = require('./crypto')
Expand Down Expand Up @@ -122,11 +123,7 @@ ECPair.prototype.getAddress = function() {
var hash = bcrypto.hash160(pubKey)
var version = this.network.pubKeyHash

var payload = new Buffer(21)
payload.writeUInt8(version, 0)
hash.copy(payload, 1)

return base58check.encode(payload)
return address.encode(version, hash)
}

ECPair.prototype.getPublicKeyBuffer = function() {
Expand Down
6 changes: 3 additions & 3 deletions src/transaction.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
var address = require('./address')
var assert = require('assert')
var scripts = require('./scripts')

var Address = require('./address')
var ECPair = require('./ecpair')
var ECSignature = require('./ecsignature')
var RawTransaction = require('./raw_transaction')
Expand Down Expand Up @@ -152,7 +152,7 @@ Transaction.prototype.addOutput = function(scriptPubKey, value) {

// Attempt to get a valid script if it's a base58 address
if (typeof scriptPubKey === 'string') {
scriptPubKey = Address.toOutputScript(scriptPubKey)
scriptPubKey = address.toOutputScript(scriptPubKey)
}

return this.tx.addOutput(scriptPubKey, value)
Expand Down Expand Up @@ -241,7 +241,7 @@ Transaction.prototype.sign = function(index, keyPair, redeemScript, hashType) {
hash = this.tx.hashForSignature(index, redeemScript, hashType)

} else {
prevOutScript = prevOutScript || Address.toOutputScript(keyPair.getAddress())
prevOutScript = prevOutScript || address.toOutputScript(keyPair.getAddress())
prevOutType = prevOutType || 'pubkeyhash'

assert.notEqual(prevOutType, 'scripthash', 'PrevOutScript is P2SH, missing redeemScript')
Expand Down
38 changes: 30 additions & 8 deletions test/address.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
var assert = require('assert')
var networks = require('../src/networks')

var Address = require('../src/address')
var address = require('../src/address')
var Script = require('../src/script')

var fixtures = require('./fixtures/address.json')

describe('Address', function() {
describe('address', function() {
describe('decode', function() {
fixtures.valid.forEach(function(f) {
it('decodes ' + f.address + ' correctly', function() {
var decoded = address.decode(f.address)

assert.equal(decoded.version, f.version)
assert.equal(decoded.hash.toString('hex'), f.hash)
assert.equal(decoded.network, networks[f.network])
})
})
})

describe('encode', function() {
fixtures.valid.forEach(function(f) {
it('encoded ' + f.address + ' correctly', function() {
var result = address.encode(f.version, new Buffer(f.hash, 'hex'))

assert.equal(result, f.address)
})
})
})

describe('fromOutputScript', function() {
fixtures.valid.forEach(function(f) {
it('imports ' + f.description + '(' + f.network + ') correctly', function() {
it('transforms ' + f.script + ' (' + f.network + ') to ' + f.address, function() {
var script = Script.fromHex(f.script)
var addr = Address.fromOutputScript(script, networks[f.network])
var addr = address.fromOutputScript(script, networks[f.network])

assert.equal(addr, f.address)
})
Expand All @@ -22,16 +44,16 @@ describe('Address', function() {
var script = Script.fromHex(f.hex)

assert.throws(function() {
Address.fromOutputScript(script)
address.fromOutputScript(script)
}, new RegExp(f.description))
})
})
})

describe('toOutputScript', function() {
fixtures.valid.forEach(function(f) {
it('imports ' + f.description + '(' + f.network + ') correctly', function() {
var script = Address.toOutputScript(f.address)
it('transforms ' + f.address + ' to ' + f.script, function() {
var script = address.toOutputScript(f.address)

assert.equal(script.toHex(), f.script)
})
Expand All @@ -40,7 +62,7 @@ describe('Address', function() {
fixtures.invalid.toOutputScript.forEach(function(f) {
it('throws when ' + f.description, function() {
assert.throws(function() {
Address.toOutputScript(f.address)
address.toOutputScript(f.address)
}, new RegExp(f.description))
})
})
Expand Down
18 changes: 13 additions & 5 deletions test/fixtures/address.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,33 @@
"description": "pubKeyHash",
"network": "bitcoin",
"address": "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH",
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac"
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac",
"version": 0,
"hash": "751e76e8199196d454941c45d1b3a323f1433bd6"
},
{
"description": "scriptHash",
"network": "bitcoin",
"address": "3LRW7jeCvQCRdPF8S3yUCfRAx4eqXFmdcr",
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687"
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687",
"version": 5,
"hash": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6"
},
{
"description": "pubKeyHash",
"network": "testnet",
"address": "mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r",
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac"
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac",
"version": 111,
"hash": "751e76e8199196d454941c45d1b3a323f1433bd6"
},
{
"description": "scriptHash",
"network": "testnet",
"address": "2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w",
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687"
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687",
"version": 196,
"hash": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6"
}
],
"invalid": {
Expand All @@ -47,4 +55,4 @@
}
]
}
}
}
2 changes: 1 addition & 1 deletion test/fixtures/crypto.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
"sha256": "a7fb8276035057ed6479c5f2305a96da100ac43f0ac10f277e5ab8c5457429da"
}
]
}
}