From dcf8fffa3a26f6259f38274178b6a3f104be18c3 Mon Sep 17 00:00:00 2001 From: Micah Maphet Date: Tue, 18 Aug 2026 13:23:45 -0400 Subject: [PATCH 1/4] lib bug fixes and a lot of linting --- packages/bitcore-lib-cash/index.js | 8 +- .../lib/script/interpreter.js | 1171 ++++++++--------- .../lib/transaction/transaction.js | 4 +- .../bitcore-lib-doge/lib/block/blockheader.js | 54 +- packages/bitcore-lib-doge/lib/crypto/hash.js | 32 +- .../lib/script/interpreter.js | 228 ++-- .../lib/transaction/input/publickeyhash.js | 28 +- packages/bitcore-lib-ltc/lib/networks.js | 15 +- .../bitcore-lib-ltc/lib/script/interpreter.js | 230 ++-- .../lib/transaction/input/publickeyhash.js | 35 +- .../bitcore-lib/lib/script/interpreter.js | 5 +- .../lib/transaction/input/publickeyhash.js | 27 +- .../bitcore-lib/lib/transaction/output.js | 17 +- 13 files changed, 918 insertions(+), 936 deletions(-) diff --git a/packages/bitcore-lib-cash/index.js b/packages/bitcore-lib-cash/index.js index a562c53b439..32bbb79c7bd 100644 --- a/packages/bitcore-lib-cash/index.js +++ b/packages/bitcore-lib-cash/index.js @@ -4,11 +4,12 @@ var bitcore = module.exports; // module information bitcore.version = 'v' + require('./package.json').version; + bitcore.versionGuard = function(version) { if (version !== undefined) { - var message = 'More than one instance of bitcore-lib-cash found. ' + - 'Please make sure to require bitcore-lib and check that submodules do' + - ' not also include their own bitcore-lib dependency.'; + const message = 'More than one instance of bitcore-lib-cash found. ' + + 'Please make sure to require bitcore-lib-cash and check that submodules do' + + ' not also include their own bitcore-lib-cash dependency.'; throw new Error(message); } }; @@ -64,6 +65,7 @@ bitcore.Unit = require('./lib/unit'); bitcore.deps = {}; bitcore.deps.bnjs = require('bn.js'); bitcore.deps.bs58 = require('bs58'); + bitcore.deps.Buffer = Buffer; bitcore.deps.elliptic = require('elliptic'); bitcore.deps._ = require('lodash'); diff --git a/packages/bitcore-lib-cash/lib/script/interpreter.js b/packages/bitcore-lib-cash/lib/script/interpreter.js index bce9347f9d2..28e057e183e 100644 --- a/packages/bitcore-lib-cash/lib/script/interpreter.js +++ b/packages/bitcore-lib-cash/lib/script/interpreter.js @@ -1,16 +1,15 @@ 'use strict'; var _ = require('lodash'); - -var Script = require('./script'); -var Opcode = require('../opcode'); var BN = require('../crypto/bn'); -var Hash = require('../crypto/hash'); -var Signature = require('../crypto/signature'); -var PublicKey = require('../publickey'); var ECDSA = require('../crypto/ecdsa'); +var Hash = require('../crypto/hash'); var Schnorr = require('../crypto/schnorr'); +var Signature = require('../crypto/signature'); var BufferWriter = require('../encoding/bufferwriter'); +var Opcode = require('../opcode'); +var PublicKey = require('../publickey'); +var Script = require('./script'); @@ -51,7 +50,7 @@ var Interpreter = function Interpreter(obj) { * Translated from bitcoind's VerifyScript */ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, satoshisBN) { - var Transaction = require('../transaction'); + const Transaction = require('../transaction'); this.nSigChecks = 0; @@ -86,7 +85,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, flags: flags, satoshisBN: satoshisBN, }); - var stackCopy; + let stackCopy; if ((flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY) !== 0 && !scriptSig.isPushOnly()) { this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'; @@ -102,7 +101,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, stackCopy = this.stack.slice(); } - var stack = this.stack; + const stack = this.stack; this.initialize(); this.set({ script: scriptPubkey, @@ -123,7 +122,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, return false; } - var buf = this.stack[this.stack.length - 1]; + const buf = this.stack[this.stack.length - 1]; if (!Interpreter.castToBool(buf)) { this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'; return false; @@ -145,8 +144,8 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, throw new Error('internal error - stack copy empty'); } - var redeemScriptSerialized = stackCopy[stackCopy.length - 1]; - var redeemScript = Script.fromBuffer(redeemScriptSerialized); + const redeemScriptSerialized = stackCopy[stackCopy.length - 1]; + const redeemScript = Script.fromBuffer(redeemScriptSerialized); stackCopy.pop(); this.initialize(); @@ -186,17 +185,17 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, // a clean stack (the P2SH inputs remain). The same holds for witness // evaluation. if ((flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) { - // Disallow CLEANSTACK without P2SH, as otherwise a switch - // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a - // softfork (and P2SH should be one). - if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) { - throw new Error('internal error - CLEANSTACK without P2SH'); - } + // Disallow CLEANSTACK without P2SH, as otherwise a switch + // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a + // softfork (and P2SH should be one). + if ((flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) { + throw new Error('internal error - CLEANSTACK without P2SH'); + } - if (this.stack.length != 1) { - this.errstr = 'SCRIPT_ERR_CLEANSTACK'; - return false; - } + if (this.stack.length != 1) { + this.errstr = 'SCRIPT_ERR_CLEANSTACK'; + return false; + } } if (flags & Interpreter.SCRIPT_VERIFY_INPUT_SIGCHECKS) { @@ -398,7 +397,7 @@ Interpreter.SCRIPT_ENABLE_P2SH_32 = (1 << 26); Interpreter.SCRIPT_ENABLE_TOKENS = (1 << 27); Interpreter.castToBool = function(buf) { - for (var i = 0; i < buf.length; i++) { + for (let i = 0; i < buf.length; i++) { if (buf[i] !== 0) { // can be negative zero if (i === buf.length - 1 && buf[i] === 0x80) { @@ -412,16 +411,16 @@ Interpreter.castToBool = function(buf) { Interpreter.isSchnorrSig = function(buf) { return (buf.length === 64 || buf.length === 65) && (buf[0] !== 0x30); -} +}; /** * Translated from bitcoind's CheckSignatureEncoding */ Interpreter.prototype.checkRawSignatureEncoding = function(buf) { - var sig; + let sig; - //TODO update interpreter.js and necessary functions to match bitcoin-abc interpreter.cpp - if(Interpreter.isSchnorrSig(buf)) { + // TODO update interpreter.js and necessary functions to match bitcoin-abc interpreter.cpp + if (Interpreter.isSchnorrSig(buf)) { return true; } @@ -443,20 +442,20 @@ Interpreter.prototype.checkRawSignatureEncoding = function(buf) { // Back compat Interpreter.prototype.checkSignatureEncoding = -Interpreter.prototype.checkTxSignatureEncoding = function(buf) { + Interpreter.prototype.checkTxSignatureEncoding = function(buf) { // Empty signature. Not strictly DER encoded, but allowed to provide a // compact way to provide an invalid signature for use with CHECK(MULTI)SIG if (buf.length == 0) { - return true; + return true; } - if (!this.checkRawSignatureEncoding(buf.slice(0,buf.length-1))) { + if (!this.checkRawSignatureEncoding(buf.slice(0, buf.length-1))) { return false; } if ((this.flags & Interpreter.SCRIPT_VERIFY_STRICTENC) !== 0) { - var sig = Signature.fromTxFormat(buf); + const sig = Signature.fromTxFormat(buf); if (!sig.hasDefinedHashtype()) { this.errstr = 'SCRIPT_ERR_SIG_HASHTYPE'; return false; @@ -475,16 +474,16 @@ Interpreter.prototype.checkTxSignatureEncoding = function(buf) { } return true; -}; + }; Interpreter.prototype.checkDataSignatureEncoding = function(buf) { - // Empty signature. Not strictly DER encoded, but allowed to provide a - // compact way to provide an invalid signature for use with CHECK(MULTI)SIG - if (buf.length == 0) { - return true; - } + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (buf.length == 0) { + return true; + } - return this.checkRawSignatureEncoding(buf); + return this.checkRawSignatureEncoding(buf); }; @@ -502,7 +501,7 @@ Interpreter.prototype.checkPubkeyEncoding = function(buf) { }; function IsCompressedOrUncompressedPubkey(bufPubkey) { - switch(bufPubkey.length) { + switch (bufPubkey.length) { case 33: return bufPubkey[0] === 0x02 || bufPubkey[0] === 0x03; case 64: @@ -523,27 +522,27 @@ function IsCompressedOrUncompressedPubkey(bufPubkey) { Interpreter._isMinimallyEncoded = function(buf, nMaxNumSize) { nMaxNumSize = nMaxNumSize || Interpreter.MAXIMUM_ELEMENT_SIZE; - if (buf.length > nMaxNumSize ) { - return false; + if (buf.length > nMaxNumSize ) { + return false; } if (buf.length > 0) { - // Check that the number is encoded with the minimum possible number - // of bytes. - // - // If the most-significant-byte - excluding the sign bit - is zero - // then we're not minimal. Note how this test also rejects the - // negative-zero encoding, 0x80. - if ((buf[buf.length-1] & 0x7f) == 0) { - // One exception: if there's more than one byte and the most - // significant bit of the second-most-significant-byte is set it - // would conflict with the sign bit. An example of this case is - // +-255, which encode to 0xff00 and 0xff80 respectively. - // (big-endian). - if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) == 0) { - return false; - } + // Check that the number is encoded with the minimum possible number + // of bytes. + // + // If the most-significant-byte - excluding the sign bit - is zero + // then we're not minimal. Note how this test also rejects the + // negative-zero encoding, 0x80. + if ((buf[buf.length-1] & 0x7f) == 0) { + // One exception: if there's more than one byte and the most + // significant bit of the second-most-significant-byte is set it + // would conflict with the sign bit. An example of this case is + // +-255, which encode to 0xff00 and 0xff80 respectively. + // (big-endian). + if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) == 0) { + return false; } + } } return true; }; @@ -555,47 +554,47 @@ Interpreter._isMinimallyEncoded = function(buf, nMaxNumSize) { * @param {number} nMaxNumSize (max allowed size) */ Interpreter._minimallyEncode = function(buf) { - if (buf.length == 0) { - return buf; - } + if (buf.length == 0) { + return buf; + } - // If the last byte is not 0x00 or 0x80, we are minimally encoded. - var last = buf[buf.length - 1]; - if (last & 0x7f) { - return buf; - } + // If the last byte is not 0x00 or 0x80, we are minimally encoded. + const last = buf[buf.length - 1]; + if (last & 0x7f) { + return buf; + } - // If the script is one byte long, then we have a zero, which encodes as an - // empty array. - if (buf.length == 1) { - return Buffer.from(''); - } + // If the script is one byte long, then we have a zero, which encodes as an + // empty array. + if (buf.length == 1) { + return Buffer.from(''); + } - // If the next byte has it sign bit set, then we are minimaly encoded. - if (buf[buf.length - 2] & 0x80) { - return buf; - } + // If the next byte has it sign bit set, then we are minimaly encoded. + if (buf[buf.length - 2] & 0x80) { + return buf; + } - // We are not minimally encoded, we need to figure out how much to trim. - for (var i = buf.length - 1; i > 0; i--) { - // We found a non zero byte, time to encode. - if (buf[i - 1] != 0) { - if (buf[i - 1] & 0x80) { - // We found a byte with it sign bit set so we need one more - // byte. - buf[i++] = last; - } else { - // the sign bit is clear, we can use it. - buf[i - 1] |= last; - } + // We are not minimally encoded, we need to figure out how much to trim. + for (let i = buf.length - 1; i > 0; i--) { + // We found a non zero byte, time to encode. + if (buf[i - 1] != 0) { + if (buf[i - 1] & 0x80) { + // We found a byte with it sign bit set so we need one more + // byte. + buf[i++] = last; + } else { + // the sign bit is clear, we can use it. + buf[i - 1] |= last; + } - return buf.slice(0,i); - } + return buf.slice(0, i); } + } - // If we the whole thing is zeros, then we have a zero. - return Buffer.from(''); -} + // If we the whole thing is zeros, then we have a zero. + return Buffer.from(''); +}; @@ -612,7 +611,7 @@ Interpreter.prototype.evaluate = function() { try { while (this.pc < this.script.chunks.length) { - var fSuccess = this.step(); + const fSuccess = this.step(); if (!fSuccess) { return false; } @@ -654,7 +653,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || + (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || (this.tx.nLockTime >= Interpreter.LOCKTIME_THRESHOLD && nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN)) )) { return false; @@ -681,7 +680,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { } return true; -} +}; /** @@ -692,54 +691,54 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { */ Interpreter.prototype.checkSequence = function(nSequence) { - // Relative lock times are supported by comparing the passed in operand to - // the sequence number of the input. - var txToSequence = this.tx.inputs[this.nin].sequenceNumber; + // Relative lock times are supported by comparing the passed in operand to + // the sequence number of the input. + const txToSequence = this.tx.inputs[this.nin].sequenceNumber; - // Fail if the transaction's version number is not set high enough to - // trigger BIP 68 rules. - if (this.tx.version < 2) { - return false; - } + // Fail if the transaction's version number is not set high enough to + // trigger BIP 68 rules. + if (this.tx.version < 2) { + return false; + } - // Sequence numbers with their most significant bit set are not consensus - // constrained. Testing that the transaction's sequence number do not have - // this bit set prevents using this property to get around a - // CHECKSEQUENCEVERIFY check. - if (txToSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG) { - return false; - } + // Sequence numbers with their most significant bit set are not consensus + // constrained. Testing that the transaction's sequence number do not have + // this bit set prevents using this property to get around a + // CHECKSEQUENCEVERIFY check. + if (txToSequence & Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) { + return false; + } - // Mask off any bits that do not have consensus-enforced meaning before - // doing the integer comparisons - var nLockTimeMask = - Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; - var txToSequenceMasked = new BN(txToSequence & nLockTimeMask); - var nSequenceMasked = nSequence.and(nLockTimeMask); + // Mask off any bits that do not have consensus-enforced meaning before + // doing the integer comparisons + const nLockTimeMask = + Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; + const txToSequenceMasked = new BN(txToSequence & nLockTimeMask); + const nSequenceMasked = nSequence.and(nLockTimeMask); - // There are two kinds of nSequence: lock-by-blockheight and - // lock-by-blocktime, distinguished by whether nSequenceMasked < - // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. - // - // We want to compare apples to apples, so fail the script unless the type - // of nSequenceMasked being tested is the same as the nSequenceMasked in the - // transaction. - var SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); + // There are two kinds of nSequence: lock-by-blockheight and + // lock-by-blocktime, distinguished by whether nSequenceMasked < + // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script unless the type + // of nSequenceMasked being tested is the same as the nSequenceMasked in the + // transaction. + const SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); - if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && + if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)) || (txToSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)))) { - return false; - } + return false; + } - // Now that we know we're comparing apples-to-apples, the comparison is a - // simple numeric one. - if (nSequenceMasked.gt(txToSequenceMasked)) { - return false; - } - return true; + // Now that we know we're comparing apples-to-apples, the comparison is a + // simple numeric one. + if (nSequenceMasked.gt(txToSequenceMasked)) { + return false; } + return true; +}; /** * Implemented from bitcoin-abc @@ -749,19 +748,19 @@ Interpreter.prototype.checkSequence = function(nSequence) { */ function DecodeBitfield(dummy, size) { if (size > 32) { - this.errstr = "INVALID_BITFIELD_SIZE"; - return {result: false}; + this.errstr = 'INVALID_BITFIELD_SIZE'; + return { result: false }; } - let bitfieldSize = Math.floor((size + 7) / 8); - let dummyBitlength = dummy.length; + const bitfieldSize = Math.floor((size + 7) / 8); + const dummyBitlength = dummy.length; if (dummyBitlength !== bitfieldSize) { - this.errstr = "INVALID_BITFIELD_SIZE"; - return {result: false}; + this.errstr = 'INVALID_BITFIELD_SIZE'; + return { result: false }; } let bitfield = 0; - let dummyAs32Bit = Uint32Array.from(dummy); + const dummyAs32Bit = Uint32Array.from(dummy); // let one = new Uint8Array([1]); // let oneAs64Bit = BigUint64Array.from(one); @@ -769,13 +768,13 @@ function DecodeBitfield(dummy, size) { bitfield = bitfield | (dummyAs32Bit[i] << (8*i)); } - let mask = (0x01 << size) - 1 - if((bitfield & mask) != bitfield) { - this.errstr = "INVALID_BIT_RANGE"; - return {result: false}; + const mask = (0x01 << size) - 1; + if ((bitfield & mask) != bitfield) { + this.errstr = 'INVALID_BIT_RANGE'; + return { result: false }; } - return {result: true, bitfield: bitfield}; + return { result: true, bitfield: bitfield }; } /** @@ -792,9 +791,9 @@ function countBits(v) { * More detailed explanation can be found at * https://www.playingwithpointers.com/blog/swar.html */ - v = v - (((v) >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; + v = v - (((v) >> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >> 2) & 0x33333333); + return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; } /** @@ -802,11 +801,9 @@ function countBits(v) { * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 */ Interpreter.prototype.step = function() { - var self = this; - - function stacktop(i) { - return self.stack[self.stack.length+i]; - } + const stacktop = (i) => { + return this.stack[this.stack.length+i]; + }; function isOpcodeDisabled(opcode, f64BitIntegers) { switch (opcode) { @@ -850,16 +847,16 @@ Interpreter.prototype.step = function() { const fNativeTokens = (this.flags & Interpreter.SCRIPT_ENABLE_TOKENS) !== 0; const maxScriptIntegerSize = f64BitIntegers ? 8 : 4; - //bool fExec = !count(vfExec.begin(), vfExec.end(), false); - var fExec = (this.vfExec.indexOf(false) === -1); - var buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, bufMessage, subscript; - var sig, pubkey; - var fValue, fSuccess; + // bool fExec = !count(vfExec.begin(), vfExec.end(), false); + const fExec = (this.vfExec.indexOf(false) === -1); + let buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, bufMessage, subscript; + let sig, pubkey; + let fValue, fSuccess; // Read instruction - var chunk = this.script.chunks[this.pc]; + const chunk = this.script.chunks[this.pc]; this.pc++; - var opcodenum = chunk.opcodenum; + const opcodenum = chunk.opcodenum; if (_.isUndefined(opcodenum)) { this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE'; return false; @@ -1117,16 +1114,15 @@ Interpreter.prototype.step = function() { break; case Opcode.OP_RETURN: - { - this.errstr = 'SCRIPT_ERR_OP_RETURN'; - return false; - } - break; + { + this.errstr = 'SCRIPT_ERR_OP_RETURN'; + return false; + } - // - // Stack ops - // + // + // Stack ops + // case Opcode.OP_TOALTSTACK: { if (this.stack.length < 1) { @@ -1182,7 +1178,7 @@ Interpreter.prototype.step = function() { } buf1 = stacktop(-3); buf2 = stacktop(-2); - var buf3 = stacktop(-1); + const buf3 = stacktop(-1); this.stack.push(buf1); this.stack.push(buf2); this.stack.push(buf3); @@ -1313,7 +1309,7 @@ Interpreter.prototype.step = function() { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - buf = stacktop(-n-1); + buf = stacktop(-n-1); if (opcodenum === Opcode.OP_ROLL) { this.stack.splice(this.stack.length - n - 1, 1); } @@ -1332,7 +1328,7 @@ Interpreter.prototype.step = function() { } x1 = stacktop(-3); x2 = stacktop(-2); - var x3 = stacktop(-1); + const x3 = stacktop(-1); this.stack[this.stack.length - 3] = x2; this.stack[this.stack.length - 2] = x3; this.stack[this.stack.length - 1] = x1; @@ -1401,17 +1397,17 @@ Interpreter.prototype.step = function() { // To avoid allocating, we modify vch1 in place. switch (opcodenum) { case Opcode.OP_AND: - for (var i = 0; i < buf1.length; i++) { + for (let i = 0; i < buf1.length; i++) { buf1[i] &= buf2[i]; } break; case Opcode.OP_OR: - for (var i = 0; i < buf1.length; i++) { + for (let i = 0; i < buf1.length; i++) { buf1[i] |= buf2[i]; } break; case Opcode.OP_XOR: - for (var i = 0; i < buf1.length; i++) { + for (let i = 0; i < buf1.length; i++) { buf1[i] ^= buf2[i]; } break; @@ -1420,13 +1416,13 @@ Interpreter.prototype.step = function() { } // And pop vch2. - this.stack.pop() + this.stack.pop(); } break; case Opcode.OP_EQUAL: case Opcode.OP_EQUALVERIFY: - //case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL + // case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL { // (x1 x2 - bool) if (this.stack.length < 2) { @@ -1435,7 +1431,7 @@ Interpreter.prototype.step = function() { } buf1 = stacktop(-2); buf2 = stacktop(-1); - var fEqual = buf1.toString('hex') === buf2.toString('hex'); + const fEqual = buf1.toString('hex') === buf2.toString('hex'); this.stack.pop(); this.stack.pop(); this.stack.push(fEqual ? Interpreter.true : Interpreter.false); @@ -1489,7 +1485,7 @@ Interpreter.prototype.step = function() { case Opcode.OP_0NOTEQUAL: bn = new BN((bn.cmp(BN.Zero) !== 0) + 0); break; - //default: assert(!'invalid opcode'); break; // TODO: does this ever occur? + // default: assert(!'invalid opcode'); break; // TODO: does this ever occur? } this.stack.pop(); this.stack.push(bn.toScriptNumBuffer()); @@ -1621,8 +1617,8 @@ Interpreter.prototype.step = function() { } bn1 = BN.fromScriptNumBuffer(stacktop(-3), fRequireMinimal, maxScriptIntegerSize); bn2 = BN.fromScriptNumBuffer(stacktop(-2), fRequireMinimal, maxScriptIntegerSize); - var bn3 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, maxScriptIntegerSize); - //bool fValue = (bn2 <= bn1 && bn1 < bn3); + const bn3 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, maxScriptIntegerSize); + // bool fValue = (bn2 <= bn1 && bn1 < bn3); fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0); this.stack.pop(); this.stack.pop(); @@ -1647,7 +1643,7 @@ Interpreter.prototype.step = function() { return false; } buf = stacktop(-1); - //valtype vchHash((opcode == Opcode.OP_RIPEMD160 || + // valtype vchHash((opcode == Opcode.OP_RIPEMD160 || // opcode == Opcode.OP_SHA1 || opcode == Opcode.OP_HASH160) ? 20 : 32); var bufHash; if (opcodenum === Opcode.OP_RIPEMD160) { @@ -1696,20 +1692,20 @@ Interpreter.prototype.step = function() { }); // Drop the signature, since there's no way for a signature to sign itself - var tmpScript = new Script().add(bufSig); + const tmpScript = new Script().add(bufSig); subscript.findAndDelete(tmpScript); try { sig = Signature.fromTxFormat(bufSig); pubkey = PublicKey.fromBuffer(bufPubkey, false); - if(!sig.isSchnorr) { + if (!sig.isSchnorr) { fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags); } else { fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags, 'schnorr'); } } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fSuccess = false; } @@ -1771,7 +1767,7 @@ Interpreter.prototype.step = function() { fSuccess = Schnorr.verify(bufHash, sig, pubkey, 'big'); } } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fSuccess = false; } @@ -1810,7 +1806,7 @@ Interpreter.prototype.step = function() { } buf1 = stacktop(-1); - var reversedBuf = Buffer.from(buf1).reverse(); + const reversedBuf = Buffer.from(buf1).reverse(); this.stack.pop(); this.stack.push(reversedBuf); } @@ -1821,15 +1817,15 @@ Interpreter.prototype.step = function() { { // ([dummy] [sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) - var i = 1; - let idxTopKey = i + 1; + let i = 1; + const idxTopKey = i + 1; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nKeysCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal).toNumber(); - var idxSigCount = idxTopKey + nKeysCount; + const nKeysCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal).toNumber(); + const idxSigCount = idxTopKey + nKeysCount; if (nKeysCount < 0 || nKeysCount > 20) { this.errstr = 'SCRIPT_ERR_PUBKEY_COUNT'; return false; @@ -1842,8 +1838,8 @@ Interpreter.prototype.step = function() { // todo map interpreter.cpp variables with interpreter.js variables for future readability, maintainability // ikey maps to idxTopKey in interpreter.cpp (MULTISIG case) - var ikey = ++i; // top pubkey - var idxTopSig = idxSigCount + 1; + const ikey = ++i; // top pubkey + const idxTopSig = idxSigCount + 1; // i maps to idxSigCount in interpreter.cpp (MULTISIG case) (stack depth of nSigsCount) i += nKeysCount; @@ -1852,22 +1848,22 @@ Interpreter.prototype.step = function() { // the stack. Top stack item = 1. With // SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if // operation fails. - var ikey2 = nKeysCount + 2; // ?dummy variable + let ikey2 = nKeysCount + 2; // ?dummy variable if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nSigsCount = BN.fromScriptNumBuffer(stacktop(-idxSigCount), fRequireMinimal).toNumber(); - var idxDummy = idxTopSig + nSigsCount; + const nSigsCount = BN.fromScriptNumBuffer(stacktop(-idxSigCount), fRequireMinimal).toNumber(); + const idxDummy = idxTopSig + nSigsCount; if (nSigsCount < 0 || nSigsCount > nKeysCount) { this.errstr = 'SCRIPT_ERR_SIG_COUNT'; return false; } // int isig = ++i; - var isig = ++i; + const isig = ++i; i += nSigsCount; if (this.stack.length < idxDummy) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; @@ -1882,87 +1878,87 @@ Interpreter.prototype.step = function() { fSuccess = true; - if((this.flags & Interpreter.SCRIPT_ENABLE_SCHNORR_MULTISIG) && stacktop(-idxDummy).length !== 0) { + if ((this.flags & Interpreter.SCRIPT_ENABLE_SCHNORR_MULTISIG) && stacktop(-idxDummy).length !== 0) { // SCHNORR MULTISIG - let dummy = stacktop(-idxDummy); + const dummy = stacktop(-idxDummy); - let bitfieldObj = DecodeBitfield(dummy, nKeysCount); + const bitfieldObj = DecodeBitfield(dummy, nKeysCount); - if(!bitfieldObj["result"]) { + if (!bitfieldObj['result']) { fSuccess = false; } - let nSigs8bit = new Uint8Array([nSigsCount]); - let nSigs32 = Uint32Array.from(nSigs8bit); + const nSigs8bit = new Uint8Array([nSigsCount]); + const nSigs32 = Uint32Array.from(nSigs8bit); - if (countBits(bitfieldObj["bitfield"]) !== nSigs32[0]) { - this.errstr = "INVALID_BIT_COUNT"; + if (countBits(bitfieldObj['bitfield']) !== nSigs32[0]) { + this.errstr = 'INVALID_BIT_COUNT'; fSuccess = false; } - var bottomKey = idxTopKey + nKeysCount - 1; - var bottomSig = idxTopSig + nSigsCount - 1; + const bottomKey = idxTopKey + nKeysCount - 1; + const bottomSig = idxTopSig + nSigsCount - 1; let iKey = 0; - for(let iSig = 0; iSig < nSigsCount; + for (let iSig = 0; iSig < nSigsCount; iSig++, iKey++) { - if((bitfieldObj["bitfield"] >> iKey) === 0) { - this.errstr = "INVALID_BIT_RANGE"; - fSuccess = false; - } - - while(((bitfieldObj["bitfield"] >> iKey) & 0x01) == 0) { - if(iKey >= nKeysCount) { - this.errstr = "wrong"; - fSuccess = false; - break; - } - iKey++; - } + if ((bitfieldObj['bitfield'] >> iKey) === 0) { + this.errstr = 'INVALID_BIT_RANGE'; + fSuccess = false; + } - // this is a sanity check and should be - // unreachable - if(iKey >= nKeysCount) { - this.errstr = "PUBKEY_COUNT"; + while (((bitfieldObj['bitfield'] >> iKey) & 0x01) == 0) { + if (iKey >= nKeysCount) { + this.errstr = 'wrong'; fSuccess = false; + break; } + iKey++; + } - // Check the signature - let bufsig = stacktop(-bottomSig + iSig) - let bufPubkey = stacktop(-bottomKey + iKey) + // this is a sanity check and should be + // unreachable + if (iKey >= nKeysCount) { + this.errstr = 'PUBKEY_COUNT'; + fSuccess = false; + } - // Note that only pubkeys associated with a - // signature are check for validity + // Check the signature + const bufsig = stacktop(-bottomSig + iSig); + const bufPubkey = stacktop(-bottomKey + iKey); - if(!this.checkRawSignatureEncoding(bufsig) || !this.checkPubkeyEncoding(bufPubkey)) { - fSuccess = false; - } + // Note that only pubkeys associated with a + // signature are check for validity - let sig = Signature.fromTxFormat(bufsig); - let pubkey = PublicKey.fromBuffer(bufPubkey, false); - let fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags, "schnorr"); + if (!this.checkRawSignatureEncoding(bufsig) || !this.checkPubkeyEncoding(bufPubkey)) { + fSuccess = false; + } - if(!fOk) { - this.errstr = "SIG_NULLFAIL" - fSuccess = false; - } + const sig = Signature.fromTxFormat(bufsig); + const pubkey = PublicKey.fromBuffer(bufPubkey, false); + const fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags, 'schnorr'); - if (bufsig.length) { - this.nSigChecks += 1; - } + if (!fOk) { + this.errstr = 'SIG_NULLFAIL'; + fSuccess = false; } - if ((bitfieldObj["bitfield"] >> iKey) != 0) { - // This is a sanity check and should be - // unreachable. - this.errstr = "INVALID_BIT_COUNT" - fSuccess = false; + if (bufsig.length) { + this.nSigChecks += 1; } + } + + if ((bitfieldObj['bitfield'] >> iKey) != 0) { + // This is a sanity check and should be + // unreachable. + this.errstr = 'INVALID_BIT_COUNT'; + fSuccess = false; + } } else { // Drop the signatures, since there's no way for a signature to sign itself - for (var k = 0; k < nSigsCount; k++) { + for (let k = 0; k < nSigsCount; k++) { bufSig = stacktop(-isig-k); subscript.findAndDelete(new Script().add(bufSig)); } @@ -1970,49 +1966,49 @@ Interpreter.prototype.step = function() { let nSigsRemaining = nSigsCount; let nKeysRemaining = nKeysCount; while (fSuccess && nSigsRemaining > 0) { - bufSig = stacktop(-isig - (nSigsCount - nSigsRemaining)); - if (bufSig.length === 65) { - return false; - } - bufPubkey = stacktop(-ikey - (nKeysCount - nKeysRemaining)); - - if (!this.checkTxSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) { - return false; - } + bufSig = stacktop(-isig - (nSigsCount - nSigsRemaining)); + if (bufSig.length === 65) { + return false; + } + bufPubkey = stacktop(-ikey - (nKeysCount - nKeysRemaining)); - var fOk; - try { - sig = Signature.fromTxFormat(bufSig); - pubkey = PublicKey.fromBuffer(bufPubkey, false); - fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags); - } catch (e) { - //invalid sig or pubkey - fOk = false; - } + if (!this.checkTxSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) { + return false; + } - if (fOk) { - nSigsRemaining--; - } - nKeysRemaining--; + var fOk; + try { + sig = Signature.fromTxFormat(bufSig); + pubkey = PublicKey.fromBuffer(bufPubkey, false); + fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.satoshisBN, this.flags); + } catch (e) { + // invalid sig or pubkey + fOk = false; + } - // If there are more signatures left than keys left, - // then too many signatures have failed - if (nSigsRemaining > nKeysRemaining) { - fSuccess = false; - } + if (fOk) { + nSigsRemaining--; } + nKeysRemaining--; - let areAllSignaturesNull = true; - for (let l = 0; l < nSigsCount; l++) { - if (stacktop(-isig-l) && stacktop(-isig-l).length) { - areAllSignaturesNull = false; - break; - } + // If there are more signatures left than keys left, + // then too many signatures have failed + if (nSigsRemaining > nKeysRemaining) { + fSuccess = false; } + } - if (!areAllSignaturesNull) { - this.nSigChecks += nKeysCount; + let areAllSignaturesNull = true; + for (let l = 0; l < nSigsCount; l++) { + if (stacktop(-isig-l) && stacktop(-isig-l).length) { + areAllSignaturesNull = false; + break; } + } + + if (!areAllSignaturesNull) { + this.nSigChecks += nKeysCount; + } } // Clean up stack of actual arguments @@ -2063,360 +2059,361 @@ Interpreter.prototype.step = function() { // // Byte string operations // - case Opcode.OP_CAT: { + case Opcode.OP_CAT: { - if (this.stack.length < 2) { - this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; - return false; - } + if (this.stack.length < 2) { + this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; + return false; + } - buf1 = stacktop(-2); - buf2 = stacktop(-1); - if (buf1.length + buf2.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { - this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; - return false; - } - this.stack[this.stack.length - 2] = Buffer.concat([buf1,buf2]); - this.stack.pop(); + buf1 = stacktop(-2); + buf2 = stacktop(-1); + if (buf1.length + buf2.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { + this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; + return false; } + this.stack[this.stack.length - 2] = Buffer.concat([buf1, buf2]); + this.stack.pop(); + } break; - case Opcode.OP_SPLIT: { - if (this.stack.length < 2) { - this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; - return false; - } - buf1 = stacktop(-2); + case Opcode.OP_SPLIT: { + if (this.stack.length < 2) { + this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; + return false; + } + buf1 = stacktop(-2); - // Make sure the split point is apropriate. - var position = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber(); - if (position < 0 || position > buf1.length) { - this.errstr = 'SCRIPT_ERR_INVALID_SPLIT_RANGE'; - return false; - } + // Make sure the split point is apropriate. + const position = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber(); + if (position < 0 || position > buf1.length) { + this.errstr = 'SCRIPT_ERR_INVALID_SPLIT_RANGE'; + return false; + } - // Prepare the results in their own buffer as `data` - // will be invalidated. - // Copy buffer data, to slice it before - var n1 = Buffer.from(buf1); + // Prepare the results in their own buffer as `data` + // will be invalidated. + // Copy buffer data, to slice it before + const n1 = Buffer.from(buf1); - // Replace existing stack values by the new values. - this.stack[this.stack.length - 2] = n1.slice(0, position); - this.stack[this.stack.length - 1] = n1.slice(position); - } + // Replace existing stack values by the new values. + this.stack[this.stack.length - 2] = n1.slice(0, position); + this.stack[this.stack.length - 1] = n1.slice(position); + } break; // // Conversion operations // - case Opcode.OP_NUM2BIN: { + case Opcode.OP_NUM2BIN: { - // (in -- out) - if (this.stack.length < 2) { - this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; - return false; - } + // (in -- out) + if (this.stack.length < 2) { + this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; + return false; + } - var size = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber(); - if (size > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { - this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; - return false; - } + const size = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal).toNumber(); + if (size > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { + this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; + return false; + } - this.stack.pop(); - var rawnum = stacktop(-1); + this.stack.pop(); + let rawnum = stacktop(-1); - // Try to see if we can fit that number in the number of - // byte requested. - rawnum=Interpreter._minimallyEncode(rawnum); + // Try to see if we can fit that number in the number of + // byte requested. + rawnum=Interpreter._minimallyEncode(rawnum); - if (rawnum.length > size) { - // We definitively cannot. - this.errstr = 'SCRIPT_ERR_IMPOSSIBLE_ENCODING'; - return false; - } + if (rawnum.length > size) { + // We definitively cannot. + this.errstr = 'SCRIPT_ERR_IMPOSSIBLE_ENCODING'; + return false; + } - // We already have an element of the right size, we - // don't need to do anything. - if (rawnum.length == size) { - this.stack[this.stack.length-1] = rawnum; - break; - } + // We already have an element of the right size, we + // don't need to do anything. + if (rawnum.length == size) { + this.stack[this.stack.length-1] = rawnum; + break; + } - var signbit = 0x00; - if (rawnum.length > 0) { - signbit = rawnum[rawnum.length - 1] & 0x80; - rawnum[rawnum.length - 1] &= 0x7f; - } + let signbit = 0x00; + if (rawnum.length > 0) { + signbit = rawnum[rawnum.length - 1] & 0x80; + rawnum[rawnum.length - 1] &= 0x7f; + } - var num = Buffer.alloc(size); - rawnum.copy(num,0); + const num = Buffer.alloc(size); + rawnum.copy(num, 0); - var l = rawnum.length - 1; - while (l++ < size - 2) { - num[l]=0x00; - } + let l = rawnum.length - 1; + while (l++ < size - 2) { + num[l]=0x00; + } - num[l]=signbit; + num[l]=signbit; - this.stack[this.stack.length-1] = num; - } + this.stack[this.stack.length-1] = num; + } break; - case Opcode.OP_BIN2NUM: { - // (in -- out) - if (this.stack.length < 1) { - this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; - return false; - } + case Opcode.OP_BIN2NUM: { + // (in -- out) + if (this.stack.length < 1) { + this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; + return false; + } - buf1 = stacktop(-1); - buf2 = Interpreter._minimallyEncode(buf1); + buf1 = stacktop(-1); + buf2 = Interpreter._minimallyEncode(buf1); - this.stack[this.stack.length - 1] = buf2; + this.stack[this.stack.length - 1] = buf2; - // The resulting number must be a valid number. - if (!Interpreter._isMinimallyEncoded(buf2, maxScriptIntegerSize)) { - this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'; - return false; - } + // The resulting number must be a valid number. + if (!Interpreter._isMinimallyEncoded(buf2, maxScriptIntegerSize)) { + this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'; + return false; } + } break; // Native Introspection opcodes (Nullary) - case Opcode.OP_INPUTINDEX: - case Opcode.OP_ACTIVEBYTECODE: - case Opcode.OP_TXVERSION: - case Opcode.OP_TXINPUTCOUNT: - case Opcode.OP_TXOUTPUTCOUNT: - case Opcode.OP_TXLOCKTIME: { - if (!fNativeIntrospection) { - this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; - return false; - } - if (!this.tx || !this.tx.inputs.every(input => input.output)) { - this.errstr = 'SCRIPT_ERR_CONTEXT_NOT_PRESENT'; - return false; - } - - switch (opcodenum) { - case Opcode.OP_INPUTINDEX: { - const bn = BN.fromNumber(this.nin); - this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_ACTIVEBYTECODE: { - // Subset of script starting at the most recent code separator (if any) - // or the entire script if no code separators are present. - subscript = new Script().set({ - chunks: this.script.chunks.slice(this.pbegincodehash) - }); - this.stack.push(subscript.toBuffer()); - } break; - case Opcode.OP_TXVERSION: { - const bn = BN.fromNumber(this.tx.version); - this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_TXINPUTCOUNT: { - const bn = BN.fromNumber(this.tx.inputs.length); - this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_TXOUTPUTCOUNT: { - const bn = BN.fromNumber(this.tx.outputs.length); - this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_TXLOCKTIME: { - const bn = BN.fromNumber(this.tx.nLockTime); - this.stack.push(bn.toScriptNumBuffer()); - } break; - default: { - this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; - return false; - } - } - } break; // end of Native Introspection opcodes (Nullary) + case Opcode.OP_INPUTINDEX: + case Opcode.OP_ACTIVEBYTECODE: + case Opcode.OP_TXVERSION: + case Opcode.OP_TXINPUTCOUNT: + case Opcode.OP_TXOUTPUTCOUNT: + case Opcode.OP_TXLOCKTIME: { + if (!fNativeIntrospection) { + this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; + return false; + } + if (!this.tx || !this.tx.inputs.every(input => input.output)) { + this.errstr = 'SCRIPT_ERR_CONTEXT_NOT_PRESENT'; + return false; + } - // Native Introspection opcodes (Unary) - case Opcode.OP_UTXOTOKENCATEGORY: - case Opcode.OP_UTXOTOKENCOMMITMENT: - case Opcode.OP_UTXOTOKENAMOUNT: - case Opcode.OP_OUTPUTTOKENCATEGORY: - case Opcode.OP_OUTPUTTOKENCOMMITMENT: - case Opcode.OP_OUTPUTTOKENAMOUNT: - if (!fNativeTokens) { + switch (opcodenum) { + case Opcode.OP_INPUTINDEX: { + const bn = BN.fromNumber(this.nin); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_ACTIVEBYTECODE: { + // Subset of script starting at the most recent code separator (if any) + // or the entire script if no code separators are present. + subscript = new Script().set({ + chunks: this.script.chunks.slice(this.pbegincodehash) + }); + this.stack.push(subscript.toBuffer()); + } break; + case Opcode.OP_TXVERSION: { + const bn = BN.fromNumber(this.tx.version); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_TXINPUTCOUNT: { + const bn = BN.fromNumber(this.tx.inputs.length); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_TXOUTPUTCOUNT: { + const bn = BN.fromNumber(this.tx.outputs.length); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_TXLOCKTIME: { + const bn = BN.fromNumber(this.tx.nLockTime); + this.stack.push(bn.toScriptNumBuffer()); + } break; + default: { this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; return false; } - case Opcode.OP_UTXOVALUE: - case Opcode.OP_UTXOBYTECODE: - case Opcode.OP_OUTPOINTTXHASH: - case Opcode.OP_OUTPOINTINDEX: - case Opcode.OP_INPUTBYTECODE: - case Opcode.OP_INPUTSEQUENCENUMBER: - case Opcode.OP_OUTPUTVALUE: - case Opcode.OP_OUTPUTBYTECODE: { - if (!fNativeIntrospection) { - this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; - return false; - } - if (!this.tx || !this.tx.inputs.every(input => input.output)) { - this.errstr = 'SCRIPT_ERR_CONTEXT_NOT_PRESENT'; - return false; - } - const bn = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, maxScriptIntegerSize); - const index = bn.toNumber(); - this.stack.pop(); - - const indexType = [ - Opcode.OP_OUTPUTVALUE, - Opcode.OP_OUTPUTBYTECODE, - Opcode.OP_OUTPUTTOKENCATEGORY, - Opcode.OP_OUTPUTTOKENCOMMITMENT, - Opcode.OP_OUTPUTTOKENAMOUNT - ].includes(opcodenum) ? 'OUTPUT' : 'INPUT'; - - const maxIndex = indexType === 'OUTPUT' - ? this.tx.outputs.length - : this.tx.inputs.length; + } + } break; // end of Native Introspection opcodes (Nullary) - if (index < 0 || index >= maxIndex) { - this.errstr = `SCRIPT_ERR_INVALID_TX_${indexType}_INDEX`; - return false; - } + // Native Introspection opcodes (Unary) + case Opcode.OP_UTXOTOKENCATEGORY: + case Opcode.OP_UTXOTOKENCOMMITMENT: + case Opcode.OP_UTXOTOKENAMOUNT: + case Opcode.OP_OUTPUTTOKENCATEGORY: + case Opcode.OP_OUTPUTTOKENCOMMITMENT: + case Opcode.OP_OUTPUTTOKENAMOUNT: + if (!fNativeTokens) { + this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; + return false; + } + // falls through + case Opcode.OP_UTXOVALUE: + case Opcode.OP_UTXOBYTECODE: + case Opcode.OP_OUTPOINTTXHASH: + case Opcode.OP_OUTPOINTINDEX: + case Opcode.OP_INPUTBYTECODE: + case Opcode.OP_INPUTSEQUENCENUMBER: + case Opcode.OP_OUTPUTVALUE: + case Opcode.OP_OUTPUTBYTECODE: { + if (!fNativeIntrospection) { + this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; + return false; + } + if (!this.tx || !this.tx.inputs.every(input => input.output)) { + this.errstr = 'SCRIPT_ERR_CONTEXT_NOT_PRESENT'; + return false; + } + const bn = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, maxScriptIntegerSize); + const index = bn.toNumber(); + this.stack.pop(); + + const indexType = [ + Opcode.OP_OUTPUTVALUE, + Opcode.OP_OUTPUTBYTECODE, + Opcode.OP_OUTPUTTOKENCATEGORY, + Opcode.OP_OUTPUTTOKENCOMMITMENT, + Opcode.OP_OUTPUTTOKENAMOUNT + ].includes(opcodenum) ? 'OUTPUT' : 'INPUT'; + + const maxIndex = indexType === 'OUTPUT' + ? this.tx.outputs.length + : this.tx.inputs.length; + + if (index < 0 || index >= maxIndex) { + this.errstr = `SCRIPT_ERR_INVALID_TX_${indexType}_INDEX`; + return false; + } - const tokenCapabilities = { - mutable: 1, - minting: 2, - }; + const tokenCapabilities = { + mutable: 1, + minting: 2, + }; - switch (opcodenum) { - case Opcode.OP_UTXOVALUE: { - const bn = this.tx.inputs[index].output.satoshisBN; - if (bn.getSize() > maxScriptIntegerSize) { - this.errstr = 'SCRIPT_ERR_INTEGER_SIZE'; - return false; - } + switch (opcodenum) { + case Opcode.OP_UTXOVALUE: { + const bn = this.tx.inputs[index].output.satoshisBN; + if (bn.getSize() > maxScriptIntegerSize) { + this.errstr = 'SCRIPT_ERR_INTEGER_SIZE'; + return false; + } + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_UTXOBYTECODE: { + const bytecode = this.tx.inputs[index].output.script.toBuffer(); + if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { + this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; + return false; + } + this.stack.push(bytecode); + } break; + case Opcode.OP_OUTPOINTTXHASH: { + const writer = new BufferWriter(); + writer.writeReverse(this.tx.inputs[index].prevTxId); + this.stack.push(writer.toBuffer()); + } break; + case Opcode.OP_OUTPOINTINDEX: { + const bn = BN.fromNumber(this.tx.inputs[index].outputIndex); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_INPUTBYTECODE: { + const bytecode = this.tx.inputs[index].script.toBuffer(); + if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { + this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; + return false; + } + this.stack.push(bytecode); + } break; + case Opcode.OP_INPUTSEQUENCENUMBER: { + const bn = BN.fromNumber(this.tx.inputs[index].sequenceNumber); + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_OUTPUTVALUE: { + const bn = this.tx.outputs[index].satoshisBN; + if (bn.getSize() > maxScriptIntegerSize) { + this.errstr = 'SCRIPT_ERR_INTEGER_SIZE'; + return false; + } + this.stack.push(bn.toScriptNumBuffer()); + } break; + case Opcode.OP_OUTPUTBYTECODE: { + const bytecode = this.tx.outputs[index].script.toBuffer(); + if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { + this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; + return false; + } + this.stack.push(bytecode); + } break; + // Token introspection + case Opcode.OP_UTXOTOKENCATEGORY: { + const tokenData = this.tx.inputs[index].output.tokenData; + if (!tokenData) { + const bn = BN.fromNumber(0); this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_UTXOBYTECODE: { - const bytecode = this.tx.inputs[index].output.script.toBuffer(); - if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { - this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; - return false; - } - this.stack.push(bytecode); - } break; - case Opcode.OP_OUTPOINTTXHASH: { - const writer = new BufferWriter(); - writer.writeReverse(this.tx.inputs[index].prevTxId); - this.stack.push(writer.toBuffer()); - } break; - case Opcode.OP_OUTPOINTINDEX: { - const bn = BN.fromNumber(this.tx.inputs[index].outputIndex); + break; + } + const category = tokenData.category; + const capability = tokenData.nft && tokenData.nft.capability && tokenCapabilities[tokenData.nft.capability] || 0; + const capabilityBuf = BN.fromNumber(capability).toScriptNumBuffer(); + const categoryBuf = Buffer.from(category, 'hex').reverse(); + const fullBuffer = Buffer.concat([categoryBuf, capabilityBuf]); + this.stack.push(fullBuffer); + } break; + case Opcode.OP_UTXOTOKENCOMMITMENT: { + const tokenData = this.tx.inputs[index].output.tokenData; + if (!tokenData || !tokenData.nft) { + const bn = BN.fromNumber(0); this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_INPUTBYTECODE: { - const bytecode = this.tx.inputs[index].script.toBuffer(); - if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { - this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; - return false; - } - this.stack.push(bytecode); - } break; - case Opcode.OP_INPUTSEQUENCENUMBER: { - const bn = BN.fromNumber(this.tx.inputs[index].sequenceNumber); + break; + } + const commitment = tokenData.nft.commitment; + this.stack.push(Buffer.from(commitment, 'hex')); + } break; + case Opcode.OP_UTXOTOKENAMOUNT: { + const tokenData = this.tx.inputs[index].output.tokenData; + if (!tokenData || !tokenData.amount) { + const bn = BN.fromNumber(0); this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_OUTPUTVALUE: { - const bn = this.tx.outputs[index].satoshisBN; - if (bn.getSize() > maxScriptIntegerSize) { - this.errstr = 'SCRIPT_ERR_INTEGER_SIZE'; - return false; - } + break; + } + this.stack.push(tokenData.amount.toScriptNumBuffer()); + } break; + case Opcode.OP_OUTPUTTOKENCATEGORY: { + const tokenData = this.tx.outputs[index].tokenData; + if (!tokenData) { + const bn = BN.fromNumber(0); this.stack.push(bn.toScriptNumBuffer()); - } break; - case Opcode.OP_OUTPUTBYTECODE: { - const bytecode = this.tx.outputs[index].script.toBuffer(); - if (bytecode.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { - this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; - return false; - } - this.stack.push(bytecode); - } break; - // Token introspection - case Opcode.OP_UTXOTOKENCATEGORY: { - const tokenData = this.tx.inputs[index].output.tokenData; - if (!tokenData) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - const category = tokenData.category; - const capability = tokenData.nft && tokenData.nft.capability && tokenCapabilities[tokenData.nft.capability] || 0; - const capabilityBuf = BN.fromNumber(capability).toScriptNumBuffer(); - const categoryBuf = Buffer.from(category, 'hex').reverse(); - const fullBuffer = Buffer.concat([categoryBuf, capabilityBuf]); - this.stack.push(fullBuffer); - } break; - case Opcode.OP_UTXOTOKENCOMMITMENT: { - const tokenData = this.tx.inputs[index].output.tokenData; - if (!tokenData || !tokenData.nft) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - const commitment = tokenData.nft.commitment; - this.stack.push(Buffer.from(commitment, 'hex')); - } break; - case Opcode.OP_UTXOTOKENAMOUNT: { - const tokenData = this.tx.inputs[index].output.tokenData; - if (!tokenData || !tokenData.amount) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - this.stack.push(tokenData.amount.toScriptNumBuffer()); - } break; - case Opcode.OP_OUTPUTTOKENCATEGORY: { - const tokenData = this.tx.outputs[index].tokenData; - if (!tokenData) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - const category = tokenData.category; - const capability = tokenData.nft && tokenData.nft.capability && tokenCapabilities[tokenData.nft.capability] || 0; - const capabilityBuf = BN.fromNumber(capability).toScriptNumBuffer(); - const categoryBuf = Buffer.from(category, 'hex').reverse(); - const fullBuffer = Buffer.concat([categoryBuf, capabilityBuf]); - this.stack.push(fullBuffer); - } break; - case Opcode.OP_OUTPUTTOKENCOMMITMENT: { - const tokenData = this.tx.outputs[index].tokenData; - if (!tokenData || !tokenData.nft) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - const commitment = tokenData.nft.commitment; - this.stack.push(Buffer.from(commitment, 'hex')); - } break; - case Opcode.OP_OUTPUTTOKENAMOUNT: { - const tokenData = this.tx.outputs[index].tokenData; - if (!tokenData || !tokenData.amount) { - const bn = BN.fromNumber(0); - this.stack.push(bn.toScriptNumBuffer()); - break; - } - this.stack.push(tokenData.amount.toScriptNumBuffer()); - } break; - default: { - this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; - return false; + break; } + const category = tokenData.category; + const capability = tokenData.nft && tokenData.nft.capability && tokenCapabilities[tokenData.nft.capability] || 0; + const capabilityBuf = BN.fromNumber(capability).toScriptNumBuffer(); + const categoryBuf = Buffer.from(category, 'hex').reverse(); + const fullBuffer = Buffer.concat([categoryBuf, capabilityBuf]); + this.stack.push(fullBuffer); + } break; + case Opcode.OP_OUTPUTTOKENCOMMITMENT: { + const tokenData = this.tx.outputs[index].tokenData; + if (!tokenData || !tokenData.nft) { + const bn = BN.fromNumber(0); + this.stack.push(bn.toScriptNumBuffer()); + break; + } + const commitment = tokenData.nft.commitment; + this.stack.push(Buffer.from(commitment, 'hex')); + } break; + case Opcode.OP_OUTPUTTOKENAMOUNT: { + const tokenData = this.tx.outputs[index].tokenData; + if (!tokenData || !tokenData.amount) { + const bn = BN.fromNumber(0); + this.stack.push(bn.toScriptNumBuffer()); + break; + } + this.stack.push(tokenData.amount.toScriptNumBuffer()); + } break; + default: { + this.errstr = 'SCRIPT_ERR_BAD_OPCODE'; + return false; } - } break; // end of Native Introspection opcodes (Unary) + } + } break; // end of Native Introspection opcodes (Unary) default: diff --git a/packages/bitcore-lib-cash/lib/transaction/transaction.js b/packages/bitcore-lib-cash/lib/transaction/transaction.js index b62188f2cb7..cd82c598faf 100644 --- a/packages/bitcore-lib-cash/lib/transaction/transaction.js +++ b/packages/bitcore-lib-cash/lib/transaction/transaction.js @@ -599,10 +599,10 @@ Transaction.prototype._selectInputType = function(utxo, pubkeys, threshold) { if (pubkeys && threshold) { if (utxo.script.isMultisigOut()) { clazz = MultiSigInput; - } else if (utxo.script.isScriptHashOut() || utxo.script.isWitnessScriptHashOut()) { + } else if (utxo.script.isScriptHashOut()) { clazz = MultiSigScriptHashInput; } - } else if (utxo.script.isPublicKeyHashOut() || utxo.script.isWitnessPublicKeyHashOut() || utxo.script.isScriptHashOut()) { + } else if (utxo.script.isPublicKeyHashOut() || utxo.script.isScriptHashOut()) { clazz = PublicKeyHashInput; } else if (utxo.script.isPublicKeyOut()) { clazz = PublicKeyInput; diff --git a/packages/bitcore-lib-doge/lib/block/blockheader.js b/packages/bitcore-lib-doge/lib/block/blockheader.js index 39740682cdf..02c905f45ab 100644 --- a/packages/bitcore-lib-doge/lib/block/blockheader.js +++ b/packages/bitcore-lib-doge/lib/block/blockheader.js @@ -2,12 +2,12 @@ var _ = require('lodash'); var BN = require('../crypto/bn'); -var BufferUtil = require('../util/buffer'); +var Hash = require('../crypto/hash'); var BufferReader = require('../encoding/bufferreader'); var BufferWriter = require('../encoding/bufferwriter'); -var Hash = require('../crypto/hash'); -var $ = require('../util/preconditions'); var Script = require('../script'); +var BufferUtil = require('../util/buffer'); +var $ = require('../util/preconditions'); var GENESIS_BITS = 0x1e0ffff0; // Regtest: 0x207fffff @@ -23,7 +23,7 @@ var BlockHeader = function BlockHeader(arg) { if (!(this instanceof BlockHeader)) { return new BlockHeader(arg); } - var info = BlockHeader._from(arg); + const info = BlockHeader._from(arg); this.version = info.version; this.prevHash = info.prevHash; this.merkleRoot = info.merkleRoot; @@ -50,7 +50,7 @@ var BlockHeader = function BlockHeader(arg) { * @private */ BlockHeader._from = function _from(arg) { - var info = {}; + let info = {}; if (BufferUtil.isBuffer(arg)) { info = BlockHeader._fromBufferReader(BufferReader(arg)); } else if (_.isObject(arg)) { @@ -68,15 +68,15 @@ BlockHeader._from = function _from(arg) { */ BlockHeader._fromObject = function _fromObject(data) { $.checkArgument(data, 'data is required'); - var prevHash = data.prevHash; - var merkleRoot = data.merkleRoot; + let prevHash = data.prevHash; + let merkleRoot = data.merkleRoot; if (_.isString(data.prevHash)) { prevHash = BufferUtil.reverse(Buffer.from(data.prevHash, 'hex')); } if (_.isString(data.merkleRoot)) { merkleRoot = BufferUtil.reverse(Buffer.from(data.merkleRoot, 'hex')); } - var info = { + const info = { hash: data.hash, version: data.version, prevHash: prevHash, @@ -95,7 +95,7 @@ BlockHeader._fromObject = function _fromObject(data) { * @returns {BlockHeader} - An instance of block header */ BlockHeader.fromObject = function fromObject(obj) { - var info = BlockHeader._fromObject(obj); + const info = BlockHeader._fromObject(obj); return new BlockHeader(info); }; @@ -107,9 +107,9 @@ BlockHeader.fromRawBlock = function fromRawBlock(data) { if (!BufferUtil.isBuffer(data)) { data = Buffer.from(data, 'binary'); } - var br = BufferReader(data); + const br = BufferReader(data); br.pos = BlockHeader.Constants.START_OF_HEADER; - var info = BlockHeader._fromBufferReader(br); + const info = BlockHeader._fromBufferReader(br); return new BlockHeader(info); }; @@ -118,7 +118,7 @@ BlockHeader.fromRawBlock = function fromRawBlock(data) { * @returns {BlockHeader} - An instance of block header */ BlockHeader.fromBuffer = function fromBuffer(buf) { - var info = BlockHeader._fromBufferReader(BufferReader(buf)); + const info = BlockHeader._fromBufferReader(BufferReader(buf)); return new BlockHeader(info); }; @@ -127,7 +127,7 @@ BlockHeader.fromBuffer = function fromBuffer(buf) { * @returns {BlockHeader} - An instance of block header */ BlockHeader.fromString = function fromString(str) { - var buf = Buffer.from(str, 'hex'); + const buf = Buffer.from(str, 'hex'); return BlockHeader.fromBuffer(buf); }; @@ -137,7 +137,9 @@ BlockHeader.fromString = function fromString(str) { * @private */ BlockHeader._fromBufferReader = function _fromBufferReader(br) { - var info = {}; + // Required lazily to avoid a circular dependency with ./auxpow + const AuxPow = require('./auxpow'); + const info = {}; info.version = br.readInt32LE(); info.prevHash = br.read(32); info.merkleRoot = br.read(32); @@ -153,7 +155,7 @@ BlockHeader._fromBufferReader = function _fromBufferReader(br) { * @returns {BlockHeader} - An instance of block header */ BlockHeader.fromBufferReader = function fromBufferReader(br) { - var info = BlockHeader._fromBufferReader(br); + const info = BlockHeader._fromBufferReader(br); return new BlockHeader(info); }; @@ -217,8 +219,8 @@ BlockHeader.prototype.toBufferWriter = function toBufferWriter(bw, includeAuxPow BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(bits) { bits = bits || this.bits; - var target = new BN(bits & 0xffffff); - var mov = 8 * ((bits >>> 24) - 3); + let target = new BN(bits & 0xffffff); + let mov = 8 * ((bits >>> 24) - 3); while (mov-- > 0) { target = target.mul(new BN(2)); } @@ -255,7 +257,7 @@ BlockHeader.prototype.getDifficulty = function getDifficulty() { * @returns {Buffer} - The little endian hash buffer of the header */ BlockHeader.prototype._getHash = function hash() { - var buf = this.toBuffer(false); + const buf = this.toBuffer(false); return Hash.sha256sha256(buf); }; @@ -280,7 +282,7 @@ Object.defineProperty(BlockHeader.prototype, 'hash', idProperty); * @returns {Boolean} - If timestamp is not too far in the future */ BlockHeader.prototype.validTimestamp = function validTimestamp() { - var currentTime = Math.round(new Date().getTime() / 1000); + const currentTime = Math.round(new Date().getTime() / 1000); if (this.time > currentTime + BlockHeader.Constants.MAX_TIME_OFFSET) { return false; } @@ -291,15 +293,15 @@ BlockHeader.prototype.validTimestamp = function validTimestamp() { * @returns {Boolean} - If the proof-of-work hash satisfies the target difficulty */ BlockHeader.prototype.validProofOfWork = function validProofOfWork() { - // For Litecoin, we use the scrypt hash to calculate proof of work + // For Dogecoin, we use the scrypt hash to calculate proof of work let hashBuf; if (this.isAuxPow()) { hashBuf = this.auxpow.parentBlock.toBuffer(); } else { - hashBuf = this.toBuffer() + hashBuf = this.toBuffer(); } - var pow = new BN(Hash.scrypt(hashBuf)); - var target = this.getTargetDifficulty(); + const pow = new BN(Hash.scrypt(hashBuf)); + const target = this.getTargetDifficulty(); if (pow.cmp(target) > 0) { return false; @@ -322,7 +324,7 @@ BlockHeader.prototype.isAuxPow = function() { // Reference for AuxPoW bit: // https://github.com/dogecoin/dogecoin/blob/0b46a40ed125d7bf4b5a485b91350bc8bdc48fc8/src/primitives/pureheader.h#L131 return Boolean(this.version & (1 << 8)); -} +}; Object.defineProperty(BlockHeader.prototype, 'auxpow', { configurable: false, @@ -336,7 +338,7 @@ Object.defineProperty(BlockHeader.prototype, 'auxpow', { } return null; } -}) +}); BlockHeader.Constants = { @@ -346,5 +348,3 @@ BlockHeader.Constants = { }; module.exports = BlockHeader; - -var AuxPow = require('./auxpow'); diff --git a/packages/bitcore-lib-doge/lib/crypto/hash.js b/packages/bitcore-lib-doge/lib/crypto/hash.js index 2dea3335c59..21674f682c6 100644 --- a/packages/bitcore-lib-doge/lib/crypto/hash.js +++ b/packages/bitcore-lib-doge/lib/crypto/hash.js @@ -1,22 +1,22 @@ 'use strict'; -var crypto = require('crypto'); +var nodeCrypto = require('crypto'); +var Scrypt = require('scryptsy'); var BufferUtil = require('../util/buffer'); -var Scrypt = require('scryptsy') var $ = require('../util/preconditions'); var Hash = module.exports; Hash.sha1 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha1').update(buf).digest(); + return nodeCrypto.createHash('sha1').update(buf).digest(); }; Hash.sha1.blocksize = 512; Hash.sha256 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha256').update(buf).digest(); + return nodeCrypto.createHash('sha256').update(buf).digest(); }; Hash.sha256.blocksize = 512; @@ -28,7 +28,7 @@ Hash.sha256sha256 = function(buf) { Hash.ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('ripemd160').update(buf).digest(); + return nodeCrypto.createHash('ripemd160').update(buf).digest(); }; Hash.sha256ripemd160 = function(buf) { @@ -38,38 +38,38 @@ Hash.sha256ripemd160 = function(buf) { Hash.sha512 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha512').update(buf).digest(); + return nodeCrypto.createHash('sha512').update(buf).digest(); }; Hash.sha512.blocksize = 1024; Hash.hmac = function(hashf, data, key) { - //http://en.wikipedia.org/wiki/Hash-based_message_authentication_code - //http://tools.ietf.org/html/rfc4868#section-2 + // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code + // http://tools.ietf.org/html/rfc4868#section-2 $.checkArgument(BufferUtil.isBuffer(data)); $.checkArgument(BufferUtil.isBuffer(key)); $.checkArgument(hashf.blocksize); - var blocksize = hashf.blocksize / 8; + const blocksize = hashf.blocksize / 8; if (key.length > blocksize) { key = hashf(key); } else if (key < blocksize) { - var fill = Buffer.alloc(blocksize); + const fill = Buffer.alloc(blocksize); fill.fill(0); key.copy(fill); key = fill; } - var o_key = Buffer.alloc(blocksize); + const o_key = Buffer.alloc(blocksize); o_key.fill(0x5c); - var i_key = Buffer.alloc(blocksize); + const i_key = Buffer.alloc(blocksize); i_key.fill(0x36); - var o_key_pad = Buffer.alloc(blocksize); - var i_key_pad = Buffer.alloc(blocksize); - for (var i = 0; i < blocksize; i++) { + const o_key_pad = Buffer.alloc(blocksize); + const i_key_pad = Buffer.alloc(blocksize); + for (let i = 0; i < blocksize; i++) { o_key_pad[i] = o_key[i] ^ key[i]; i_key_pad[i] = i_key[i] ^ key[i]; } @@ -85,7 +85,7 @@ Hash.sha512hmac = function(data, key) { return Hash.hmac(Hash.sha512, data, key); }; -// Litecoin Scrypt hashing +// Dogecoin Scrypt hashing Hash.scrypt = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); return BufferUtil.reverse(Scrypt(buf, buf, 1024, 1, 1, 32)); diff --git a/packages/bitcore-lib-doge/lib/script/interpreter.js b/packages/bitcore-lib-doge/lib/script/interpreter.js index ddec35f4a83..44bdab523a1 100644 --- a/packages/bitcore-lib-doge/lib/script/interpreter.js +++ b/packages/bitcore-lib-doge/lib/script/interpreter.js @@ -1,13 +1,12 @@ 'use strict'; var _ = require('lodash'); - -var Script = require('./script'); -var Opcode = require('../opcode'); var BN = require('../crypto/bn'); var Hash = require('../crypto/hash'); var Signature = require('../crypto/signature'); +var Opcode = require('../opcode'); var PublicKey = require('../publickey'); +var Script = require('./script'); /** * Bitcoin transactions contain scripts. Each input has a script called the @@ -33,8 +32,8 @@ var Interpreter = function Interpreter(obj) { Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, satoshis, flags) { - var scriptPubKey = new Script(); - var stack = []; + let scriptPubKey = new Script(); + let stack = []; if (version === 0) { if (program.length === 32) { @@ -43,9 +42,9 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, return false; } - var scriptPubKeyBuffer = witness[witness.length - 1]; + const scriptPubKeyBuffer = witness[witness.length - 1]; scriptPubKey = new Script(scriptPubKeyBuffer); - var hash = Hash.sha256(scriptPubKeyBuffer); + const hash = Hash.sha256(scriptPubKeyBuffer); if (hash.toString('hex') !== program.toString('hex')) { this.errstr = 'SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH'; return false; @@ -88,7 +87,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, }); // Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack - for (let s of stack) { + for (const s of stack) { if (s.length > Interpreter.MAX_SCRIPT_ELEMENT_SIZE) { this.errstr = 'SCRIPT_ERR_PUSH_SIZE'; return false; @@ -104,7 +103,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, return false; } - var buf = this.stack[this.stack.length - 1]; + const buf = this.stack[this.stack.length - 1]; if (!Interpreter.castToBool(buf)) { this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'; return false; @@ -132,7 +131,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, */ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) { - var Transaction = require('../transaction'); + const Transaction = require('../transaction'); if (_.isUndefined(tx)) { tx = new Transaction(); } @@ -157,7 +156,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, satoshis: 0, flags: flags }); - var stackCopy; + let stackCopy; if ((flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY) !== 0 && !scriptSig.isPushOnly()) { this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'; @@ -173,7 +172,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, stackCopy = this.stack.slice(); } - var stack = this.stack; + let stack = this.stack; this.initialize(); this.set({ script: scriptPubkey, @@ -193,15 +192,15 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, return false; } - var buf = this.stack[this.stack.length - 1]; + const buf = this.stack[this.stack.length - 1]; if (!Interpreter.castToBool(buf)) { this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'; return false; } - var hadWitness = false; + let hadWitness = false; if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { - var witnessValues = {}; + const witnessValues = {}; if (scriptPubkey.isWitnessProgram(witnessValues)) { hadWitness = true; if (scriptSig.toBuffer().length !== 0) { @@ -228,8 +227,8 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, throw new Error('internal error - stack copy empty'); } - var redeemScriptSerialized = stackCopy[stackCopy.length - 1]; - var redeemScript = Script.fromBuffer(redeemScriptSerialized); + const redeemScriptSerialized = stackCopy[stackCopy.length - 1]; + const redeemScript = Script.fromBuffer(redeemScriptSerialized); stackCopy.pop(); this.initialize(); @@ -256,10 +255,10 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, return false; } if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { - var p2shWitnessValues = {}; + const p2shWitnessValues = {}; if (redeemScript.isWitnessProgram(p2shWitnessValues)) { hadWitness = true; - var redeemScriptPush = new Script(); + const redeemScriptPush = new Script(); redeemScriptPush.add(redeemScript.toBuffer()); if (scriptSig.toHex() !== redeemScriptPush.toHex()) { this.errstr = 'SCRIPT_ERR_WITNESS_MALLEATED_P2SH'; @@ -281,16 +280,16 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, // a clean stack (the P2SH inputs remain). The same holds for witness // evaluation. if ((this.flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) { - // Disallow CLEANSTACK without P2SH, as otherwise a switch - // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a - // softfork (and P2SH should be one). - if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) - throw 'flags & SCRIPT_VERIFY_P2SH'; - - if (stackCopy.length != 1) { - this.errstr = 'SCRIPT_ERR_CLEANSTACK'; - return false; - } + // Disallow CLEANSTACK without P2SH, as otherwise a switch + // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a + // softfork (and P2SH should be one). + if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) + throw 'flags & SCRIPT_VERIFY_P2SH'; + + if (stackCopy.length != 1) { + this.errstr = 'SCRIPT_ERR_CLEANSTACK'; + return false; + } } if ((this.flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { @@ -395,7 +394,7 @@ Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 7); // be true". // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. -Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8), +Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8); // CLTV See BIP65 for details. Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1 << 9); @@ -467,7 +466,7 @@ Interpreter.SIGVERSION_WITNESS_V0 = 1; Interpreter.castToBool = function(buf) { - for (var i = 0; i < buf.length; i++) { + for (let i = 0; i < buf.length; i++) { if (buf[i] !== 0) { // can be negative zero if (i === buf.length - 1 && buf[i] === 0x80) { @@ -483,13 +482,13 @@ Interpreter.castToBool = function(buf) { * Translated from bitcoind's CheckSignatureEncoding */ Interpreter.prototype.checkSignatureEncoding = function(buf) { - var sig; + let sig; - // Empty signature. Not strictly DER encoded, but allowed to provide a - // compact way to provide an invalid signature for use with CHECK(MULTI)SIG - if (buf.length == 0) { - return true; - } + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (buf.length == 0) { + return true; + } if ((this.flags & (Interpreter.SCRIPT_VERIFY_DERSIG | Interpreter.SCRIPT_VERIFY_LOW_S | Interpreter.SCRIPT_VERIFY_STRICTENC)) !== 0 && !Signature.isTxDER(buf)) { this.errstr = 'SCRIPT_ERR_SIG_DER_INVALID_FORMAT'; @@ -542,7 +541,7 @@ Interpreter.prototype.evaluate = function() { try { while (this.pc < this.script.chunks.length) { - var fSuccess = this.step(); + const fSuccess = this.step(); if (!fSuccess) { return false; } @@ -584,7 +583,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || + (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || (this.tx.nLockTime >= Interpreter.LOCKTIME_THRESHOLD && nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN)) )) { return false; @@ -611,7 +610,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { } return true; -} +}; /** @@ -622,73 +621,73 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { */ Interpreter.prototype.checkSequence = function(nSequence) { - // Relative lock times are supported by comparing the passed in operand to - // the sequence number of the input. - var txToSequence = this.tx.inputs[this.nin].sequenceNumber; + // Relative lock times are supported by comparing the passed in operand to + // the sequence number of the input. + const txToSequence = this.tx.inputs[this.nin].sequenceNumber; - // Fail if the transaction's version number is not set high enough to - // trigger BIP 68 rules. - if (this.tx.version < 2) { - return false; - } + // Fail if the transaction's version number is not set high enough to + // trigger BIP 68 rules. + if (this.tx.version < 2) { + return false; + } - // Sequence numbers with their most significant bit set are not consensus - // constrained. Testing that the transaction's sequence number do not have - // this bit set prevents using this property to get around a - // CHECKSEQUENCEVERIFY check. - var SEQUENCE_LOCKTIME_DISABLE_FLAG = Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG; - if (txToSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG) { - return false; - } + // Sequence numbers with their most significant bit set are not consensus + // constrained. Testing that the transaction's sequence number do not have + // this bit set prevents using this property to get around a + // CHECKSEQUENCEVERIFY check. + const SEQUENCE_LOCKTIME_DISABLE_FLAG = Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG; + if (txToSequence & SEQUENCE_LOCKTIME_DISABLE_FLAG) { + return false; + } - // Mask off any bits that do not have consensus-enforced meaning before - // doing the integer comparisons - var nLockTimeMask = - Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; - var txToSequenceMasked = new BN(txToSequence & nLockTimeMask); - var nSequenceMasked = nSequence.and(new BN(nLockTimeMask)); - - // There are two kinds of nSequence: lock-by-blockheight and - // lock-by-blocktime, distinguished by whether nSequenceMasked < - // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. - // - // We want to compare apples to apples, so fail the script unless the type - // of nSequenceMasked being tested is the same as the nSequenceMasked in the - // transaction. - var SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); + // Mask off any bits that do not have consensus-enforced meaning before + // doing the integer comparisons + const nLockTimeMask = + Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; + const txToSequenceMasked = new BN(txToSequence & nLockTimeMask); + const nSequenceMasked = nSequence.and(new BN(nLockTimeMask)); + + // There are two kinds of nSequence: lock-by-blockheight and + // lock-by-blocktime, distinguished by whether nSequenceMasked < + // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script unless the type + // of nSequenceMasked being tested is the same as the nSequenceMasked in the + // transaction. + const SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); - if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && + if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)) || (txToSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)))) { - return false; - } + return false; + } - // Now that we know we're comparing apples-to-apples, the comparison is a - // simple numeric one. - if (nSequenceMasked.gt(txToSequenceMasked)) { - return false; - } - return true; + // Now that we know we're comparing apples-to-apples, the comparison is a + // simple numeric one. + if (nSequenceMasked.gt(txToSequenceMasked)) { + return false; } + return true; +}; /** * Based on the inner loop of bitcoind's EvalScript function * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 */ Interpreter.prototype.step = function() { - var fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0; + const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0; - //bool fExec = !count(vfExec.begin(), vfExec.end(), false); - var fExec = (this.vfExec.indexOf(false) === -1); - var buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, subscript; - var sig, pubkey; - var fValue, fSuccess; + // bool fExec = !count(vfExec.begin(), vfExec.end(), false); + const fExec = (this.vfExec.indexOf(false) === -1); + let buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, subscript; + let sig, pubkey; + let fValue, fSuccess; // Read instruction - var chunk = this.script.chunks[this.pc]; + const chunk = this.script.chunks[this.pc]; this.pc++; - var opcodenum = chunk.opcodenum; + const opcodenum = chunk.opcodenum; if (_.isUndefined(opcodenum)) { this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE'; return false; @@ -963,16 +962,15 @@ Interpreter.prototype.step = function() { break; case Opcode.OP_RETURN: - { - this.errstr = 'SCRIPT_ERR_OP_RETURN'; - return false; - } - break; + { + this.errstr = 'SCRIPT_ERR_OP_RETURN'; + return false; + } - // - // Stack ops - // + // + // Stack ops + // case Opcode.OP_TOALTSTACK: { if (this.stack.length < 1) { @@ -1028,7 +1026,7 @@ Interpreter.prototype.step = function() { } buf1 = this.stack[this.stack.length - 3]; buf2 = this.stack[this.stack.length - 2]; - var buf3 = this.stack[this.stack.length - 1]; + const buf3 = this.stack[this.stack.length - 1]; this.stack.push(buf1); this.stack.push(buf2); this.stack.push(buf3); @@ -1178,7 +1176,7 @@ Interpreter.prototype.step = function() { } x1 = this.stack[this.stack.length - 3]; x2 = this.stack[this.stack.length - 2]; - var x3 = this.stack[this.stack.length - 1]; + const x3 = this.stack[this.stack.length - 1]; this.stack[this.stack.length - 3] = x2; this.stack[this.stack.length - 2] = x3; this.stack[this.stack.length - 1] = x1; @@ -1229,7 +1227,7 @@ Interpreter.prototype.step = function() { // case Opcode.OP_EQUAL: case Opcode.OP_EQUALVERIFY: - //case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL + // case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL { // (x1 x2 - bool) if (this.stack.length < 2) { @@ -1238,7 +1236,7 @@ Interpreter.prototype.step = function() { } buf1 = this.stack[this.stack.length - 2]; buf2 = this.stack[this.stack.length - 1]; - var fEqual = buf1.toString('hex') === buf2.toString('hex'); + const fEqual = buf1.toString('hex') === buf2.toString('hex'); this.stack.pop(); this.stack.pop(); this.stack.push(fEqual ? Interpreter.true : Interpreter.false); @@ -1292,7 +1290,7 @@ Interpreter.prototype.step = function() { case Opcode.OP_0NOTEQUAL: bn = new BN((bn.cmp(BN.Zero) !== 0) + 0); break; - //default: assert(!'invalid opcode'); break; // TODO: does this ever occur? + // default: assert(!'invalid opcode'); break; // TODO: does this ever occur? } this.stack.pop(); this.stack.push(bn.toScriptNumBuffer()); @@ -1400,8 +1398,8 @@ Interpreter.prototype.step = function() { } bn1 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 3], fRequireMinimal); bn2 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal); - var bn3 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal); - //bool fValue = (bn2 <= bn1 && bn1 < bn3); + const bn3 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal); + // bool fValue = (bn2 <= bn1 && bn1 < bn3); fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0); this.stack.pop(); this.stack.pop(); @@ -1426,9 +1424,9 @@ Interpreter.prototype.step = function() { return false; } buf = this.stack[this.stack.length - 1]; - //valtype vchHash((opcode == Opcode.OP_RIPEMD160 || + // valtype vchHash((opcode == Opcode.OP_RIPEMD160 || // opcode == Opcode.OP_SHA1 || opcode == Opcode.OP_HASH160) ? 20 : 32); - var bufHash; + let bufHash; if (opcodenum === Opcode.OP_RIPEMD160) { bufHash = Hash.ripemd160(buf); } else if (opcodenum === Opcode.OP_SHA1) { @@ -1475,7 +1473,7 @@ Interpreter.prototype.step = function() { // Drop the signature, since there's no way for a signature to sign itself if (this.sigversion === Interpreter.SIGVERSION_BASE) { - var tmpScript = new Script().add(bufSig); + const tmpScript = new Script().add(bufSig); subscript.findAndDelete(tmpScript); } @@ -1484,7 +1482,7 @@ Interpreter.prototype.step = function() { pubkey = PublicKey.fromBuffer(bufPubkey, false); fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.sigversion, this.satoshis); } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fSuccess = false; } @@ -1515,13 +1513,13 @@ Interpreter.prototype.step = function() { { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) - var i = 1; + let i = 1; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nKeysCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); + let nKeysCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); if (nKeysCount < 0 || nKeysCount > 20) { this.errstr = 'SCRIPT_ERR_PUBKEY_COUNT'; return false; @@ -1532,27 +1530,27 @@ Interpreter.prototype.step = function() { return false; } // int ikey = ++i; - var ikey = ++i; + let ikey = ++i; i += nKeysCount; // ikey2 is the position of last non-signature item in // the stack. Top stack item = 1. With // SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if // operation fails. - var ikey2 = nKeysCount + 2; + let ikey2 = nKeysCount + 2; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nSigsCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); + let nSigsCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); if (nSigsCount < 0 || nSigsCount > nKeysCount) { this.errstr = 'SCRIPT_ERR_SIG_COUNT'; return false; } // int isig = ++i; - var isig = ++i; + let isig = ++i; i += nSigsCount; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; @@ -1566,7 +1564,7 @@ Interpreter.prototype.step = function() { // Drop the signatures, since there's no way for a signature to sign itself if (this.sigversion === Interpreter.SIGVERSION_BASE) { - for (var k = 0; k < nSigsCount; k++) { + for (let k = 0; k < nSigsCount; k++) { bufSig = this.stack[this.stack.length - isig - k]; subscript.findAndDelete(new Script().add(bufSig)); } @@ -1589,7 +1587,7 @@ Interpreter.prototype.step = function() { pubkey = PublicKey.fromBuffer(bufPubkey, false); fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.sigversion, this.satoshis); } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fOk = false; } diff --git a/packages/bitcore-lib-doge/lib/transaction/input/publickeyhash.js b/packages/bitcore-lib-doge/lib/transaction/input/publickeyhash.js index d8bffda5680..c9b78c73219 100644 --- a/packages/bitcore-lib-doge/lib/transaction/input/publickeyhash.js +++ b/packages/bitcore-lib-doge/lib/transaction/input/publickeyhash.js @@ -1,20 +1,16 @@ 'use strict'; var inherits = require('inherits'); - -var $ = require('../../util/preconditions'); -var BufferUtil = require('../../util/buffer'); - var Hash = require('../../crypto/hash'); -var Input = require('./input'); -var Output = require('../output'); -var Sighash = require('../sighash'); -var SighashWitness = require('../sighashwitness'); +var Signature = require('../../crypto/signature'); var BufferWriter = require('../../encoding/bufferwriter'); -var BufferUtil = require('../../util/buffer'); var Script = require('../../script'); -var Signature = require('../../crypto/signature'); +var BufferUtil = require('../../util/buffer'); +var $ = require('../../util/preconditions'); +var Output = require('../output'); +var Sighash = require('../sighash'); var TransactionSignature = require('../signature'); +var Input = require('./input'); /** * Represents a special kind of input of PayToPublicKeyHash kind. @@ -27,9 +23,9 @@ inherits(PublicKeyHashInput, Input); PublicKeyHashInput.prototype.getRedeemScript = function(publicKey) { if (!this.redeemScript) { - var redeemScript = Script.buildWitnessV0Out(publicKey); + const redeemScript = Script.buildWitnessV0Out(publicKey); if (Script.buildScriptHashOut(redeemScript).equals(this.output.script)) { - var scriptSig = new Script(); + const scriptSig = new Script(); scriptSig.add(redeemScript.toBuffer()); this.setScript(scriptSig); this.redeemScript = redeemScript; @@ -39,14 +35,14 @@ PublicKeyHashInput.prototype.getRedeemScript = function(publicKey) { }; PublicKeyHashInput.prototype.getScriptCode = function(publicKey) { - var writer = new BufferWriter(); - var script; + const writer = new BufferWriter(); + let script; if (this.output.script.isScriptHashOut()) { script = this.getRedeemScript(publicKey); } else { script = this.output.script; } - var scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); + const scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); writer.writeVarintNum(scriptBuffer.length); writer.write(scriptBuffer); return writer.toBuffer(); @@ -159,4 +155,4 @@ PublicKeyHashInput.prototype._estimateSize = function() { return this._getBaseSize() + 1 + PublicKeyHashInput.SCRIPT_MAX_SIZE; }; -module.exports = PublicKeyHashInput; \ No newline at end of file +module.exports = PublicKeyHashInput; diff --git a/packages/bitcore-lib-ltc/lib/networks.js b/packages/bitcore-lib-ltc/lib/networks.js index f8b63ac4bd3..2275f159316 100644 --- a/packages/bitcore-lib-ltc/lib/networks.js +++ b/packages/bitcore-lib-ltc/lib/networks.js @@ -1,6 +1,7 @@ 'use strict'; var BufferUtil = require('./util/buffer'); var JSUtil = require('./util/js'); + var networks = []; var networkMaps = {}; @@ -79,7 +80,7 @@ function is(str) { */ function addNetwork(data) { - var network = new Network(); + const network = new Network(); JSUtil.defineImmutable(network, { name: data.name, @@ -113,12 +114,6 @@ function addNetwork(data) { }); } - if (data.bech32prefix) { - JSUtil.defineImmutable(network, { - bech32prefix: data.bech32prefix - }); - } - for (const value of Object.values(network)) { if (value != null && typeof value !== 'object') { if (!networkMaps[value]) { @@ -151,12 +146,12 @@ function removeNetwork(network) { if (typeof network !== 'object') { network = get(network); } - for (var i = 0; i < networks.length; i++) { + for (let i = 0; i < networks.length; i++) { if (networks[i] === network) { networks.splice(i, 1); } } - for (var key in networkMaps) { + for (const key in networkMaps) { if (networkMaps[key].length) { const index = networkMaps[key].indexOf(network); if (index >= 0) { @@ -218,7 +213,7 @@ addNetwork({ dnsSeeds: [ 'testnet-seed.litecointools.com', 'seed-b.litecoin.loshan.co.uk' - ] + ] }] }); diff --git a/packages/bitcore-lib-ltc/lib/script/interpreter.js b/packages/bitcore-lib-ltc/lib/script/interpreter.js index 4fa5e91c8de..bd4c35d1708 100644 --- a/packages/bitcore-lib-ltc/lib/script/interpreter.js +++ b/packages/bitcore-lib-ltc/lib/script/interpreter.js @@ -1,13 +1,12 @@ 'use strict'; var _ = require('lodash'); - -var Script = require('./script'); -var Opcode = require('../opcode'); var BN = require('../crypto/bn'); var Hash = require('../crypto/hash'); var Signature = require('../crypto/signature'); +var Opcode = require('../opcode'); var PublicKey = require('../publickey'); +var Script = require('./script'); /** * Bitcoin transactions contain scripts. Each input has a script called the @@ -33,8 +32,8 @@ var Interpreter = function Interpreter(obj) { Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, satoshis, flags) { - var scriptPubKey = new Script(); - var stack = []; + let scriptPubKey = new Script(); + let stack = []; if (version === 0) { if (program.length === 32) { @@ -43,9 +42,9 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, return false; } - var scriptPubKeyBuffer = witness[witness.length - 1]; + const scriptPubKeyBuffer = witness[witness.length - 1]; scriptPubKey = new Script(scriptPubKeyBuffer); - var hash = Hash.sha256(scriptPubKeyBuffer); + const hash = Hash.sha256(scriptPubKeyBuffer); if (hash.toString('hex') !== program.toString('hex')) { this.errstr = 'SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH'; return false; @@ -104,7 +103,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, return false; } - var buf = this.stack[this.stack.length - 1]; + const buf = this.stack[this.stack.length - 1]; if (!Interpreter.castToBool(buf)) { this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'; return false; @@ -132,7 +131,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, */ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) { - var Transaction = require('../transaction'); + const Transaction = require('../transaction'); if (_.isUndefined(tx)) { tx = new Transaction(); } @@ -157,7 +156,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, satoshis: 0, flags: flags }); - var stackCopy; + let stackCopy; if ((flags & Interpreter.SCRIPT_VERIFY_SIGPUSHONLY) !== 0 && !scriptSig.isPushOnly()) { this.errstr = 'SCRIPT_ERR_SIG_PUSHONLY'; @@ -173,7 +172,7 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, stackCopy = this.stack.slice(); } - var stack = this.stack; + let stack = this.stack; this.initialize(); this.set({ script: scriptPubkey, @@ -193,15 +192,15 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, return false; } - var buf = this.stack[this.stack.length - 1]; + const buf = this.stack[this.stack.length - 1]; if (!Interpreter.castToBool(buf)) { this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_STACK'; return false; } - var hadWitness = false; + let hadWitness = false; if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { - var witnessValues = {}; + const witnessValues = {}; if (scriptPubkey.isWitnessProgram(witnessValues)) { hadWitness = true; if (scriptSig.toBuffer().length !== 0) { @@ -228,8 +227,8 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, throw new Error('internal error - stack copy empty'); } - var redeemScriptSerialized = stackCopy[stackCopy.length - 1]; - var redeemScript = Script.fromBuffer(redeemScriptSerialized); + const redeemScriptSerialized = stackCopy[stackCopy.length - 1]; + const redeemScript = Script.fromBuffer(redeemScriptSerialized); stackCopy.pop(); this.initialize(); @@ -256,10 +255,10 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, return false; } if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { - var p2shWitnessValues = {}; + const p2shWitnessValues = {}; if (redeemScript.isWitnessProgram(p2shWitnessValues)) { hadWitness = true; - var redeemScriptPush = new Script(); + const redeemScriptPush = new Script(); redeemScriptPush.add(redeemScript.toBuffer()); if (scriptSig.toHex() !== redeemScriptPush.toHex()) { this.errstr = 'SCRIPT_ERR_WITNESS_MALLEATED_P2SH'; @@ -281,16 +280,16 @@ Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, // a clean stack (the P2SH inputs remain). The same holds for witness // evaluation. if ((this.flags & Interpreter.SCRIPT_VERIFY_CLEANSTACK) != 0) { - // Disallow CLEANSTACK without P2SH, as otherwise a switch - // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a - // softfork (and P2SH should be one). - if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) - throw 'flags & SCRIPT_VERIFY_P2SH'; - - if (stackCopy.length != 1) { - this.errstr = 'SCRIPT_ERR_CLEANSTACK'; - return false; - } + // Disallow CLEANSTACK without P2SH, as otherwise a switch + // CLEANSTACK->P2SH+CLEANSTACK would be possible, which is not a + // softfork (and P2SH should be one). + if ((this.flags & Interpreter.SCRIPT_VERIFY_P2SH) == 0) + throw 'flags & SCRIPT_VERIFY_P2SH'; + + if (stackCopy.length != 1) { + this.errstr = 'SCRIPT_ERR_CLEANSTACK'; + return false; + } } if ((this.flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { @@ -395,7 +394,7 @@ Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 7); // be true". // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. -Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8), +Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8); // CLTV See BIP65 for details. Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1 << 9); @@ -476,7 +475,7 @@ Interpreter.SIGVERSION_WITNESS_V0 = 1; Interpreter.castToBool = function(buf) { - for (var i = 0; i < buf.length; i++) { + for (let i = 0; i < buf.length; i++) { if (buf[i] !== 0) { // can be negative zero if (i === buf.length - 1 && buf[i] === 0x80) { @@ -492,13 +491,13 @@ Interpreter.castToBool = function(buf) { * Translated from bitcoind's CheckSignatureEncoding */ Interpreter.prototype.checkSignatureEncoding = function(buf) { - var sig; + let sig; - // Empty signature. Not strictly DER encoded, but allowed to provide a - // compact way to provide an invalid signature for use with CHECK(MULTI)SIG - if (buf.length == 0) { - return true; - } + // Empty signature. Not strictly DER encoded, but allowed to provide a + // compact way to provide an invalid signature for use with CHECK(MULTI)SIG + if (buf.length == 0) { + return true; + } if ((this.flags & (Interpreter.SCRIPT_VERIFY_DERSIG | Interpreter.SCRIPT_VERIFY_LOW_S | Interpreter.SCRIPT_VERIFY_STRICTENC)) !== 0 && !Signature.isTxDER(buf)) { this.errstr = 'SCRIPT_ERR_SIG_DER_INVALID_FORMAT'; @@ -551,7 +550,7 @@ Interpreter.prototype.evaluate = function() { try { while (this.pc < this.script.chunks.length) { - var fSuccess = this.step(); + const fSuccess = this.step(); if (!fSuccess) { return false; } @@ -593,7 +592,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { // unless the type of nLockTime being tested is the same as // the nLockTime in the transaction. if (!( - (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || + (this.tx.nLockTime < Interpreter.LOCKTIME_THRESHOLD && nLockTime.lt(Interpreter.LOCKTIME_THRESHOLD_BN)) || (this.tx.nLockTime >= Interpreter.LOCKTIME_THRESHOLD && nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN)) )) { return false; @@ -620,7 +619,7 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { } return true; -} +}; /** @@ -631,72 +630,72 @@ Interpreter.prototype.checkLockTime = function(nLockTime) { */ Interpreter.prototype.checkSequence = function(nSequence) { - // Relative lock times are supported by comparing the passed in operand to - // the sequence number of the input. - var txToSequence = this.tx.inputs[this.nin].sequenceNumber; + // Relative lock times are supported by comparing the passed in operand to + // the sequence number of the input. + const txToSequence = this.tx.inputs[this.nin].sequenceNumber; - // Fail if the transaction's version number is not set high enough to - // trigger BIP 68 rules. - if (this.tx.version < 2) { - return false; - } + // Fail if the transaction's version number is not set high enough to + // trigger BIP 68 rules. + if (this.tx.version < 2) { + return false; + } - // Sequence numbers with their most significant bit set are not consensus - // constrained. Testing that the transaction's sequence number do not have - // this bit set prevents using this property to get around a - // CHECKSEQUENCEVERIFY check. - if (txToSequence & Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) { - return false; - } + // Sequence numbers with their most significant bit set are not consensus + // constrained. Testing that the transaction's sequence number do not have + // this bit set prevents using this property to get around a + // CHECKSEQUENCEVERIFY check. + if (txToSequence & Interpreter.SEQUENCE_LOCKTIME_DISABLE_FLAG) { + return false; + } - // Mask off any bits that do not have consensus-enforced meaning before - // doing the integer comparisons - var nLockTimeMask = - Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; - var txToSequenceMasked = new BN(txToSequence & nLockTimeMask); - var nSequenceMasked = nSequence.and(new BN(nLockTimeMask)); - - // There are two kinds of nSequence: lock-by-blockheight and - // lock-by-blocktime, distinguished by whether nSequenceMasked < - // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. - // - // We want to compare apples to apples, so fail the script unless the type - // of nSequenceMasked being tested is the same as the nSequenceMasked in the - // transaction. - var SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); + // Mask off any bits that do not have consensus-enforced meaning before + // doing the integer comparisons + const nLockTimeMask = + Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG | Interpreter.SEQUENCE_LOCKTIME_MASK; + const txToSequenceMasked = new BN(txToSequence & nLockTimeMask); + const nSequenceMasked = nSequence.and(new BN(nLockTimeMask)); + + // There are two kinds of nSequence: lock-by-blockheight and + // lock-by-blocktime, distinguished by whether nSequenceMasked < + // CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script unless the type + // of nSequenceMasked being tested is the same as the nSequenceMasked in the + // transaction. + const SEQUENCE_LOCKTIME_TYPE_FLAG_BN = new BN(Interpreter.SEQUENCE_LOCKTIME_TYPE_FLAG); - if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && + if (!((txToSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.lt(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)) || (txToSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN) && nSequenceMasked.gte(SEQUENCE_LOCKTIME_TYPE_FLAG_BN)))) { - return false; - } + return false; + } - // Now that we know we're comparing apples-to-apples, the comparison is a - // simple numeric one. - if (nSequenceMasked.gt(txToSequenceMasked)) { - return false; - } - return true; + // Now that we know we're comparing apples-to-apples, the comparison is a + // simple numeric one. + if (nSequenceMasked.gt(txToSequenceMasked)) { + return false; } + return true; +}; /** * Based on the inner loop of bitcoind's EvalScript function * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 */ Interpreter.prototype.step = function() { - var fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0; + const fRequireMinimal = (this.flags & Interpreter.SCRIPT_VERIFY_MINIMALDATA) !== 0; - //bool fExec = !count(vfExec.begin(), vfExec.end(), false); - var fExec = (this.vfExec.indexOf(false) === -1); - var buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, subscript; - var sig, pubkey; - var fValue, fSuccess; + // bool fExec = !count(vfExec.begin(), vfExec.end(), false); + const fExec = (this.vfExec.indexOf(false) === -1); + let buf, buf1, buf2, spliced, n, x1, x2, bn, bn1, bn2, bufSig, bufPubkey, subscript; + let sig, pubkey; + let fValue, fSuccess; // Read instruction - var chunk = this.script.chunks[this.pc]; + const chunk = this.script.chunks[this.pc]; this.pc++; - var opcodenum = chunk.opcodenum; + const opcodenum = chunk.opcodenum; if (_.isUndefined(opcodenum)) { this.errstr = 'SCRIPT_ERR_UNDEFINED_OPCODE'; return false; @@ -977,16 +976,15 @@ Interpreter.prototype.step = function() { break; case Opcode.OP_RETURN: - { - this.errstr = 'SCRIPT_ERR_OP_RETURN'; - return false; - } - break; + { + this.errstr = 'SCRIPT_ERR_OP_RETURN'; + return false; + } - // - // Stack ops - // + // + // Stack ops + // case Opcode.OP_TOALTSTACK: { if (this.stack.length < 1) { @@ -1042,7 +1040,7 @@ Interpreter.prototype.step = function() { } buf1 = this.stack[this.stack.length - 3]; buf2 = this.stack[this.stack.length - 2]; - var buf3 = this.stack[this.stack.length - 1]; + const buf3 = this.stack[this.stack.length - 1]; this.stack.push(buf1); this.stack.push(buf2); this.stack.push(buf3); @@ -1192,7 +1190,7 @@ Interpreter.prototype.step = function() { } x1 = this.stack[this.stack.length - 3]; x2 = this.stack[this.stack.length - 2]; - var x3 = this.stack[this.stack.length - 1]; + const x3 = this.stack[this.stack.length - 1]; this.stack[this.stack.length - 3] = x2; this.stack[this.stack.length - 2] = x3; this.stack[this.stack.length - 1] = x1; @@ -1243,7 +1241,7 @@ Interpreter.prototype.step = function() { // case Opcode.OP_EQUAL: case Opcode.OP_EQUALVERIFY: - //case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL + // case Opcode.OP_NOTEQUAL: // use Opcode.OP_NUMNOTEQUAL { // (x1 x2 - bool) if (this.stack.length < 2) { @@ -1252,7 +1250,7 @@ Interpreter.prototype.step = function() { } buf1 = this.stack[this.stack.length - 2]; buf2 = this.stack[this.stack.length - 1]; - var fEqual = buf1.toString('hex') === buf2.toString('hex'); + const fEqual = buf1.toString('hex') === buf2.toString('hex'); this.stack.pop(); this.stack.pop(); this.stack.push(fEqual ? Interpreter.true : Interpreter.false); @@ -1306,7 +1304,7 @@ Interpreter.prototype.step = function() { case Opcode.OP_0NOTEQUAL: bn = new BN((bn.cmp(BN.Zero) !== 0) + 0); break; - //default: assert(!'invalid opcode'); break; // TODO: does this ever occur? + // default: assert(!'invalid opcode'); break; // TODO: does this ever occur? } this.stack.pop(); this.stack.push(bn.toScriptNumBuffer()); @@ -1414,8 +1412,8 @@ Interpreter.prototype.step = function() { } bn1 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 3], fRequireMinimal); bn2 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal); - var bn3 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal); - //bool fValue = (bn2 <= bn1 && bn1 < bn3); + const bn3 = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal); + // bool fValue = (bn2 <= bn1 && bn1 < bn3); fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0); this.stack.pop(); this.stack.pop(); @@ -1440,9 +1438,9 @@ Interpreter.prototype.step = function() { return false; } buf = this.stack[this.stack.length - 1]; - //valtype vchHash((opcode == Opcode.OP_RIPEMD160 || + // valtype vchHash((opcode == Opcode.OP_RIPEMD160 || // opcode == Opcode.OP_SHA1 || opcode == Opcode.OP_HASH160) ? 20 : 32); - var bufHash; + let bufHash; if (opcodenum === Opcode.OP_RIPEMD160) { bufHash = Hash.ripemd160(buf); } else if (opcodenum === Opcode.OP_SHA1) { @@ -1488,11 +1486,11 @@ Interpreter.prototype.step = function() { // Drop the signature in pre-segwit scripts but not segwit scripts if (this.sigversion === Interpreter.SIGVERSION_BASE) { // Drop the signature, since there's no way for a signature to sign itself - var tmpScript = new Script().add(bufSig); - var preDelCount = subscript.chunks.length; + const tmpScript = new Script().add(bufSig); + const preDelCount = subscript.chunks.length; subscript.findAndDelete(tmpScript); - var found = subscript.chunks.length < preDelCount; + const found = subscript.chunks.length < preDelCount; if (found && (this.flags & Interpreter.SCRIPT_VERIFY_CONST_SCRIPTCODE)) { this.errstr = 'SCRIPT_ERR_SIG_FINDANDDELETE'; return false; @@ -1508,7 +1506,7 @@ Interpreter.prototype.step = function() { pubkey = PublicKey.fromBuffer(bufPubkey, false); fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.sigversion, this.satoshis); } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fSuccess = false; } @@ -1539,13 +1537,13 @@ Interpreter.prototype.step = function() { { // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool) - var i = 1; + let i = 1; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nKeysCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); + let nKeysCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); if (nKeysCount < 0 || nKeysCount > 20) { this.errstr = 'SCRIPT_ERR_PUBKEY_COUNT'; return false; @@ -1556,27 +1554,27 @@ Interpreter.prototype.step = function() { return false; } // int ikey = ++i; - var ikey = ++i; + let ikey = ++i; i += nKeysCount; // ikey2 is the position of last non-signature item in // the stack. Top stack item = 1. With // SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if // operation fails. - var ikey2 = nKeysCount + 2; + let ikey2 = nKeysCount + 2; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; return false; } - var nSigsCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); + let nSigsCount = BN.fromScriptNumBuffer(this.stack[this.stack.length - i], fRequireMinimal).toNumber(); if (nSigsCount < 0 || nSigsCount > nKeysCount) { this.errstr = 'SCRIPT_ERR_SIG_COUNT'; return false; } // int isig = ++i; - var isig = ++i; + let isig = ++i; i += nSigsCount; if (this.stack.length < i) { this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; @@ -1589,10 +1587,10 @@ Interpreter.prototype.step = function() { }); // Drop the signature in pre-segwit scripts but not segwit scripts - for (var k = 0; k < nSigsCount; k++) { + for (let k = 0; k < nSigsCount; k++) { bufSig = this.stack[this.stack.length - isig - k]; if (this.sigversion === Interpreter.SIGVERSION_BASE) { - let preDelCount = subscript.chunks.length; + const preDelCount = subscript.chunks.length; subscript.findAndDelete(new Script().add(bufSig)); const found = subscript.chunks.length < preDelCount; @@ -1620,7 +1618,7 @@ Interpreter.prototype.step = function() { pubkey = PublicKey.fromBuffer(bufPubkey, false); fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript, this.sigversion, this.satoshis); } catch (e) { - //invalid sig or pubkey + // invalid sig or pubkey fOk = false; } diff --git a/packages/bitcore-lib-ltc/lib/transaction/input/publickeyhash.js b/packages/bitcore-lib-ltc/lib/transaction/input/publickeyhash.js index 7a5f3841bda..3ec30b6c33d 100644 --- a/packages/bitcore-lib-ltc/lib/transaction/input/publickeyhash.js +++ b/packages/bitcore-lib-ltc/lib/transaction/input/publickeyhash.js @@ -1,20 +1,17 @@ 'use strict'; var inherits = require('inherits'); - -var $ = require('../../util/preconditions'); -var BufferUtil = require('../../util/buffer'); - var Hash = require('../../crypto/hash'); -var Input = require('./input'); +var Signature = require('../../crypto/signature'); +var BufferWriter = require('../../encoding/bufferwriter'); +var Script = require('../../script'); +var BufferUtil = require('../../util/buffer'); +var $ = require('../../util/preconditions'); var Output = require('../output'); var Sighash = require('../sighash'); var SighashWitness = require('../sighashwitness'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferUtil = require('../../util/buffer'); -var Script = require('../../script'); -var Signature = require('../../crypto/signature'); var TransactionSignature = require('../signature'); +var Input = require('./input'); /** * Represents a special kind of input of PayToPublicKeyHash kind. @@ -27,9 +24,9 @@ inherits(PublicKeyHashInput, Input); PublicKeyHashInput.prototype.getRedeemScript = function(publicKey) { if (!this.redeemScript) { - var redeemScript = Script.buildWitnessV0Out(publicKey); + const redeemScript = Script.buildWitnessV0Out(publicKey); if (Script.buildScriptHashOut(redeemScript).equals(this.output.script)) { - var scriptSig = new Script(); + const scriptSig = new Script(); scriptSig.add(redeemScript.toBuffer()); this.setScript(scriptSig); this.redeemScript = redeemScript; @@ -39,14 +36,14 @@ PublicKeyHashInput.prototype.getRedeemScript = function(publicKey) { }; PublicKeyHashInput.prototype.getScriptCode = function(publicKey) { - var writer = new BufferWriter(); - var script; + const writer = new BufferWriter(); + let script; if (this.output.script.isScriptHashOut()) { script = this.getRedeemScript(publicKey); } else { script = this.output.script; } - var scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); + const scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); writer.writeVarintNum(scriptBuffer.length); writer.write(scriptBuffer); return writer.toBuffer(); @@ -100,10 +97,10 @@ PublicKeyHashInput.prototype.getSignatures = function(transaction, privateKey, i : this.output.script; if (script && BufferUtil.equals(hashData, script.getPublicKeyHash())) { - var signature; + let signature; if (script.isWitnessPublicKeyHashOut()) { - var satoshisBuffer = this.getSatoshisBuffer(); - var scriptCode = this.getScriptCode(privateKey.publicKey); + const satoshisBuffer = this.getSatoshisBuffer(); + const scriptCode = this.getScriptCode(privateKey.publicKey); signature = SighashWitness.sign(transaction, privateKey, sigtype, index, scriptCode, satoshisBuffer, signingMethod); } else { signature = Sighash.sign(transaction, privateKey, sigtype, index, this.output.script, signingMethod); @@ -175,8 +172,8 @@ PublicKeyHashInput.prototype.isValidSignature = function(transaction, signature, // FIXME: Refactor signature so this is not necessary signature.signature.nhashtype = signature.sigtype; if (this.output.script.isWitnessPublicKeyHashOut() || this.output.script.isScriptHashOut()) { - var scriptCode = this.getScriptCode(); - var satoshisBuffer = this.getSatoshisBuffer(); + const scriptCode = this.getScriptCode(); + const satoshisBuffer = this.getSatoshisBuffer(); return SighashWitness.verify( transaction, signature.signature, diff --git a/packages/bitcore-lib/lib/script/interpreter.js b/packages/bitcore-lib/lib/script/interpreter.js index af661589178..83ccf6c0fe6 100644 --- a/packages/bitcore-lib/lib/script/interpreter.js +++ b/packages/bitcore-lib/lib/script/interpreter.js @@ -1,4 +1,4 @@ -/* eslint-disable no-bitwise */ + 'use strict'; const _ = require('lodash'); @@ -11,6 +11,7 @@ const Opcode = require('../opcode'); const PublicKey = require('../publickey'); const SighashSchnorr = require('../transaction/sighashschnorr'); const SighashWitness = require('../transaction/sighashwitness'); +const JSUtil = require('../util/js'); const $ = require('../util/preconditions'); const Script = require('./script'); @@ -505,7 +506,7 @@ Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1 << 7); // be true". // (softfork safe, BIP62 rule 6) // Note: CLEANSTACK should never be used without P2SH or WITNESS. -Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8), +Interpreter.SCRIPT_VERIFY_CLEANSTACK = (1 << 8); // Verify CHECKLOCKTIMEVERIFY // diff --git a/packages/bitcore-lib/lib/transaction/input/publickeyhash.js b/packages/bitcore-lib/lib/transaction/input/publickeyhash.js index e64574fa13e..2eb26521957 100644 --- a/packages/bitcore-lib/lib/transaction/input/publickeyhash.js +++ b/packages/bitcore-lib/lib/transaction/input/publickeyhash.js @@ -1,21 +1,18 @@ 'use strict'; var inherits = require('inherits'); - -var $ = require('../../util/preconditions'); -var BufferUtil = require('../../util/buffer'); - -var PublicKey = require('../../publickey'); var Hash = require('../../crypto/hash'); -var Input = require('./input'); +var Signature = require('../../crypto/signature'); +var BufferWriter = require('../../encoding/bufferwriter'); +var PublicKey = require('../../publickey'); +var Script = require('../../script'); +var BufferUtil = require('../../util/buffer'); +var $ = require('../../util/preconditions'); var Output = require('../output'); var Sighash = require('../sighash'); var SighashWitness = require('../sighashwitness'); -var BufferWriter = require('../../encoding/bufferwriter'); -var BufferUtil = require('../../util/buffer'); -var Script = require('../../script'); -var Signature = require('../../crypto/signature'); var TransactionSignature = require('../signature'); +var Input = require('./input'); /** * Represents a special kind of input of PayToPublicKeyHash kind. @@ -40,14 +37,14 @@ PublicKeyHashInput.prototype.getRedeemScript = function(publicKey) { }; PublicKeyHashInput.prototype.getScriptCode = function(publicKey) { - var writer = new BufferWriter(); - var script; + const writer = new BufferWriter(); + let script; if (this.output.script.isScriptHashOut()) { script = this.getRedeemScript(publicKey); } else { script = this.output.script; } - var scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); + const scriptBuffer = Script.buildPublicKeyHashOut(script.toAddress()).toBuffer(); writer.writeVarintNum(scriptBuffer.length); writer.write(scriptBuffer); return writer.toBuffer(); @@ -177,8 +174,8 @@ PublicKeyHashInput.prototype.isValidSignature = function(transaction, signature, // FIXME: Refactor signature so this is not necessary signature.signature.nhashtype = signature.sigtype; if (this.output.script.isWitnessPublicKeyHashOut() || this.output.script.isScriptHashOut()) { - var scriptCode = this.getScriptCode(signature.publicKey); - var satoshisBuffer = this.getSatoshisBuffer(); + const scriptCode = this.getScriptCode(signature.publicKey); + const satoshisBuffer = this.getSatoshisBuffer(); return SighashWitness.verify( transaction, signature.signature, diff --git a/packages/bitcore-lib/lib/transaction/output.js b/packages/bitcore-lib/lib/transaction/output.js index 8dd841862a1..e603551fb31 100644 --- a/packages/bitcore-lib/lib/transaction/output.js +++ b/packages/bitcore-lib/lib/transaction/output.js @@ -32,12 +32,13 @@ function Output(args) { } if (args.type === 'taproot') { - this.branch = []; + this._branch = []; + this._isValid = true; Object.defineProperty(this, 'isValid', { configurable: false, enumerable: false, get: function() { - this._isValid || this._branch.length === 0; + return this._isValid; }, set: function(isValid) { this._isValid = isValid; @@ -240,7 +241,7 @@ Output.prototype._insertNode = function(node, depth) { * The 'node' variable is overwritten here with the newly combined node. */ while (this.isValid && this._branch.length > depth && this._branch[depth]) { node = this._combineNodes(node, this._branch[depth]); - this._branch = this._branch.slice(0, this._branch.length - 2); + this._branch.pop(); if (depth == 0) { this.isValid = false; /* Can't propagate further up than the root */ } @@ -249,10 +250,10 @@ Output.prototype._insertNode = function(node, depth) { if (this.isValid) { /* Make sure the branch is big enough to place the new node. */ if (this._branch.length <= depth) { - this._branch = this._branch.slice(0, depth + 1); + this._branch.length = depth + 1; } - $.checkState(!this._nodes[depth]); - m_branch[depth] = node; + $.checkState(!this._branch[depth]); + this._branch[depth] = node; } }; @@ -285,11 +286,11 @@ Output.prototype._combineNodes = function(a, b) { * Finalize the construction. Can only be called when IsComplete() is true. * internal_key.IsFullyValid() must be true. * @param {PublicKey} pubKey + * @returns {{ parity: Number, tweakedPubKey: Buffer }} */ Output.prototype.finalize = function(pubKey) { $.checkState(this.isComplete === true, 'finalize can only be called when isComplete is true'); - const ret = pubKey.createTapTweak(this._branch.length === 0 ? null : this._branch[0].hash); - + return pubKey.createTapTweak(this._branch.length === 0 ? null : this._branch[0].hash); }; module.exports = Output; From c3eb3bb835001108e6b6662c4d000a8204a4994a Mon Sep 17 00:00:00 2001 From: Micah Maphet Date: Tue, 18 Aug 2026 14:01:41 -0400 Subject: [PATCH 2/4] standardized nodeCrytpo on lib hash.js's and reverted lazy import in doge --- packages/bitcore-lib-cash/lib/crypto/hash.js | 14 +++++++------- .../bitcore-lib-doge/lib/block/blockheader.js | 6 +++--- packages/bitcore-lib-doge/lib/crypto/hash.js | 16 ++++++++-------- packages/bitcore-lib-ltc/lib/crypto/hash.js | 16 ++++++++-------- packages/bitcore-lib/lib/crypto/hash.js | 14 +++++++------- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/bitcore-lib-cash/lib/crypto/hash.js b/packages/bitcore-lib-cash/lib/crypto/hash.js index 189e8f3fa83..2762b00ab59 100644 --- a/packages/bitcore-lib-cash/lib/crypto/hash.js +++ b/packages/bitcore-lib-cash/lib/crypto/hash.js @@ -1,6 +1,6 @@ 'use strict'; -var crypto = require('crypto'); +var nodeCrypto = require('crypto'); var BufferUtil = require('../util/buffer'); var $ = require('../util/preconditions'); @@ -8,14 +8,14 @@ var Hash = module.exports; Hash.sha1 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha1').update(buf).digest(); + return nodeCrypto.createHash('sha1').update(buf).digest(); }; Hash.sha1.blocksize = 512; Hash.sha256 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha256').update(buf).digest(); + return nodeCrypto.createHash('sha256').update(buf).digest(); }; Hash.sha256.blocksize = 512; @@ -27,7 +27,7 @@ Hash.sha256sha256 = function(buf) { Hash.ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('ripemd160').update(buf).digest(); + return nodeCrypto.createHash('ripemd160').update(buf).digest(); }; Hash.sha256ripemd160 = function(buf) { @@ -37,14 +37,14 @@ Hash.sha256ripemd160 = function(buf) { Hash.sha512 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha512').update(buf).digest(); + return nodeCrypto.createHash('sha512').update(buf).digest(); }; Hash.sha512.blocksize = 1024; Hash.hmac = function(hashf, data, key) { - //http://en.wikipedia.org/wiki/Hash-based_message_authentication_code - //http://tools.ietf.org/html/rfc4868#section-2 + // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code + // http://tools.ietf.org/html/rfc4868#section-2 $.checkArgument(BufferUtil.isBuffer(data)); $.checkArgument(BufferUtil.isBuffer(key)); $.checkArgument(hashf.blocksize); diff --git a/packages/bitcore-lib-doge/lib/block/blockheader.js b/packages/bitcore-lib-doge/lib/block/blockheader.js index 02c905f45ab..185e4cf47e4 100644 --- a/packages/bitcore-lib-doge/lib/block/blockheader.js +++ b/packages/bitcore-lib-doge/lib/block/blockheader.js @@ -5,8 +5,8 @@ var BN = require('../crypto/bn'); var Hash = require('../crypto/hash'); var BufferReader = require('../encoding/bufferreader'); var BufferWriter = require('../encoding/bufferwriter'); -var Script = require('../script'); var BufferUtil = require('../util/buffer'); +// eslint-disable-next-line import/order var $ = require('../util/preconditions'); var GENESIS_BITS = 0x1e0ffff0; // Regtest: 0x207fffff @@ -137,8 +137,6 @@ BlockHeader.fromString = function fromString(str) { * @private */ BlockHeader._fromBufferReader = function _fromBufferReader(br) { - // Required lazily to avoid a circular dependency with ./auxpow - const AuxPow = require('./auxpow'); const info = {}; info.version = br.readInt32LE(); info.prevHash = br.read(32); @@ -348,3 +346,5 @@ BlockHeader.Constants = { }; module.exports = BlockHeader; + +var AuxPow = require('./auxpow'); diff --git a/packages/bitcore-lib-doge/lib/crypto/hash.js b/packages/bitcore-lib-doge/lib/crypto/hash.js index 21674f682c6..ac5d30a6a72 100644 --- a/packages/bitcore-lib-doge/lib/crypto/hash.js +++ b/packages/bitcore-lib-doge/lib/crypto/hash.js @@ -50,26 +50,26 @@ Hash.hmac = function(hashf, data, key) { $.checkArgument(BufferUtil.isBuffer(key)); $.checkArgument(hashf.blocksize); - const blocksize = hashf.blocksize / 8; + var blocksize = hashf.blocksize / 8; if (key.length > blocksize) { key = hashf(key); } else if (key < blocksize) { - const fill = Buffer.alloc(blocksize); + var fill = Buffer.alloc(blocksize); fill.fill(0); key.copy(fill); key = fill; } - const o_key = Buffer.alloc(blocksize); + var o_key = Buffer.alloc(blocksize); o_key.fill(0x5c); - const i_key = Buffer.alloc(blocksize); + var i_key = Buffer.alloc(blocksize); i_key.fill(0x36); - const o_key_pad = Buffer.alloc(blocksize); - const i_key_pad = Buffer.alloc(blocksize); - for (let i = 0; i < blocksize; i++) { + var o_key_pad = Buffer.alloc(blocksize); + var i_key_pad = Buffer.alloc(blocksize); + for (var i = 0; i < blocksize; i++) { o_key_pad[i] = o_key[i] ^ key[i]; i_key_pad[i] = i_key[i] ^ key[i]; } @@ -85,7 +85,7 @@ Hash.sha512hmac = function(data, key) { return Hash.hmac(Hash.sha512, data, key); }; -// Dogecoin Scrypt hashing +// Litecoin Scrypt hashing Hash.scrypt = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); return BufferUtil.reverse(Scrypt(buf, buf, 1024, 1, 1, 32)); diff --git a/packages/bitcore-lib-ltc/lib/crypto/hash.js b/packages/bitcore-lib-ltc/lib/crypto/hash.js index 2dea3335c59..ac5d30a6a72 100644 --- a/packages/bitcore-lib-ltc/lib/crypto/hash.js +++ b/packages/bitcore-lib-ltc/lib/crypto/hash.js @@ -1,22 +1,22 @@ 'use strict'; -var crypto = require('crypto'); +var nodeCrypto = require('crypto'); +var Scrypt = require('scryptsy'); var BufferUtil = require('../util/buffer'); -var Scrypt = require('scryptsy') var $ = require('../util/preconditions'); var Hash = module.exports; Hash.sha1 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha1').update(buf).digest(); + return nodeCrypto.createHash('sha1').update(buf).digest(); }; Hash.sha1.blocksize = 512; Hash.sha256 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha256').update(buf).digest(); + return nodeCrypto.createHash('sha256').update(buf).digest(); }; Hash.sha256.blocksize = 512; @@ -28,7 +28,7 @@ Hash.sha256sha256 = function(buf) { Hash.ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('ripemd160').update(buf).digest(); + return nodeCrypto.createHash('ripemd160').update(buf).digest(); }; Hash.sha256ripemd160 = function(buf) { @@ -38,14 +38,14 @@ Hash.sha256ripemd160 = function(buf) { Hash.sha512 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha512').update(buf).digest(); + return nodeCrypto.createHash('sha512').update(buf).digest(); }; Hash.sha512.blocksize = 1024; Hash.hmac = function(hashf, data, key) { - //http://en.wikipedia.org/wiki/Hash-based_message_authentication_code - //http://tools.ietf.org/html/rfc4868#section-2 + // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code + // http://tools.ietf.org/html/rfc4868#section-2 $.checkArgument(BufferUtil.isBuffer(data)); $.checkArgument(BufferUtil.isBuffer(key)); $.checkArgument(hashf.blocksize); diff --git a/packages/bitcore-lib/lib/crypto/hash.js b/packages/bitcore-lib/lib/crypto/hash.js index 189e8f3fa83..2762b00ab59 100644 --- a/packages/bitcore-lib/lib/crypto/hash.js +++ b/packages/bitcore-lib/lib/crypto/hash.js @@ -1,6 +1,6 @@ 'use strict'; -var crypto = require('crypto'); +var nodeCrypto = require('crypto'); var BufferUtil = require('../util/buffer'); var $ = require('../util/preconditions'); @@ -8,14 +8,14 @@ var Hash = module.exports; Hash.sha1 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha1').update(buf).digest(); + return nodeCrypto.createHash('sha1').update(buf).digest(); }; Hash.sha1.blocksize = 512; Hash.sha256 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha256').update(buf).digest(); + return nodeCrypto.createHash('sha256').update(buf).digest(); }; Hash.sha256.blocksize = 512; @@ -27,7 +27,7 @@ Hash.sha256sha256 = function(buf) { Hash.ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('ripemd160').update(buf).digest(); + return nodeCrypto.createHash('ripemd160').update(buf).digest(); }; Hash.sha256ripemd160 = function(buf) { @@ -37,14 +37,14 @@ Hash.sha256ripemd160 = function(buf) { Hash.sha512 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - return crypto.createHash('sha512').update(buf).digest(); + return nodeCrypto.createHash('sha512').update(buf).digest(); }; Hash.sha512.blocksize = 1024; Hash.hmac = function(hashf, data, key) { - //http://en.wikipedia.org/wiki/Hash-based_message_authentication_code - //http://tools.ietf.org/html/rfc4868#section-2 + // http://en.wikipedia.org/wiki/Hash-based_message_authentication_code + // http://tools.ietf.org/html/rfc4868#section-2 $.checkArgument(BufferUtil.isBuffer(data)); $.checkArgument(BufferUtil.isBuffer(key)); $.checkArgument(hashf.blocksize); From cf7e4405668dad9514fedb6fa689573d72610f3e Mon Sep 17 00:00:00 2001 From: Micah Maphet Date: Tue, 18 Aug 2026 14:59:40 -0400 Subject: [PATCH 3/4] increased ib test timeout --- packages/bitcore-build/wdio.conf.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/bitcore-build/wdio.conf.js b/packages/bitcore-build/wdio.conf.js index 2d9e1a3156a..ffec8a3e9fd 100644 --- a/packages/bitcore-build/wdio.conf.js +++ b/packages/bitcore-build/wdio.conf.js @@ -1,5 +1,5 @@ 'use strict'; - +/* eslint-disable @typescript-eslint/no-require-imports */ const fs = require('fs'); const os = require('os'); const path = require('path'); @@ -162,7 +162,7 @@ module.exports.config = { // See the full list at http://mochajs.org/ mochaOpts: { ui: 'bdd', - timeout: 240000 + timeout: 300000 }, // @@ -322,6 +322,7 @@ module.exports.config = { * @param {Array.} capabilities list of capabilities details * @param {} results object containing test results */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars onComplete: function(exitCode, config, capabilities, results) { try { fs.rmSync(chromeUserDataDirRoot, { recursive: true, force: true }); From c45a1452c2807d0479711d50d33f6d979bcaa33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9B=E3=83=83=E3=83=88=E3=83=94=E3=82=B0?= <93409262+MicahMaphet@users.noreply.github.com> Date: Thu, 10 Sep 2026 10:57:41 -0400 Subject: [PATCH 4/4] Remove empty line before 'use strict'; Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- packages/bitcore-lib/lib/script/interpreter.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bitcore-lib/lib/script/interpreter.js b/packages/bitcore-lib/lib/script/interpreter.js index 83ccf6c0fe6..41f8f7675d0 100644 --- a/packages/bitcore-lib/lib/script/interpreter.js +++ b/packages/bitcore-lib/lib/script/interpreter.js @@ -1,4 +1,3 @@ - 'use strict'; const _ = require('lodash');