Skip to content
Merged
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
8 changes: 3 additions & 5 deletions src/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,10 @@ Address.fromBase58Check = function(string) {
Address.fromOutputScript = function(script, network) {
network = network || networks.bitcoin

var type = scripts.classifyOutput(script)
if (scripts.isPubKeyHashOutput(script)) return new Address(script.chunks[2], network.pubKeyHash)
if (scripts.isScriptHashOutput(script)) return new Address(script.chunks[1], network.scriptHash)

if (type === 'pubkeyhash') return new Address(script.chunks[2], network.pubKeyHash)
if (type === 'scripthash') return new Address(script.chunks[1], network.scriptHash)

assert(false, type + ' has no matching Address')
assert(false, script.toASM() + ' has no matching Address')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an API change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so. Why would it?

}

// Export functions
Expand Down
35 changes: 25 additions & 10 deletions src/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function isMultisigOutput(script) {
return pubKeys.every(isCanonicalPubKey)
}

function isNulldataOutput(script) {
function isNullDataOutput(script) {
return script.chunks[0] === ops.OP_RETURN
}

Expand All @@ -127,7 +127,7 @@ function classifyOutput(script) {
return 'multisig'
} else if (isPubKeyOutput(script)) {
return 'pubkey'
} else if (isNulldataOutput(script)) {
} else if (isNullDataOutput(script)) {
return 'nulldata'
}

Expand Down Expand Up @@ -241,20 +241,35 @@ function multisigInput(signatures, scriptPubKey) {
return Script.fromChunks([].concat(ops.OP_0, signatures))
}

function dataOutput(data) {
function nullDataOutput(data) {
return Script.fromChunks([ops.OP_RETURN, data])
}

module.exports = {
classifyInput: classifyInput,
isCanonicalPubKey: isCanonicalPubKey,
isCanonicalSignature: isCanonicalSignature,
isPubKeyHashInput: isPubKeyHashInput,
isPubKeyHashOutput: isPubKeyHashOutput,
isPubKeyInput: isPubKeyInput,
isPubKeyOutput: isPubKeyOutput,
isScriptHashInput: isScriptHashInput,
isScriptHashOutput: isScriptHashOutput,
isMultisigInput: isMultisigInput,
isMultisigOutput: isMultisigOutput,
isNullDataOutput: isNullDataOutput,
classifyOutput: classifyOutput,
dataOutput: dataOutput,
multisigInput: multisigInput,
multisigOutput: multisigOutput,
pubKeyHashInput: pubKeyHashInput,
classifyInput: classifyInput,
pubKeyOutput: pubKeyOutput,
pubKeyHashOutput: pubKeyHashOutput,
scriptHashOutput: scriptHashOutput,
multisigOutput: multisigOutput,
pubKeyInput: pubKeyInput,
pubKeyOutput: pubKeyOutput,
pubKeyHashInput: pubKeyHashInput,
scriptHashInput: scriptHashInput,
scriptHashOutput: scriptHashOutput
multisigInput: multisigInput,
dataOutput: function(data) {
console.warn('dataOutput is deprecated, use nullDataOutput by 2.0.0')
return nullDataOutput(data)
},
nullDataOutput: nullDataOutput
}
24 changes: 12 additions & 12 deletions test/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ describe('Address', function() {
describe('Constructor', function() {
it('does not mutate the input', function() {
fixtures.valid.forEach(function(f) {
var hash = new Buffer(f.hex, 'hex')
var hash = new Buffer(f.hash, 'hex')
var addr = new Address(hash, f.version)

assert.equal(addr.version, f.version)
assert.equal(addr.hash.toString('hex'), f.hex)
assert.equal(addr.hash.toString('hex'), f.hash)
})
})
})

describe('fromBase58Check', function() {
fixtures.valid.forEach(function(f) {
it('imports ' + f.description + '(' + f.network + ') correctly', function() {
it('imports ' + f.script + ' (' + f.network + ') correctly', function() {
var addr = Address.fromBase58Check(f.base58check)

assert.equal(addr.version, f.version)
assert.equal(addr.hash.toString('hex'), f.hex)
assert.equal(addr.hash.toString('hex'), f.hash)
})
})

Expand All @@ -40,18 +40,18 @@ describe('Address', function() {

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

assert.equal(addr.version, f.version)
assert.equal(addr.hash.toString('hex'), f.hex)
assert.equal(addr.hash.toString('hex'), f.hash)
})
})

fixtures.invalid.fromOutputScript.forEach(function(f) {
it('throws when ' + f.description, function() {
var script = Script.fromHex(f.hex)
var script = Script.fromASM(f.script)

assert.throws(function() {
Address.fromOutputScript(script)
Expand All @@ -62,7 +62,7 @@ describe('Address', function() {

describe('toBase58Check', function() {
fixtures.valid.forEach(function(f) {
it('exports ' + f.description + '(' + f.network + ') correctly', function() {
it('exports ' + f.script + ' (' + f.network + ') correctly', function() {
var addr = Address.fromBase58Check(f.base58check)
var result = addr.toBase58Check()

Expand All @@ -73,17 +73,17 @@ describe('Address', function() {

describe('toOutputScript', function() {
fixtures.valid.forEach(function(f) {
it('imports ' + f.description + '(' + f.network + ') correctly', function() {
it('imports ' + f.script + ' (' + f.network + ') correctly', function() {
var addr = Address.fromBase58Check(f.base58check)
var script = addr.toOutputScript()

assert.equal(script.toHex(), f.script)
assert.equal(script.toASM(), f.script)
})
})

fixtures.invalid.toOutputScript.forEach(function(f) {
it('throws when ' + f.description, function() {
var addr = new Address(new Buffer(f.hex, 'hex'), f.version)
var addr = new Address(new Buffer(f.hash, 'hex'), f.version)

assert.throws(function() {
addr.toOutputScript()
Expand Down
34 changes: 15 additions & 19 deletions test/fixtures/address.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
{
"valid": [
{
"description": "pubKeyHash",
"network": "bitcoin",
"version": 0,
"hex": "751e76e8199196d454941c45d1b3a323f1433bd6",
"hash": "751e76e8199196d454941c45d1b3a323f1433bd6",
"base58check": "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH",
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac"
"script": "OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG"
},
{
"description": "scriptHash",
"network": "bitcoin",
"version": 5,
"hex": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6",
"hash": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6",
"base58check": "3LRW7jeCvQCRdPF8S3yUCfRAx4eqXFmdcr",
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687"
"script": "OP_HASH160 cd7b44d0b03f2d026d1e586d7ae18903b0d385f6 OP_EQUAL"
},
{
"description": "pubKeyHash",
"network": "testnet",
"version": 111,
"hex": "751e76e8199196d454941c45d1b3a323f1433bd6",
"hash": "751e76e8199196d454941c45d1b3a323f1433bd6",
"base58check": "mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r",
"script": "76a914751e76e8199196d454941c45d1b3a323f1433bd688ac"
"script": "OP_DUP OP_HASH160 751e76e8199196d454941c45d1b3a323f1433bd6 OP_EQUALVERIFY OP_CHECKSIG"
},
{
"description": "scriptHash",
"network": "testnet",
"version": 196,
"hex": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6",
"hash": "cd7b44d0b03f2d026d1e586d7ae18903b0d385f6",
"base58check": "2NByiBUaEXrhmqAsg7BbLpcQSAQs1EDwt5w",
"script": "a914cd7b44d0b03f2d026d1e586d7ae18903b0d385f687"
"script": "OP_HASH160 cd7b44d0b03f2d026d1e586d7ae18903b0d385f6 OP_EQUAL"
}
],
"invalid": {
Expand All @@ -48,22 +44,22 @@
],
"fromOutputScript": [
{
"description": "pubkey has no matching Address",
"hex": "21031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95ac"
"description": "has no matching Address",
"script": "031f1e68f82112b373f0fe980b3a89d212d2b5c01fb51eb25acb8b4c4b4299ce95 OP_CHECKSIG"
},
{
"description": "multisig has no matching Address",
"hex": "5121032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca330162102308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a52ae"
"description": "has no matching Address",
"script": "OP_TRUE 032487c2a32f7c8d57d2a93906a6457afd00697925b0e6e145d89af6d3bca33016 02308673d16987eaa010e540901cc6fe3695e758c19f46ce604e174dac315e685a OP_2 OP_CHECKMULTISIG"
},
{
"description": "nulldata has no matching Address",
"hex": "6a2606deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474"
"description": "has no matching Address",
"script": "OP_RETURN 06deadbeef03f895a2ad89fb6d696497af486cb7c644a27aa568c7a18dd06113401115185474"
}
],
"toOutputScript": [
{
"description": "24kPZCmVgzfkpGdXExy56234MRHrsqQxNWE has no matching Script",
"hex": "751e76e8199196d454941c45d1b3a323f1433bd6",
"hash": "751e76e8199196d454941c45d1b3a323f1433bd6",
"version": 153
}
]
Expand Down
87 changes: 46 additions & 41 deletions test/fixtures/scripts.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,78 +56,71 @@
}
],
"invalid": {
"classify": [
"isPubKeyHashInput": [
{
"description": "multisig output : OP_CHECKMULTISIG not found",
"description": "pubKeyHash input : extraneous data",
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 ffffffff"
}
],
"isScriptHashInput": [
{
"description": "redeemScript not data",
"scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 OP_RESERVED"
}
],
"isPubKeyInput": [
{
"description": "non-canonical signature",
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf7593ffffffffffffffff"
}
],
"isMultisigOutput": [
{
"description": "OP_CHECKMULTISIG not found",
"scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_HASH160"
},
{
"description": "multisig output : less than 4 chunks",
"description": "less than 4 chunks",
"scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 OP_HASH160"
},
{
"description": "multisig output : m === 0",
"description": "m === 0",
"scriptPubKey": "OP_0 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG"
},
{
"description": "multisig output : m < OP_1",
"description": "m < OP_1",
"scriptPubKey": "OP_1NEGATE 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG"
},
{
"description": "multisig output : m > OP_16",
"description": "m > OP_16",
"scriptPubKey": "OP_NOP 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_2 OP_CHECKMULTISIG"
},
{
"description": "multisig output : n === 0",
"description": "n === 0",
"scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_0 OP_CHECKMULTISIG"
},
{
"description": "multisig output : n < OP_1",
"description": "n < OP_1",
"scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1NEGATE OP_CHECKMULTISIG"
},
{
"description": "multisig output : n > OP_16",
"description": "n > OP_16",
"scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_NOP OP_CHECKMULTISIG"
},
{
"description": "multisig output : n < m",
"description": "n < m",
"scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 OP_1 OP_CHECKMULTISIG"
},
{
"description": "multisig output : n < len(pubKeys)",
"description": "n < len(pubKeys)",
"scriptPubKey": "OP_2 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 02b80011a883a0fd621ad46dfc405df1e74bf075cbaf700fd4aebef6e96f848340 024289801366bcee6172b771cf5a7f13aaecd237a0b9a1ff9d769cabc2e6b70a34 OP_2 OP_CHECKMULTISIG"
},
{
"description": "multisig output : non-canonical pubKey (bad length)",
"description": "non-canonical pubKey (bad length)",
"scriptPubKey": "OP_1 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798ffff OP_1 OP_CHECKMULTISIG"
},
{
"description": "pubKeyHash input : extraneous data",
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 02359c6e3f04cefbf089cf1d6670dc47c3fb4df68e2bad1fa5a369f9ce4b42bbd1 ffffffff"
},
{
"description": "scriptHash input : redeemScript not data",
"scriptSig": "OP_0 304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801 3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501 OP_RESERVED"
},
{
"description": "pubKey input : non-canonical signature",
"scriptSig": "304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf7593ffffffffffffffff"
}
],
"multisig": [
{
"exception": "Not enough pubKeys provided",
"m": 4,
"pubKeys": [
"02ea1297665dd733d444f31ec2581020004892cdaaf3dd6c0107c615afb839785f",
"02fab2dea1458990793f56f42e4a47dbf35a12a351f26fa5d7e0cc7447eaafa21f",
"036c6802ce7e8113723dd92cdb852e492ebb157a871ca532c3cb9ed08248ff0e19"
],
"signatures": [
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801"
],
"scriptPubKey": true
},
"multisigInput": [
{
"exception": "Not enough signatures provided",
"pubKeys": [
Expand All @@ -136,8 +129,7 @@
],
"signatures": [
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801"
],
"scriptPubKey": false
]
},
{
"exception": "Too many signatures provided",
Expand All @@ -149,8 +141,21 @@
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801",
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501",
"3045022100ef253c1faa39e65115872519e5f0a33bbecf430c0f35cf562beabbad4da24d8d02201742be8ee49812a73adea3007c9641ce6725c32cd44ddb8e3a3af460015d140501"
]
}
],
"multisigOutput": [
{
"exception": "Not enough pubKeys provided",
"m": 4,
"pubKeys": [
"02ea1297665dd733d444f31ec2581020004892cdaaf3dd6c0107c615afb839785f",
"02fab2dea1458990793f56f42e4a47dbf35a12a351f26fa5d7e0cc7447eaafa21f",
"036c6802ce7e8113723dd92cdb852e492ebb157a871ca532c3cb9ed08248ff0e19"
],
"scriptPubKey": false
"signatures": [
"304402207515cf147d201f411092e6be5a64a6006f9308fad7b2a8fdaab22cd86ce764c202200974b8aca7bf51dbf54150d3884e1ae04f675637b926ec33bf75939446f6ca2801"
]
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion test/integration/advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe('bitcoinjs-lib (advanced)', function() {
var tx = new bitcoin.TransactionBuilder()

var data = new Buffer('cafedeadbeef', 'hex')
var dataScript = bitcoin.scripts.dataOutput(data)
var dataScript = bitcoin.scripts.nullDataOutput(data)

tx.addInput(unspent.txHash, unspent.index)
tx.addOutput(dataScript, 1000)
Expand Down
Loading