@opcat-labs/opcat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.yaml +3 -0
- package/index.d.ts +1541 -0
- package/index.js +74 -0
- package/lib/address.js +478 -0
- package/lib/block/block.js +277 -0
- package/lib/block/blockheader.js +295 -0
- package/lib/block/index.js +4 -0
- package/lib/block/merkleblock.js +323 -0
- package/lib/bn.js +3423 -0
- package/lib/crypto/bn.js +278 -0
- package/lib/crypto/ecdsa.js +339 -0
- package/lib/crypto/hash.browser.js +171 -0
- package/lib/crypto/hash.js +2 -0
- package/lib/crypto/hash.node.js +171 -0
- package/lib/crypto/point.js +221 -0
- package/lib/crypto/random.browser.js +28 -0
- package/lib/crypto/random.js +2 -0
- package/lib/crypto/random.node.js +11 -0
- package/lib/crypto/signature.js +325 -0
- package/lib/encoding/base58.js +111 -0
- package/lib/encoding/base58check.js +121 -0
- package/lib/encoding/bufferreader.js +212 -0
- package/lib/encoding/bufferwriter.js +140 -0
- package/lib/encoding/decode-asm.js +24 -0
- package/lib/encoding/decode-hex.js +32 -0
- package/lib/encoding/decode-script-chunks.js +43 -0
- package/lib/encoding/encode-hex.js +284 -0
- package/lib/encoding/is-hex.js +7 -0
- package/lib/encoding/varint.js +75 -0
- package/lib/errors/index.js +54 -0
- package/lib/errors/spec.js +314 -0
- package/lib/hash-cache.js +50 -0
- package/lib/hdprivatekey.js +678 -0
- package/lib/hdpublickey.js +525 -0
- package/lib/message/message.js +191 -0
- package/lib/mnemonic/mnemonic.js +303 -0
- package/lib/mnemonic/pbkdf2.browser.js +68 -0
- package/lib/mnemonic/pbkdf2.js +2 -0
- package/lib/mnemonic/pbkdf2.node.js +68 -0
- package/lib/mnemonic/words/chinese.js +2054 -0
- package/lib/mnemonic/words/english.js +2054 -0
- package/lib/mnemonic/words/french.js +2054 -0
- package/lib/mnemonic/words/index.js +8 -0
- package/lib/mnemonic/words/italian.js +2054 -0
- package/lib/mnemonic/words/japanese.js +2054 -0
- package/lib/mnemonic/words/spanish.js +2054 -0
- package/lib/networks.js +379 -0
- package/lib/opcode.js +255 -0
- package/lib/privatekey.js +374 -0
- package/lib/publickey.js +386 -0
- package/lib/script/index.js +5 -0
- package/lib/script/interpreter.js +1834 -0
- package/lib/script/script.js +1074 -0
- package/lib/script/stack.js +109 -0
- package/lib/script/write-i32-le.js +17 -0
- package/lib/script/write-push-data.js +35 -0
- package/lib/script/write-u16-le.js +12 -0
- package/lib/script/write-u32-le.js +16 -0
- package/lib/script/write-u64-le.js +24 -0
- package/lib/script/write-u8-le.js +8 -0
- package/lib/script/write-varint.js +46 -0
- package/lib/transaction/index.js +7 -0
- package/lib/transaction/input/index.js +5 -0
- package/lib/transaction/input/input.js +354 -0
- package/lib/transaction/input/multisig.js +242 -0
- package/lib/transaction/input/publickey.js +100 -0
- package/lib/transaction/input/publickeyhash.js +118 -0
- package/lib/transaction/output.js +231 -0
- package/lib/transaction/sighash.js +167 -0
- package/lib/transaction/signature.js +97 -0
- package/lib/transaction/transaction.js +1639 -0
- package/lib/transaction/unspentoutput.js +113 -0
- package/lib/util/_.js +47 -0
- package/lib/util/js.js +90 -0
- package/lib/util/preconditions.js +33 -0
- package/package.json +26 -0
- package/test/address.js +509 -0
- package/test/block/block.js +251 -0
- package/test/block/blockheader.js +275 -0
- package/test/block/merklebloack.js +211 -0
- package/test/crypto/bn.js +177 -0
- package/test/crypto/ecdsa.js +391 -0
- package/test/crypto/hash.browser.js +135 -0
- package/test/crypto/hash.js +136 -0
- package/test/crypto/point.js +224 -0
- package/test/crypto/random.js +32 -0
- package/test/crypto/signature.js +409 -0
- package/test/data/bip69.json +215 -0
- package/test/data/bitcoind/base58_keys_invalid.json +52 -0
- package/test/data/bitcoind/base58_keys_valid.json +335 -0
- package/test/data/bitcoind/blocks.json +22 -0
- package/test/data/bitcoind/script_tests.json +3822 -0
- package/test/data/bitcoind/sig_canonical.json +7 -0
- package/test/data/bitcoind/sig_noncanonical.json +36 -0
- package/test/data/bitcoind/tx_invalid.json +445 -0
- package/test/data/bitcoind/tx_valid.json +44 -0
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +14 -0
- package/test/data/blk86756-testnet.json +684 -0
- package/test/data/block.hex +1 -0
- package/test/data/ecdsa.json +230 -0
- package/test/data/merkleblocks.js +488 -0
- package/test/data/messages.json +22 -0
- package/test/data/sighash.json +12 -0
- package/test/data/tx_creation.json +95 -0
- package/test/encoding/base58.js +131 -0
- package/test/encoding/base58check.js +136 -0
- package/test/encoding/bufferreader.js +337 -0
- package/test/encoding/bufferwriter.js +172 -0
- package/test/encoding/varint.js +104 -0
- package/test/hashCache.js +67 -0
- package/test/hdkeys.js +445 -0
- package/test/hdprivatekey.js +332 -0
- package/test/hdpublickey.js +304 -0
- package/test/index.js +16 -0
- package/test/message/message.js +204 -0
- package/test/mnemonic/data/fixtures.json +300 -0
- package/test/mnemonic/mnemonic.js +259 -0
- package/test/mnemonic/mocha.opts +1 -0
- package/test/mnemonic/pbkdf2.test.js +59 -0
- package/test/networks.js +159 -0
- package/test/opcode.js +161 -0
- package/test/privatekey.js +439 -0
- package/test/publickey.js +554 -0
- package/test/script/interpreter.js +734 -0
- package/test/script/script.js +1437 -0
- package/test/transaction/deserialize.js +34 -0
- package/test/transaction/input/input.js +90 -0
- package/test/transaction/input/multisig.js +90 -0
- package/test/transaction/input/publickey.js +68 -0
- package/test/transaction/input/publickeyhash.js +51 -0
- package/test/transaction/output.js +185 -0
- package/test/transaction/sighash.js +65 -0
- package/test/transaction/signature.js +114 -0
- package/test/transaction/transaction.js +1109 -0
- package/test/transaction/unspentoutput.js +110 -0
- package/test/util/js.js +76 -0
- package/test/util/preconditions.js +79 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
var Signature = require('../crypto/signature')
|
|
3
|
+
var Script = require('../script')
|
|
4
|
+
var Output = require('./output')
|
|
5
|
+
var BufferReader = require('../encoding/bufferreader')
|
|
6
|
+
var BufferWriter = require('../encoding/bufferwriter')
|
|
7
|
+
var Hash = require('../crypto/hash')
|
|
8
|
+
var ECDSA = require('../crypto/ecdsa')
|
|
9
|
+
var $ = require('../util/preconditions')
|
|
10
|
+
var _ = require('../util/_')
|
|
11
|
+
|
|
12
|
+
var SIGHASH_SINGLE_BUG = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
|
|
13
|
+
/**
|
|
14
|
+
* Returns a buffer with the which is hashed with sighash that needs to be signed
|
|
15
|
+
* for OP_CHECKSIG.
|
|
16
|
+
*
|
|
17
|
+
* @name Signing.sighash
|
|
18
|
+
* @param {Transaction} transaction the transaction to sign
|
|
19
|
+
* @param {number} sighashType the type of the hash
|
|
20
|
+
* @param {number} inputNumber the input index for the signature
|
|
21
|
+
* @param {Script} subscript the script that will be signed
|
|
22
|
+
* @param {satoshisBN} input's amount (for ForkId signatures)
|
|
23
|
+
*
|
|
24
|
+
*/
|
|
25
|
+
var sighashPreimage = function sighashPreimage (transaction, sighashType, inputNumber) {
|
|
26
|
+
// Check that all inputs have an output, prevent shallow transaction
|
|
27
|
+
_.each(transaction.inputs, function (input) {
|
|
28
|
+
$.checkState(input.output instanceof Output, 'input.output must be an instance of Output')
|
|
29
|
+
})
|
|
30
|
+
$.checkArgument(sighashType === Signature.SIGHASH_ALL, 'only SIGHASH_ALL is supported')
|
|
31
|
+
$.checkArgument(inputNumber < transaction.inputs.length, 'inputNumber must be less than the number of inputs')
|
|
32
|
+
|
|
33
|
+
var nVersion
|
|
34
|
+
var prevouts = []
|
|
35
|
+
var spentScriptHash
|
|
36
|
+
var spentDataHash
|
|
37
|
+
var spentAmount
|
|
38
|
+
var sequence
|
|
39
|
+
var spentAmounts = []
|
|
40
|
+
var spentScriptHashes = []
|
|
41
|
+
var spentDataHashes = []
|
|
42
|
+
var sequences = []
|
|
43
|
+
var outputs = []
|
|
44
|
+
var inputIndex
|
|
45
|
+
var nLockTime
|
|
46
|
+
var sighashTypeBuf
|
|
47
|
+
|
|
48
|
+
const getSeparatedScript = function (script) {
|
|
49
|
+
const separatedScript = new Script(script)
|
|
50
|
+
separatedScript.removeCodeseparators()
|
|
51
|
+
return separatedScript
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// all inputs
|
|
55
|
+
_.each(transaction.inputs, function (input) {
|
|
56
|
+
prevouts.push(input.toPrevout())
|
|
57
|
+
spentAmounts.push(new BufferWriter().writeUInt64LEBN(input.output.satoshisBN).toBuffer())
|
|
58
|
+
spentScriptHashes.push(Hash.sha256(getSeparatedScript(input.output.script).toBuffer()))
|
|
59
|
+
spentDataHashes.push(Hash.sha256(input.output.data))
|
|
60
|
+
sequences.push(new BufferWriter().writeUInt32LE(input.sequenceNumber).toBuffer())
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// current input
|
|
64
|
+
spentScriptHash = Hash.sha256(getSeparatedScript(transaction.inputs[inputNumber].output.script).toBuffer())
|
|
65
|
+
spentDataHash = Hash.sha256(transaction.inputs[inputNumber].output.data)
|
|
66
|
+
spentAmount = new BufferWriter().writeUInt64LEBN(transaction.inputs[inputNumber].output.satoshisBN).toBuffer()
|
|
67
|
+
sequence = new BufferWriter().writeUInt32LE(transaction.inputs[inputNumber].sequenceNumber).toBuffer()
|
|
68
|
+
inputIndex = new BufferWriter().writeUInt32LE(inputNumber).toBuffer()
|
|
69
|
+
sighashTypeBuf = new BufferWriter().writeUInt32LE(sighashType).toBuffer()
|
|
70
|
+
|
|
71
|
+
// all outputs
|
|
72
|
+
_.each(transaction.outputs, function (output) {
|
|
73
|
+
outputs.push(output.toBufferWriter(true).toBuffer())
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// tx.version
|
|
77
|
+
nVersion = new BufferWriter().writeUInt32LE(transaction.version).toBuffer()
|
|
78
|
+
// tx.nLockTime
|
|
79
|
+
nLockTime = new BufferWriter().writeUInt32LE(transaction.nLockTime).toBuffer()
|
|
80
|
+
|
|
81
|
+
let bw = new BufferWriter()
|
|
82
|
+
|
|
83
|
+
bw.write(nVersion)
|
|
84
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...prevouts])))
|
|
85
|
+
bw.write(spentScriptHash)
|
|
86
|
+
bw.write(spentDataHash)
|
|
87
|
+
bw.write(spentAmount)
|
|
88
|
+
bw.write(sequence)
|
|
89
|
+
|
|
90
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...spentAmounts])))
|
|
91
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...spentScriptHashes])))
|
|
92
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...spentDataHashes])))
|
|
93
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...sequences])))
|
|
94
|
+
bw.write(Hash.sha256sha256(Buffer.concat([...outputs])))
|
|
95
|
+
|
|
96
|
+
bw.write(inputIndex)
|
|
97
|
+
bw.write(nLockTime)
|
|
98
|
+
bw.write(sighashTypeBuf)
|
|
99
|
+
|
|
100
|
+
return bw.toBuffer()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Returns a buffer of length 32 bytes with the hash that needs to be signed
|
|
105
|
+
* for OP_CHECKSIG.
|
|
106
|
+
*
|
|
107
|
+
* @name Signing.sighash
|
|
108
|
+
* @param {Transaction} transaction the transaction to sign
|
|
109
|
+
* @param {number} sighashType the type of the hash
|
|
110
|
+
* @param {number} inputNumber the input index for the signature
|
|
111
|
+
*
|
|
112
|
+
*/
|
|
113
|
+
var sighash = function sighash (transaction, sighashType, inputNumber) {
|
|
114
|
+
var preimage = sighashPreimage(transaction, sighashType, inputNumber)
|
|
115
|
+
if (preimage.compare(SIGHASH_SINGLE_BUG) === 0) return preimage
|
|
116
|
+
var ret = Hash.sha256sha256(preimage)
|
|
117
|
+
ret = new BufferReader(ret).readReverse()
|
|
118
|
+
return ret
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a signature
|
|
122
|
+
*
|
|
123
|
+
* @name Signing.sign
|
|
124
|
+
* @param {Transaction} transaction
|
|
125
|
+
* @param {PrivateKey} privateKey
|
|
126
|
+
* @param {number} sighash
|
|
127
|
+
* @param {number} inputIndex
|
|
128
|
+
* @return {Signature}
|
|
129
|
+
*/
|
|
130
|
+
function sign (transaction, privateKey, sighashType, inputIndex) {
|
|
131
|
+
var hashbuf = sighash(transaction, sighashType, inputIndex)
|
|
132
|
+
|
|
133
|
+
var sig = ECDSA.sign(hashbuf, privateKey, 'little').set({
|
|
134
|
+
nhashtype: sighashType
|
|
135
|
+
})
|
|
136
|
+
return sig
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Verify a signature
|
|
141
|
+
*
|
|
142
|
+
* @name Signing.verify
|
|
143
|
+
* @param {Transaction} transaction
|
|
144
|
+
* @param {Signature} signature
|
|
145
|
+
* @param {PublicKey} publicKey
|
|
146
|
+
* @param {number} inputIndex
|
|
147
|
+
* @param {Script} subscript
|
|
148
|
+
* @param {satoshisBN} input's amount
|
|
149
|
+
* @param {flags} verification flags
|
|
150
|
+
* @return {boolean}
|
|
151
|
+
*/
|
|
152
|
+
function verify (transaction, signature, publicKey, inputIndex) {
|
|
153
|
+
$.checkArgument(!_.isUndefined(transaction))
|
|
154
|
+
$.checkArgument(!_.isUndefined(signature) && !_.isUndefined(signature.nhashtype))
|
|
155
|
+
var hashbuf = sighash(transaction, signature.nhashtype, inputIndex)
|
|
156
|
+
return ECDSA.verify(hashbuf, signature, publicKey, 'little')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @namespace Signing
|
|
161
|
+
*/
|
|
162
|
+
module.exports = {
|
|
163
|
+
sighashPreimage: sighashPreimage,
|
|
164
|
+
sighash: sighash,
|
|
165
|
+
sign: sign,
|
|
166
|
+
verify: verify
|
|
167
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var _ = require('../util/_');
|
|
4
|
+
var $ = require('../util/preconditions');
|
|
5
|
+
var inherits = require('inherits');
|
|
6
|
+
var JSUtil = require('../util/js');
|
|
7
|
+
|
|
8
|
+
var PublicKey = require('../publickey');
|
|
9
|
+
var errors = require('../errors');
|
|
10
|
+
var Signature = require('../crypto/signature');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @desc
|
|
14
|
+
* Wrapper around Signature with fields related to signing a transaction specifically
|
|
15
|
+
*
|
|
16
|
+
* @param {Object|string|TransactionSignature} arg
|
|
17
|
+
* @constructor
|
|
18
|
+
*/
|
|
19
|
+
function TransactionSignature(arg) {
|
|
20
|
+
if (!(this instanceof TransactionSignature)) {
|
|
21
|
+
return new TransactionSignature(arg);
|
|
22
|
+
}
|
|
23
|
+
if (arg instanceof TransactionSignature) {
|
|
24
|
+
return arg;
|
|
25
|
+
}
|
|
26
|
+
if (_.isObject(arg)) {
|
|
27
|
+
return this._fromObject(arg);
|
|
28
|
+
}
|
|
29
|
+
throw new errors.InvalidArgument('TransactionSignatures must be instantiated from an object');
|
|
30
|
+
}
|
|
31
|
+
inherits(TransactionSignature, Signature);
|
|
32
|
+
|
|
33
|
+
TransactionSignature.prototype._fromObject = function (arg) {
|
|
34
|
+
this._checkObjectArgs(arg);
|
|
35
|
+
this.publicKey = new PublicKey(arg.publicKey);
|
|
36
|
+
this.prevTxId = Buffer.isBuffer(arg.prevTxId) ? arg.prevTxId : Buffer.from(arg.prevTxId, 'hex');
|
|
37
|
+
this.outputIndex = arg.outputIndex;
|
|
38
|
+
this.inputIndex = arg.inputIndex;
|
|
39
|
+
this.signature =
|
|
40
|
+
arg.signature instanceof Signature
|
|
41
|
+
? arg.signature
|
|
42
|
+
: Buffer.isBuffer(arg.signature)
|
|
43
|
+
? Signature.fromBuffer(arg.signature)
|
|
44
|
+
: Signature.fromString(arg.signature);
|
|
45
|
+
this.sigtype = arg.sigtype;
|
|
46
|
+
return this;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
TransactionSignature.prototype._checkObjectArgs = function (arg) {
|
|
50
|
+
$.checkArgument(PublicKey(arg.publicKey), 'publicKey');
|
|
51
|
+
$.checkArgument(!_.isUndefined(arg.inputIndex), 'inputIndex');
|
|
52
|
+
$.checkArgument(!_.isUndefined(arg.outputIndex), 'outputIndex');
|
|
53
|
+
$.checkState(_.isNumber(arg.inputIndex), 'inputIndex must be a number');
|
|
54
|
+
$.checkState(_.isNumber(arg.outputIndex), 'outputIndex must be a number');
|
|
55
|
+
$.checkArgument(arg.signature, 'signature');
|
|
56
|
+
$.checkArgument(arg.prevTxId, 'prevTxId');
|
|
57
|
+
$.checkState(
|
|
58
|
+
arg.signature instanceof Signature ||
|
|
59
|
+
Buffer.isBuffer(arg.signature) ||
|
|
60
|
+
JSUtil.isHexa(arg.signature),
|
|
61
|
+
'signature must be a buffer or hexa value',
|
|
62
|
+
);
|
|
63
|
+
$.checkState(
|
|
64
|
+
Buffer.isBuffer(arg.prevTxId) || JSUtil.isHexa(arg.prevTxId),
|
|
65
|
+
'prevTxId must be a buffer or hexa value',
|
|
66
|
+
);
|
|
67
|
+
$.checkArgument(arg.sigtype, 'sigtype');
|
|
68
|
+
$.checkState(_.isNumber(arg.sigtype), 'sigtype must be a number');
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Serializes a transaction to a plain JS object
|
|
73
|
+
* @return {Object}
|
|
74
|
+
*/
|
|
75
|
+
TransactionSignature.prototype.toObject = TransactionSignature.prototype.toJSON =
|
|
76
|
+
function toObject() {
|
|
77
|
+
return {
|
|
78
|
+
publicKey: this.publicKey.toString(),
|
|
79
|
+
prevTxId: this.prevTxId.toString('hex'),
|
|
80
|
+
outputIndex: this.outputIndex,
|
|
81
|
+
inputIndex: this.inputIndex,
|
|
82
|
+
signature: this.signature.toString(),
|
|
83
|
+
sigtype: this.sigtype,
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Builds a TransactionSignature from an object
|
|
89
|
+
* @param {Object} object
|
|
90
|
+
* @return {TransactionSignature}
|
|
91
|
+
*/
|
|
92
|
+
TransactionSignature.fromObject = function (object) {
|
|
93
|
+
$.checkArgument(object);
|
|
94
|
+
return new TransactionSignature(object);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
module.exports = TransactionSignature;
|