Lint script/interpreter
This commit is contained in:
parent
85169a3874
commit
490279acb0
|
@ -6,8 +6,6 @@ var Script = require('./script');
|
|||
var Opcode = require('../opcode');
|
||||
var BN = require('../crypto/bn');
|
||||
var Hash = require('../crypto/hash');
|
||||
var BufferReader = require('../encoding/bufferreader');
|
||||
var BufferWriter = require('../encoding/bufferwriter');
|
||||
var Signature = require('../crypto/signature');
|
||||
var PublicKey = require('../publickey');
|
||||
|
||||
|
@ -323,7 +321,9 @@ Interpreter.prototype.step = function() {
|
|||
|
||||
//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;
|
||||
|
||||
// Read instruction
|
||||
var chunk = this.script.chunks[this.pc];
|
||||
|
@ -399,8 +399,8 @@ Interpreter.prototype.step = function() {
|
|||
{
|
||||
// ( -- value)
|
||||
// ScriptNum bn((int)opcode - (int)(Opcode.OP_1 - 1));
|
||||
var n = opcodenum - (Opcode.OP_1 - 1);
|
||||
var buf = BN(n).toScriptNumBuffer();
|
||||
n = opcodenum - (Opcode.OP_1 - 1);
|
||||
buf = BN(n).toScriptNumBuffer();
|
||||
this.stack.push(buf);
|
||||
// The result of these opcodes should always be the minimal way to push the data
|
||||
// they push, so no need for a CheckMinimalPush here.
|
||||
|
@ -437,16 +437,17 @@ Interpreter.prototype.step = function() {
|
|||
{
|
||||
// <expression> if [statements] [else [statements]] endif
|
||||
// bool fValue = false;
|
||||
var fValue = false;
|
||||
fValue = false;
|
||||
if (fExec) {
|
||||
if (this.stack.length < 1) {
|
||||
this.errstr = 'SCRIPT_ERR_UNBALANCED_CONDITIONAL';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack.pop();
|
||||
buf = this.stack.pop();
|
||||
fValue = Interpreter.castToBool(buf);
|
||||
if (opcodenum === Opcode.OP_NOTIF)
|
||||
if (opcodenum === Opcode.OP_NOTIF) {
|
||||
fValue = !fValue;
|
||||
}
|
||||
}
|
||||
this.vfExec.push(fValue);
|
||||
}
|
||||
|
@ -480,11 +481,11 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - 1];
|
||||
var fValue = Interpreter.castToBool(buf);
|
||||
if (fValue)
|
||||
buf = this.stack[this.stack.length - 1];
|
||||
fValue = Interpreter.castToBool(buf);
|
||||
if (fValue) {
|
||||
this.stack.pop();
|
||||
else {
|
||||
} else {
|
||||
this.errstr = 'SCRIPT_ERR_VERIFY';
|
||||
return false;
|
||||
}
|
||||
|
@ -541,8 +542,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf1 = this.stack[this.stack.length - 2];
|
||||
var buf2 = this.stack[this.stack.length - 1];
|
||||
buf1 = this.stack[this.stack.length - 2];
|
||||
buf2 = this.stack[this.stack.length - 1];
|
||||
this.stack.push(buf1);
|
||||
this.stack.push(buf2);
|
||||
}
|
||||
|
@ -555,8 +556,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf1 = this.stack[this.stack.length - 3];
|
||||
var buf2 = this.stack[this.stack.length - 2];
|
||||
buf1 = this.stack[this.stack.length - 3];
|
||||
buf2 = this.stack[this.stack.length - 2];
|
||||
var buf3 = this.stack[this.stack.length - 1];
|
||||
this.stack.push(buf1);
|
||||
this.stack.push(buf2);
|
||||
|
@ -571,8 +572,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf1 = this.stack[this.stack.length - 4];
|
||||
var buf2 = this.stack[this.stack.length - 3];
|
||||
buf1 = this.stack[this.stack.length - 4];
|
||||
buf2 = this.stack[this.stack.length - 3];
|
||||
this.stack.push(buf1);
|
||||
this.stack.push(buf2);
|
||||
}
|
||||
|
@ -585,7 +586,7 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var spliced = this.stack.splice(this.stack.length - 6, 2);
|
||||
spliced = this.stack.splice(this.stack.length - 6, 2);
|
||||
this.stack.push(spliced[0]);
|
||||
this.stack.push(spliced[1]);
|
||||
}
|
||||
|
@ -598,7 +599,7 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var spliced = this.stack.splice(this.stack.length - 4, 2);
|
||||
spliced = this.stack.splice(this.stack.length - 4, 2);
|
||||
this.stack.push(spliced[0]);
|
||||
this.stack.push(spliced[1]);
|
||||
}
|
||||
|
@ -611,17 +612,18 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - 1];
|
||||
var fValue = Interpreter.castToBool(buf);
|
||||
if (fValue)
|
||||
buf = this.stack[this.stack.length - 1];
|
||||
fValue = Interpreter.castToBool(buf);
|
||||
if (fValue) {
|
||||
this.stack.push(buf);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Opcode.OP_DEPTH:
|
||||
{
|
||||
// -- stacksize
|
||||
var buf = BN(this.stack.length).toScriptNumBuffer();
|
||||
buf = BN(this.stack.length).toScriptNumBuffer();
|
||||
this.stack.push(buf);
|
||||
}
|
||||
break;
|
||||
|
@ -679,17 +681,18 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - 1];
|
||||
var bn = BN().fromScriptNumBuffer(buf, fRequireMinimal);
|
||||
var n = bn.toNumber();
|
||||
buf = this.stack[this.stack.length - 1];
|
||||
bn = BN().fromScriptNumBuffer(buf, fRequireMinimal);
|
||||
n = bn.toNumber();
|
||||
this.stack.pop();
|
||||
if (n < 0 || n >= this.stack.length) {
|
||||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - n - 1];
|
||||
if (opcodenum === Opcode.OP_ROLL)
|
||||
buf = this.stack[this.stack.length - n - 1];
|
||||
if (opcodenum === Opcode.OP_ROLL) {
|
||||
this.stack.splice(this.stack.length - n - 1, 1);
|
||||
}
|
||||
this.stack.push(buf);
|
||||
}
|
||||
break;
|
||||
|
@ -703,8 +706,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var x1 = this.stack[this.stack.length - 3];
|
||||
var x2 = this.stack[this.stack.length - 2];
|
||||
x1 = this.stack[this.stack.length - 3];
|
||||
x2 = this.stack[this.stack.length - 2];
|
||||
var x3 = this.stack[this.stack.length - 1];
|
||||
this.stack[this.stack.length - 3] = x2;
|
||||
this.stack[this.stack.length - 2] = x3;
|
||||
|
@ -719,8 +722,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var x1 = this.stack[this.stack.length - 2];
|
||||
var x2 = this.stack[this.stack.length - 1];
|
||||
x1 = this.stack[this.stack.length - 2];
|
||||
x2 = this.stack[this.stack.length - 1];
|
||||
this.stack[this.stack.length - 2] = x2;
|
||||
this.stack[this.stack.length - 1] = x1;
|
||||
}
|
||||
|
@ -745,7 +748,7 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var bn = BN(this.stack[this.stack.length - 1].length);
|
||||
bn = BN(this.stack[this.stack.length - 1].length);
|
||||
this.stack.push(bn.toScriptNumBuffer());
|
||||
}
|
||||
break;
|
||||
|
@ -763,8 +766,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf1 = this.stack[this.stack.length - 2];
|
||||
var buf2 = this.stack[this.stack.length - 1];
|
||||
buf1 = this.stack[this.stack.length - 2];
|
||||
buf2 = this.stack[this.stack.length - 1];
|
||||
var fEqual = buf1.toString('hex') === buf2.toString('hex');
|
||||
// Opcode.OP_NOTEQUAL is disabled because it would be too easy to say
|
||||
// something like n != 1 and have some wiseguy pass in 1 with extra
|
||||
|
@ -775,9 +778,9 @@ Interpreter.prototype.step = function() {
|
|||
this.stack.pop();
|
||||
this.stack.push(fEqual ? Interpreter.true : Interpreter.false);
|
||||
if (opcodenum === Opcode.OP_EQUALVERIFY) {
|
||||
if (fEqual)
|
||||
if (fEqual) {
|
||||
this.stack.pop();
|
||||
else {
|
||||
} else {
|
||||
this.errstr = 'SCRIPT_ERR_EQUALVERIFY';
|
||||
return false;
|
||||
}
|
||||
|
@ -801,8 +804,8 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - 1];
|
||||
var bn = BN().fromScriptNumBuffer(buf, fRequireMinimal);
|
||||
buf = this.stack[this.stack.length - 1];
|
||||
bn = BN().fromScriptNumBuffer(buf, fRequireMinimal);
|
||||
switch (opcodenum) {
|
||||
case Opcode.OP_1ADD:
|
||||
bn = bn.add(1);
|
||||
|
@ -814,7 +817,9 @@ Interpreter.prototype.step = function() {
|
|||
bn = bn.neg();
|
||||
break;
|
||||
case Opcode.OP_ABS:
|
||||
if (bn.cmp(0) < 0) bn = bn.neg();
|
||||
if (bn.cmp(0) < 0) {
|
||||
bn = bn.neg();
|
||||
}
|
||||
break;
|
||||
case Opcode.OP_NOT:
|
||||
bn = BN((bn.cmp(0) === 0) + 0);
|
||||
|
@ -848,9 +853,9 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var bn1 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal);
|
||||
var bn2 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal);
|
||||
var bn = BN(0);
|
||||
bn1 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal);
|
||||
bn2 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal);
|
||||
bn = BN(0);
|
||||
|
||||
switch (opcodenum) {
|
||||
case Opcode.OP_ADD:
|
||||
|
@ -911,9 +916,9 @@ Interpreter.prototype.step = function() {
|
|||
|
||||
if (opcodenum === Opcode.OP_NUMEQUALVERIFY) {
|
||||
// if (CastToBool(stacktop(-1)))
|
||||
if (Interpreter.castToBool(this.stack[this.stack.length - 1]))
|
||||
if (Interpreter.castToBool(this.stack[this.stack.length - 1])) {
|
||||
this.stack.pop();
|
||||
else {
|
||||
} else {
|
||||
this.errstr = 'SCRIPT_ERR_NUMEQUALVERIFY';
|
||||
return false;
|
||||
}
|
||||
|
@ -928,11 +933,11 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var bn1 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 3], fRequireMinimal);
|
||||
var bn2 = BN().fromScriptNumBuffer(this.stack[this.stack.length - 2], fRequireMinimal);
|
||||
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);
|
||||
var fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0);
|
||||
fValue = (bn2.cmp(bn1) <= 0) && (bn1.cmp(bn3) < 0);
|
||||
this.stack.pop();
|
||||
this.stack.pop();
|
||||
this.stack.pop();
|
||||
|
@ -955,19 +960,21 @@ Interpreter.prototype.step = function() {
|
|||
this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION';
|
||||
return false;
|
||||
}
|
||||
var buf = this.stack[this.stack.length - 1];
|
||||
//valtype vchHash((opcode == Opcode.OP_RIPEMD160 || opcode == Opcode.OP_SHA1 || opcode == Opcode.OP_HASH160) ? 20 : 32);
|
||||
buf = this.stack[this.stack.length - 1];
|
||||
//valtype vchHash((opcode == Opcode.OP_RIPEMD160 ||
|
||||
// opcode == Opcode.OP_SHA1 || opcode == Opcode.OP_HASH160) ? 20 : 32);
|
||||
var bufHash;
|
||||
if (opcodenum === Opcode.OP_RIPEMD160)
|
||||
if (opcodenum === Opcode.OP_RIPEMD160) {
|
||||
bufHash = Hash.ripemd160(buf);
|
||||
else if (opcodenum === Opcode.OP_SHA1)
|
||||
} else if (opcodenum === Opcode.OP_SHA1) {
|
||||
bufHash = Hash.sha1(buf);
|
||||
else if (opcodenum === Opcode.OP_SHA256)
|
||||
} else if (opcodenum === Opcode.OP_SHA256) {
|
||||
bufHash = Hash.sha256(buf);
|
||||
else if (opcodenum === Opcode.OP_HASH160)
|
||||
} else if (opcodenum === Opcode.OP_HASH160) {
|
||||
bufHash = Hash.sha256ripemd160(buf);
|
||||
else if (opcodenum === Opcode.OP_HASH256)
|
||||
} else if (opcodenum === Opcode.OP_HASH256) {
|
||||
bufHash = Hash.sha256sha256(buf);
|
||||
}
|
||||
this.stack.pop();
|
||||
this.stack.push(bufHash);
|
||||
}
|
||||
|
@ -989,27 +996,26 @@ Interpreter.prototype.step = function() {
|
|||
return false;
|
||||
}
|
||||
|
||||
var bufSig = this.stack[this.stack.length - 2];
|
||||
var bufPubkey = this.stack[this.stack.length - 1];
|
||||
bufSig = this.stack[this.stack.length - 2];
|
||||
bufPubkey = this.stack[this.stack.length - 1];
|
||||
|
||||
// Subset of script starting at the most recent codeseparator
|
||||
// CScript scriptCode(pbegincodehash, pend);
|
||||
var subscript = Script().set({
|
||||
subscript = new Script().set({
|
||||
chunks: this.script.chunks.slice(this.pbegincodehash)
|
||||
});
|
||||
|
||||
// Drop the signature, since there's no way for a signature to sign itself
|
||||
var tmpScript = Script().add(bufSig);
|
||||
var tmpScript = new Script().add(bufSig);
|
||||
subscript.findAndDelete(tmpScript);
|
||||
|
||||
if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var fSuccess;
|
||||
try {
|
||||
var sig = Signature.fromTxFormat(bufSig);
|
||||
var pubkey = PublicKey.fromBuffer(bufPubkey, false);
|
||||
sig = Signature.fromTxFormat(bufSig);
|
||||
pubkey = PublicKey.fromBuffer(bufPubkey, false);
|
||||
fSuccess = this.tx.verifySignature(sig, pubkey, this.nin, subscript);
|
||||
} catch (e) {
|
||||
//invalid sig or pubkey
|
||||
|
@ -1074,22 +1080,22 @@ Interpreter.prototype.step = function() {
|
|||
}
|
||||
|
||||
// Subset of script starting at the most recent codeseparator
|
||||
var subscript = Script().set({
|
||||
subscript = new Script().set({
|
||||
chunks: this.script.chunks.slice(this.pbegincodehash)
|
||||
});
|
||||
|
||||
// Drop the signatures, since there's no way for a signature to sign itself
|
||||
for (var k = 0; k < nSigsCount; k++) {
|
||||
var bufSig = this.stack[this.stack.length - isig - k];
|
||||
subscript.findAndDelete(Script().add(bufSig));
|
||||
bufSig = this.stack[this.stack.length - isig - k];
|
||||
subscript.findAndDelete(new Script().add(bufSig));
|
||||
}
|
||||
|
||||
var fSuccess = true;
|
||||
fSuccess = true;
|
||||
while (fSuccess && nSigsCount > 0) {
|
||||
// valtype& vchSig = stacktop(-isig);
|
||||
var bufSig = this.stack[this.stack.length - isig];
|
||||
bufSig = this.stack[this.stack.length - isig];
|
||||
// valtype& vchPubKey = stacktop(-ikey);
|
||||
var bufPubkey = this.stack[this.stack.length - ikey];
|
||||
bufPubkey = this.stack[this.stack.length - ikey];
|
||||
|
||||
if (!this.checkSignatureEncoding(bufSig) || !this.checkPubkeyEncoding(bufPubkey)) {
|
||||
return false;
|
||||
|
@ -1097,8 +1103,8 @@ Interpreter.prototype.step = function() {
|
|||
|
||||
var fOk;
|
||||
try {
|
||||
var sig = Signature.fromTxFormat(bufSig);
|
||||
var pubkey = PublicKey.fromBuffer(bufPubkey, false);
|
||||
sig = Signature.fromTxFormat(bufSig);
|
||||
pubkey = PublicKey.fromBuffer(bufPubkey, false);
|
||||
fOk = this.tx.verifySignature(sig, pubkey, this.nin, subscript);
|
||||
} catch (e) {
|
||||
//invalid sig or pubkey
|
||||
|
@ -1143,9 +1149,9 @@ Interpreter.prototype.step = function() {
|
|||
this.stack.push(fSuccess ? Interpreter.true : Interpreter.false);
|
||||
|
||||
if (opcodenum === Opcode.OP_CHECKMULTISIGVERIFY) {
|
||||
if (fSuccess)
|
||||
if (fSuccess) {
|
||||
this.stack.pop();
|
||||
else {
|
||||
} else {
|
||||
this.errstr = 'SCRIPT_ERR_CHECKMULTISIGVERIFY';
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue