itns-sidechain/test/script-test.js

334 lines
7.8 KiB
JavaScript
Raw Normal View History

2016-06-13 01:06:01 -07:00
'use strict';
2016-04-29 17:45:13 -07:00
var assert = require('assert');
2016-12-10 07:43:54 -08:00
var Script = require('../lib/script/script');
var Witness = require('../lib/script/witness');
var Stack = require('../lib/script/stack');
var TX = require('../lib/primitives/tx');
2017-01-06 09:57:55 -08:00
var encoding = require('../lib/utils/encoding');
var opcodes = Script.opcodes;
2016-12-10 07:43:54 -08:00
2016-04-19 01:30:12 -07:00
var scripts = require('./data/script_tests');
2016-12-10 07:43:54 -08:00
function success(res, stack) {
if (!res)
return false;
if (stack.length === 0)
return false;
if (!Script.bool(stack.top(-1)))
return false;
return true;
}
2014-05-04 23:24:32 +04:00
describe('Script', function() {
it('should encode/decode script', function() {
2016-12-10 07:43:54 -08:00
var src, decoded, dst;
src = '20'
2016-05-15 21:47:39 -07:00
+ '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f'
+ '20'
+ '101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f'
+ 'ac';
2014-05-04 23:24:32 +04:00
2016-12-10 07:43:54 -08:00
decoded = Script.fromRaw(src, 'hex');
2016-12-03 18:02:10 -08:00
assert.equal(decoded.code.length, 3);
assert.equal(decoded.code[0].data.toString('hex'),
2014-05-04 23:24:32 +04:00
'000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f');
2016-12-03 18:02:10 -08:00
assert.equal(decoded.code[1].data.toString('hex'),
2014-05-04 23:24:32 +04:00
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f');
2016-12-03 18:02:10 -08:00
assert.equal(decoded.code[2].value, opcodes.OP_CHECKSIG);
2014-05-04 23:24:32 +04:00
2016-12-10 07:43:54 -08:00
dst = decoded.toRaw();
2016-04-18 00:36:03 -07:00
assert.equal(dst.toString('hex'), src);
2014-05-04 23:24:32 +04:00
});
2014-05-06 00:55:24 +04:00
it('should encode/decode numbers', function() {
2016-05-15 21:47:39 -07:00
var script = [0, 0x51, 0x52, 0x60];
2016-12-10 07:43:54 -08:00
var encoded = Script.fromArray(script).raw;
var decoded = Script(encoded).toArray();
2014-05-06 00:55:24 +04:00
assert.deepEqual(decoded, script);
});
2016-05-15 21:47:39 -07:00
it('should recognize a P2SH output', function() {
var hex = 'a91419a7d869032368fd1f1e26e5e73a4ad0e474960e87';
2016-12-10 07:43:54 -08:00
var decoded = Script.fromRaw(hex, 'hex');
2016-05-15 21:47:39 -07:00
assert(decoded.isScripthash());
2016-03-14 20:33:15 -07:00
});
2016-05-15 21:47:39 -07:00
it('should recognize a Null Data output', function() {
var hex = '6a28590c080112220a1b353930632e6f7267282a5f'
+ '5e294f7665726c6179404f7261636c65103b1a010c';
2016-12-10 07:43:54 -08:00
var decoded = Script.fromRaw(hex, 'hex');
2016-05-15 21:47:39 -07:00
assert(decoded.isNulldata());
2016-03-14 20:33:15 -07:00
});
2016-05-15 21:47:39 -07:00
it('should handle if statements correctly', function() {
2016-12-10 07:43:54 -08:00
var input, output, stack, res;
input = new Script([opcodes.OP_1, opcodes.OP_2]);
output = new Script([
2016-03-28 19:42:05 -07:00
opcodes.OP_2,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ELSE,
opcodes.OP_4,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
input.execute(stack);
res = output.execute(stack);
assert(res);
2016-12-10 07:43:54 -08:00
assert.deepEqual(stack.items, [[1], [3], [5]]);
2016-12-10 07:43:54 -08:00
input = new Script([opcodes.OP_1, opcodes.OP_2]);
output = new Script([
2016-03-28 19:42:05 -07:00
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ELSE,
opcodes.OP_4,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
input.execute(stack);
res = output.execute(stack);
assert(res);
assert.deepEqual(stack.items, [[1], [4], [5]]);
2016-12-10 07:43:54 -08:00
input = new Script([opcodes.OP_1, opcodes.OP_2]);
output = new Script([
2016-03-28 19:42:05 -07:00
opcodes.OP_2,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
input.execute(stack);
res = output.execute(stack);
assert(res);
assert.deepEqual(stack.items, [[1], [3], [5]]);
2016-12-10 07:43:54 -08:00
input = new Script([opcodes.OP_1, opcodes.OP_2]);
output = new Script([
2016-03-28 19:42:05 -07:00
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_IF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
input.execute(stack);
res = output.execute(stack);
assert(res);
assert.deepEqual(stack.items, [[1], [5]]);
2016-12-10 07:43:54 -08:00
input = new Script([opcodes.OP_1, opcodes.OP_2]);
output = new Script([
2016-03-28 19:42:05 -07:00
opcodes.OP_9,
opcodes.OP_EQUAL,
opcodes.OP_NOTIF,
opcodes.OP_3,
opcodes.OP_ENDIF,
opcodes.OP_5
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
input.execute(stack);
res = output.execute(stack);
assert(res);
assert.deepEqual(stack.items, [[1], [3], [5]]);
2016-03-14 20:33:15 -07:00
});
2016-04-19 01:30:12 -07:00
2016-05-15 21:47:39 -07:00
it('should handle CScriptNums correctly', function() {
2016-12-10 14:25:02 -08:00
var input, output, stack;
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
input = new Script([
new Buffer('ffffff7f', 'hex'),
2016-05-15 21:47:39 -07:00
opcodes.OP_NEGATE,
opcodes.OP_DUP,
opcodes.OP_ADD
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
output = new Script([
new Buffer('feffffff80', 'hex'),
2016-05-15 21:47:39 -07:00
opcodes.OP_EQUAL
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
2016-12-10 14:25:02 -08:00
assert(input.execute(stack));
assert(success(output.execute(stack), stack));
2016-04-19 04:25:28 -07:00
});
2016-05-15 21:47:39 -07:00
it('should handle CScriptNums correctly', function() {
2016-12-10 14:25:02 -08:00
var input, output, stack;
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
input = new Script([
2016-05-15 21:47:39 -07:00
opcodes.OP_11,
opcodes.OP_10,
opcodes.OP_1,
opcodes.OP_ADD
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
output = new Script([
2016-05-15 21:47:39 -07:00
opcodes.OP_NUMNOTEQUAL,
opcodes.OP_NOT
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
2016-12-10 14:25:02 -08:00
assert(input.execute(stack));
assert(success(output.execute(stack), stack));
2016-04-19 04:25:28 -07:00
});
2016-05-15 21:47:39 -07:00
it('should handle OP_ROLL correctly', function() {
2016-12-10 14:25:02 -08:00
var input, output, stack;
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
input = new Script([
2016-05-15 21:47:39 -07:00
new Buffer([0x16]),
new Buffer([0x15]),
new Buffer([0x14])
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
2016-12-10 14:25:02 -08:00
output = new Script([
2016-05-15 21:47:39 -07:00
opcodes.OP_0,
opcodes.OP_ROLL,
2016-04-19 04:25:28 -07:00
new Buffer([0x14]),
2016-05-15 21:47:39 -07:00
opcodes.OP_EQUALVERIFY,
opcodes.OP_DEPTH,
opcodes.OP_2,
opcodes.OP_EQUAL
2016-04-19 04:25:28 -07:00
]);
2016-12-10 07:43:54 -08:00
stack = new Stack();
2016-12-10 14:25:02 -08:00
assert(input.execute(stack));
assert(success(output.execute(stack), stack));
2016-04-19 04:25:28 -07:00
});
2016-04-19 01:30:12 -07:00
scripts.forEach(function(data) {
2016-07-01 06:19:57 -07:00
var witness = Array.isArray(data[0]) ? data.shift() : [];
2016-04-19 01:30:12 -07:00
var input = data[0] ? data[0].trim() : data[0] || '';
var output = data[1] ? data[1].trim() : data[1] || '';
var flags = data[2] ? data[2].trim().split(/,\s*/) : [];
var expected = data[3] || '';
var comments = Array.isArray(data[4]) ? data[4].join('. ') : data[4] || '';
2016-06-09 03:38:31 -07:00
var amount = 0;
var flag = 0;
2016-12-10 17:03:43 -08:00
var i, name;
2016-04-19 01:30:12 -07:00
if (data.length === 1)
return;
if (!comments)
comments = output.slice(0, 60);
comments += ' (' + expected + ')';
2016-07-01 06:19:57 -07:00
if (witness.length !== 0)
2016-06-09 03:38:31 -07:00
amount = witness.pop() * 100000000;
2016-12-10 07:43:54 -08:00
witness = Witness.fromString(witness);
input = Script.fromString(input);
output = Script.fromString(output);
2016-04-19 01:30:12 -07:00
for (i = 0; i < flags.length; i++) {
name = 'VERIFY_' + flags[i];
2017-01-06 09:57:55 -08:00
assert(Script.flags[name] != null, 'Unknown flag.');
flag |= Script.flags[name];
2016-04-19 01:30:12 -07:00
}
2016-04-19 01:30:12 -07:00
flags = flag;
2016-12-10 14:25:02 -08:00
[false, true].forEach(function(noCache) {
var suffix = noCache ? ' without cache' : ' with cache';
2016-05-15 21:47:39 -07:00
it('should handle script test' + suffix + ': ' + comments, function() {
var prev, tx, err, res;
// Funding transaction.
2016-12-10 07:43:54 -08:00
prev = new TX({
2016-04-19 06:45:10 -07:00
version: 1,
2016-05-19 00:09:06 -07:00
flag: 1,
2016-04-19 06:45:10 -07:00
inputs: [{
prevout: {
2017-01-06 09:57:55 -08:00
hash: encoding.NULL_HASH,
2016-04-19 06:45:10 -07:00
index: 0xffffffff
},
script: [opcodes.OP_0, opcodes.OP_0],
witness: [],
2016-04-19 06:45:10 -07:00
sequence: 0xffffffff
}],
outputs: [{
script: output,
2016-06-09 03:38:31 -07:00
value: amount
2016-04-19 06:45:10 -07:00
}],
locktime: 0
});
// Spending transaction.
2016-12-10 07:43:54 -08:00
tx = new TX({
2016-04-19 06:45:10 -07:00
version: 1,
2016-05-19 00:09:06 -07:00
flag: 1,
2016-04-19 06:45:10 -07:00
inputs: [{
prevout: {
hash: prev.hash('hex'),
2016-04-19 06:45:10 -07:00
index: 0
},
script: input,
witness: witness,
sequence: 0xffffffff
}],
outputs: [{
script: [],
2016-06-09 03:38:31 -07:00
value: amount
2016-04-19 06:45:10 -07:00
}],
locktime: 0
});
2016-12-10 14:25:02 -08:00
if (noCache) {
2016-12-16 22:02:05 -08:00
prev.refresh();
tx.refresh();
2016-04-19 06:45:10 -07:00
}
2016-04-19 22:44:54 -07:00
try {
res = Script.verify(input, witness, output, tx, 0, amount, flags);
2016-04-19 22:44:54 -07:00
} catch (e) {
err = e;
}
2016-04-19 22:44:54 -07:00
if (expected !== 'OK') {
assert(!res);
assert(err);
assert.equal(err.code, expected);
return;
}
2016-10-02 01:01:16 -07:00
assert.ifError(err);
2016-04-19 22:44:54 -07:00
assert(res);
2016-04-19 01:30:12 -07:00
});
});
});
2014-05-04 23:24:32 +04:00
});