Skip to content

Commit ca09849

Browse files
committed
Merge pull request #288 from dcousens/types
Types
2 parents 166053a + 967e724 commit ca09849

12 files changed

+130
-48
lines changed

src/address.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var assert = require('assert')
22
var base58check = require('bs58check')
3+
var enforceType = require('./types')
34
var networks = require('./networks')
45
var scripts = require('./scripts')
56

@@ -13,7 +14,8 @@ function findScriptTypeByVersion(version) {
1314
}
1415

1516
function Address(hash, version) {
16-
assert(Buffer.isBuffer(hash), 'Expected Buffer, got ' + hash)
17+
enforceType('Buffer', hash)
18+
1719
assert.strictEqual(hash.length, 20, 'Invalid hash length')
1820
assert.strictEqual(version & 0xff, version, 'Invalid version byte')
1921

src/ecdsa.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
var assert = require('assert')
22
var crypto = require('./crypto')
3+
var enforceType = require('./types')
34

45
var BigInteger = require('bigi')
56
var ECSignature = require('./ecsignature')
67

78
// https://tools.ietf.org/html/rfc6979#section-3.2
89
function deterministicGenerateK(curve, hash, d) {
9-
assert(Buffer.isBuffer(hash), 'Hash must be a Buffer, not ' + hash)
10+
enforceType('Buffer', hash)
11+
enforceType(BigInteger, d)
12+
13+
// sanity check
1014
assert.equal(hash.length, 32, 'Hash must be 256 bit')
11-
assert(d instanceof BigInteger, 'Private key must be a BigInteger')
1215

1316
var x = d.toBuffer(32)
1417
var k = new Buffer(32)

src/eckey.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var assert = require('assert')
22
var base58check = require('bs58check')
33
var crypto = require('crypto')
44
var ecdsa = require('./ecdsa')
5+
var enforceType = require('./types')
56
var networks = require('./networks')
67

78
var BigInteger = require('bigi')
@@ -46,7 +47,8 @@ ECKey.makeRandom = function(compressed, rng) {
4647
rng = rng || crypto.randomBytes
4748

4849
var buffer = rng(32)
49-
assert(Buffer.isBuffer(buffer), 'Expected Buffer, got ' + buffer)
50+
enforceType('Buffer', buffer)
51+
assert.equal(buffer.length, 32, 'Expected 256-bit Buffer from RNG')
5052

5153
var d = BigInteger.fromBuffer(buffer)
5254
d = d.mod(curve.n)

src/ecpubkey.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var assert = require('assert')
21
var crypto = require('./crypto')
32
var ecdsa = require('./ecdsa')
3+
var enforceType = require('./types')
44
var networks = require('./networks')
55

66
var Address = require('./address')
@@ -9,10 +9,10 @@ var ecurve = require('ecurve')
99
var curve = ecurve.getCurveByName('secp256k1')
1010

1111
function ECPubKey(Q, compressed) {
12-
assert(Q instanceof ecurve.Point, 'Expected Point, got ' + Q)
12+
if (compressed === undefined) compressed = true
1313

14-
if (compressed == undefined) compressed = true
15-
assert.strictEqual(typeof compressed, 'boolean', 'Expected boolean, got ' + compressed)
14+
enforceType(ecurve.Point, Q)
15+
enforceType('Boolean', compressed)
1616

1717
this.compressed = compressed
1818
this.Q = Q

src/ecsignature.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
var assert = require('assert')
2+
var enforceType = require('./types')
3+
24
var BigInteger = require('bigi')
35

46
function ECSignature(r, s) {
5-
assert(r instanceof BigInteger, 'Expected BigInteger, got ' + r)
6-
assert(s instanceof BigInteger, 'Expected BigInteger, got ' + s)
7+
enforceType(BigInteger, r)
8+
enforceType(BigInteger, s)
9+
710
this.r = r
811
this.s = s
912
}

src/hdnode.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var assert = require('assert')
22
var base58check = require('bs58check')
33
var crypto = require('./crypto')
4+
var enforceType = require('./types')
45
var networks = require('./networks')
56

67
var BigInteger = require('bigi')
@@ -30,7 +31,8 @@ function findBIP32ParamsByVersion(version) {
3031
function HDNode(K, chainCode, network) {
3132
network = network || networks.bitcoin
3233

33-
assert(Buffer.isBuffer(chainCode), 'Expected Buffer, got ' + chainCode)
34+
enforceType('Buffer', chainCode)
35+
3436
assert.equal(chainCode.length, 32, 'Expected chainCode length of 32, got ' + chainCode.length)
3537
assert(network.bip32, 'Unknown BIP32 constants for network')
3638

@@ -52,7 +54,8 @@ HDNode.HIGHEST_BIT = 0x80000000
5254
HDNode.LENGTH = 78
5355

5456
HDNode.fromSeedBuffer = function(seed, network) {
55-
assert(Buffer.isBuffer(seed), 'Expected Buffer, got ' + seed)
57+
enforceType('Buffer', seed)
58+
5659
assert(seed.length >= 16, 'Seed should be at least 128 bits')
5760
assert(seed.length <= 64, 'Seed should be at most 512 bits')
5861

src/script.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
var assert = require('assert')
22
var bufferutils = require('./bufferutils')
33
var crypto = require('./crypto')
4+
var enforceType = require('./types')
45
var opcodes = require('./opcodes')
56

67
function Script(buffer, chunks) {
7-
assert(Buffer.isBuffer(buffer), 'Expected Buffer, got ' + buffer)
8-
assert(Array.isArray(chunks), 'Expected Array, got ' + chunks)
8+
enforceType('Buffer', buffer)
9+
enforceType('Array', chunks)
910

1011
this.buffer = buffer
1112
this.chunks = chunks
@@ -55,7 +56,7 @@ Script.fromBuffer = function(buffer) {
5556
}
5657

5758
Script.fromChunks = function(chunks) {
58-
assert(Array.isArray(chunks), 'Expected Array, got ' + chunks)
59+
enforceType('Array', chunks)
5960

6061
var bufferSize = chunks.reduce(function(accum, chunk) {
6162
if (Buffer.isBuffer(chunk)) {

src/scripts.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var assert = require('assert')
2+
var enforceType = require('./types')
23
var opcodes = require('./opcodes')
34

45
// FIXME: use ECPubKey, currently the circular dependency breaks everything.
@@ -18,7 +19,7 @@ var ECSignature = require('./ecsignature')
1819
var Script = require('./script')
1920

2021
function classifyOutput(script) {
21-
assert(script instanceof Script, 'Expected Script, got ', script)
22+
enforceType(Script, script)
2223

2324
if (isPubKeyHashOutput.call(script)) {
2425
return 'pubkeyhash'
@@ -36,7 +37,7 @@ function classifyOutput(script) {
3637
}
3738

3839
function classifyInput(script) {
39-
assert(script instanceof Script, 'Expected Script, got ', script)
40+
enforceType(Script, script)
4041

4142
if (isPubKeyHashInput.call(script)) {
4243
return 'pubkeyhash'
@@ -171,7 +172,7 @@ function pubKeyOutput(pubKey) {
171172

172173
// OP_DUP OP_HASH160 {pubKeyHash} OP_EQUALVERIFY OP_CHECKSIG
173174
function pubKeyHashOutput(hash) {
174-
assert(Buffer.isBuffer(hash), 'Expected Buffer, got ' + hash)
175+
enforceType('Buffer', hash)
175176

176177
return Script.fromChunks([
177178
opcodes.OP_DUP,
@@ -184,7 +185,7 @@ function pubKeyHashOutput(hash) {
184185

185186
// OP_HASH160 {scriptHash} OP_EQUAL
186187
function scriptHashOutput(hash) {
187-
assert(Buffer.isBuffer(hash), 'Expected Buffer, got ' + hash)
188+
enforceType('Buffer', hash)
188189

189190
return Script.fromChunks([
190191
opcodes.OP_HASH160,
@@ -195,7 +196,8 @@ function scriptHashOutput(hash) {
195196

196197
// m [pubKeys ...] n OP_CHECKMULTISIG
197198
function multisigOutput(m, pubKeys) {
198-
assert(Array.isArray(pubKeys), 'Expected Array, got ' + pubKeys)
199+
enforceType('Array', pubKeys)
200+
199201
assert(pubKeys.length >= m, 'Not enough pubKeys provided')
200202

201203
var pubKeyBuffers = pubKeys.map(function(pubKey) {
@@ -213,14 +215,14 @@ function multisigOutput(m, pubKeys) {
213215

214216
// {signature}
215217
function pubKeyInput(signature) {
216-
assert(Buffer.isBuffer(signature), 'Expected Buffer, got ' + signature)
218+
enforceType('Buffer', signature)
217219

218220
return Script.fromChunks([signature])
219221
}
220222

221223
// {signature} {pubKey}
222224
function pubKeyHashInput(signature, pubKey) {
223-
assert(Buffer.isBuffer(signature), 'Expected Buffer, got ' + signature)
225+
enforceType('Buffer', signature)
224226

225227
return Script.fromChunks([signature, pubKey.toBuffer()])
226228
}

src/transaction.js

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
var assert = require('assert')
22
var bufferutils = require('./bufferutils')
33
var crypto = require('./crypto')
4+
var enforceType = require('./types')
45
var opcodes = require('./opcodes')
56
var scripts = require('./scripts')
67

78
var Address = require('./address')
89
var ECSignature = require('./ecsignature')
910
var Script = require('./script')
1011

11-
Transaction.DEFAULT_SEQUENCE = 0xffffffff
12-
Transaction.SIGHASH_ALL = 0x01
13-
Transaction.SIGHASH_NONE = 0x02
14-
Transaction.SIGHASH_SINGLE = 0x03
15-
Transaction.SIGHASH_ANYONECANPAY = 0x80
16-
1712
function Transaction() {
1813
this.version = 1
1914
this.locktime = 0
2015
this.ins = []
2116
this.outs = []
2217
}
2318

19+
Transaction.DEFAULT_SEQUENCE = 0xffffffff
20+
Transaction.SIGHASH_ALL = 0x01
21+
Transaction.SIGHASH_NONE = 0x02
22+
Transaction.SIGHASH_SINGLE = 0x03
23+
Transaction.SIGHASH_ANYONECANPAY = 0x80
24+
2425
/**
2526
* Create a new txin.
2627
*
@@ -31,26 +32,23 @@ function Transaction() {
3132
*
3233
* Note that this method does not sign the created input.
3334
*/
34-
Transaction.prototype.addInput = function(tx, index, sequence) {
35-
if (sequence == undefined) sequence = Transaction.DEFAULT_SEQUENCE
35+
Transaction.prototype.addInput = function(hash, index, sequence) {
36+
if (sequence === undefined) sequence = Transaction.DEFAULT_SEQUENCE
3637

37-
var hash
38-
39-
if (typeof tx === 'string') {
38+
if (typeof hash === 'string') {
4039
// TxId hex is big-endian, we need little-endian
41-
hash = bufferutils.reverse(new Buffer(tx, 'hex'))
40+
hash = bufferutils.reverse(new Buffer(hash, 'hex'))
4241

43-
} else if (tx instanceof Transaction) {
44-
hash = tx.getHash()
42+
} else if (hash instanceof Transaction) {
43+
hash = hash.getHash()
4544

46-
} else {
47-
hash = tx
4845
}
4946

50-
assert(Buffer.isBuffer(hash), 'Expected Transaction, txId or txHash, got ' + tx)
47+
enforceType('Buffer', hash)
48+
enforceType('Number', index)
49+
enforceType('Number', sequence)
50+
5151
assert.equal(hash.length, 32, 'Expected hash length of 32, got ' + hash.length)
52-
assert(isFinite(index), 'Expected number index, got ' + index)
53-
assert(isFinite(sequence), 'Expected number sequence, got ' + sequence)
5452

5553
// Add the input and return the input's index
5654
return (this.ins.push({
@@ -81,8 +79,8 @@ Transaction.prototype.addOutput = function(scriptPubKey, value) {
8179
scriptPubKey = scriptPubKey.toOutputScript()
8280
}
8381

84-
assert(scriptPubKey instanceof Script, 'Expected Address or Script, got ' + scriptPubKey)
85-
assert(isFinite(value), 'Expected number value, got ' + value)
82+
enforceType(Script, scriptPubKey)
83+
enforceType('Number', value)
8684

8785
// Add the output and return the output's index
8886
return (this.outs.push({
@@ -172,9 +170,12 @@ Transaction.prototype.hashForSignature = function(inIndex, prevOutScript, hashTy
172170
prevOutScript = tmp
173171
}
174172

173+
enforceType('Number', inIndex)
174+
enforceType(Script, prevOutScript)
175+
enforceType('Number', hashType)
176+
175177
assert(inIndex >= 0, 'Invalid vin index')
176178
assert(inIndex < this.ins.length, 'Invalid vin index')
177-
assert(prevOutScript instanceof Script, 'Invalid Script object')
178179

179180
var txTmp = this.clone()
180181
var hashScript = prevOutScript.without(opcodes.OP_CODESEPARATOR)

src/types.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module.exports = function enforce(type, value) {
2+
switch (type) {
3+
case 'Array': {
4+
if (Array.isArray(value)) return
5+
break
6+
}
7+
8+
case 'Boolean': {
9+
if (typeof value === 'boolean') return
10+
break
11+
}
12+
13+
case 'Buffer': {
14+
if (Buffer.isBuffer(value)) return
15+
break
16+
}
17+
18+
case 'Number': {
19+
if (typeof value === 'number') return
20+
break
21+
}
22+
23+
case 'String': {
24+
if (typeof value === 'string') return
25+
break
26+
}
27+
28+
default: {
29+
if (value instanceof type) return
30+
}
31+
}
32+
33+
throw new TypeError('Expected ' + (type.name || type) + ', got ' + value)
34+
}

src/wallet.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var assert = require('assert')
22
var bufferutils = require('./bufferutils')
33
var crypto = require('crypto')
4+
var enforceType = require('./types')
45
var networks = require('./networks')
56

67
var Address = require('./address')
@@ -300,15 +301,17 @@ Wallet.prototype.setUnspentOutputs = function(unspents) {
300301
index = unspent.outputIndex
301302
}
302303

303-
assert.equal(typeof txId, 'string', 'Expected txId, got ' + txId)
304+
enforceType('String', txId)
305+
enforceType('Number', index)
306+
enforceType('Number', unspent.value)
307+
304308
assert.equal(txId.length, 64, 'Expected valid txId, got ' + txId)
305309
assert.doesNotThrow(function() { Address.fromBase58Check(unspent.address) }, 'Expected Base58 Address, got ' + unspent.address)
306-
assert(isFinite(index), 'Expected number index, got ' + index)
307-
assert.equal(typeof unspent.value, 'number', 'Expected number value, got ' + unspent.value)
310+
assert(isFinite(index), 'Expected finite index, got ' + index)
308311

309312
// FIXME: remove branch in 2.0.0
310313
if (unspent.confirmations !== undefined) {
311-
assert.equal(typeof unspent.confirmations, 'number', 'Expected number confirmations, got ' + unspent.confirmations)
314+
enforceType('Number', unspent.confirmations)
312315
}
313316

314317
var txHash = bufferutils.reverse(new Buffer(txId, 'hex'))

0 commit comments

Comments
 (0)