You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
4.3 KiB
174 lines
4.3 KiB
var BufferReader = require('./bufferreader');
|
|
var BufferWriter = require('./bufferwriter');
|
|
var Opcode = require('./opcode');
|
|
|
|
var Script = function Script(buf) {
|
|
if (!(this instanceof Script))
|
|
return new Script(buf);
|
|
|
|
this.chunks = [];
|
|
|
|
if (Buffer.isBuffer(buf)) {
|
|
this.fromBuffer(buf);
|
|
}
|
|
else if (typeof buf === 'string') {
|
|
var str = buf;
|
|
this.fromString(str);
|
|
}
|
|
else if (typeof buf !== 'undefined') {
|
|
var obj = buf;
|
|
this.set(obj);
|
|
}
|
|
};
|
|
|
|
Script.prototype.set = function(obj) {
|
|
this.chunks = obj.chunks || this.chunks;
|
|
return this;
|
|
};
|
|
|
|
Script.prototype.fromJSON = function(json) {
|
|
return this.fromString(json);
|
|
};
|
|
|
|
Script.prototype.toJSON = function() {
|
|
return this.toString();
|
|
};
|
|
|
|
Script.prototype.fromBuffer = function(buf) {
|
|
this.chunks = [];
|
|
|
|
var br = new BufferReader(buf);
|
|
while (!br.eof()) {
|
|
var opcodenum = br.readUInt8();
|
|
|
|
var len, buf;
|
|
if (opcodenum > 0 && opcodenum < Opcode.map.OP_PUSHDATA1) {
|
|
len = opcodenum;
|
|
this.chunks.push({
|
|
buf: br.read(len),
|
|
len: len,
|
|
opcodenum: opcodenum
|
|
});
|
|
} else if (opcodenum === Opcode.map.OP_PUSHDATA1) {
|
|
len = br.readUInt8();
|
|
var buf = br.read(len);
|
|
this.chunks.push({
|
|
buf: buf,
|
|
len: len,
|
|
opcodenum: opcodenum
|
|
});
|
|
} else if (opcodenum === Opcode.map.OP_PUSHDATA2) {
|
|
len = br.readUInt16LE();
|
|
buf = br.read(len);
|
|
this.chunks.push({
|
|
buf: buf,
|
|
len: len,
|
|
opcodenum: opcodenum
|
|
});
|
|
} else if (opcodenum === Opcode.map.OP_PUSHDATA4) {
|
|
len = br.readUInt32LE();
|
|
buf = br.read(len);
|
|
this.chunks.push({
|
|
buf: buf,
|
|
len: len,
|
|
opcodenum: opcodenum
|
|
});
|
|
} else {
|
|
this.chunks.push(opcodenum);
|
|
}
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
Script.prototype.toBuffer = function() {
|
|
var bw = new BufferWriter();
|
|
|
|
for (var i = 0; i < this.chunks.length; i++) {
|
|
var chunk = this.chunks[i];
|
|
if (typeof chunk === 'number') {
|
|
var opcodenum = chunk;
|
|
bw.writeUInt8(opcodenum);
|
|
} else {
|
|
var opcodenum = chunk.opcodenum;
|
|
bw.writeUInt8(chunk.opcodenum);
|
|
if (opcodenum < Opcode.map.OP_PUSHDATA1) {
|
|
bw.write(chunk.buf);
|
|
}
|
|
else if (opcodenum === Opcode.map.OP_PUSHDATA1) {
|
|
bw.writeUInt8(chunk.len);
|
|
bw.write(chunk.buf);
|
|
}
|
|
else if (opcodenum === Opcode.map.OP_PUSHDATA2) {
|
|
bw.writeUInt16LE(chunk.len);
|
|
bw.write(chunk.buf);
|
|
}
|
|
else if (opcodenum === Opcode.map.OP_PUSHDATA4) {
|
|
bw.writeUInt32LE(chunk.len);
|
|
bw.write(chunk.buf);
|
|
}
|
|
}
|
|
}
|
|
|
|
return bw.concat();
|
|
};
|
|
|
|
Script.prototype.fromString = function(str) {
|
|
this.chunks = [];
|
|
|
|
var tokens = str.split(' ');
|
|
var i = 0;
|
|
while (i < tokens.length) {
|
|
var token = tokens[i];
|
|
var opcode = Opcode(token);
|
|
var opcodenum = opcode.toNumber();
|
|
|
|
if (typeof opcodenum === 'undefined') {
|
|
opcodenum = parseInt(token);
|
|
if (opcodenum > 0 && opcodenum < Opcode.map.OP_PUSHDATA1) {
|
|
this.chunks.push({
|
|
buf: new Buffer(tokens[i + 1].slice(2), 'hex'),
|
|
len: opcodenum,
|
|
opcodenum: opcodenum
|
|
});
|
|
i = i + 2;
|
|
}
|
|
else {
|
|
throw new Error('Invalid script');
|
|
}
|
|
} else if (opcodenum === Opcode.map.OP_PUSHDATA1 || opcodenum === Opcode.map.OP_PUSHDATA2 || opcodenum === Opcode.map.OP_PUSHDATA4) {
|
|
this.chunks.push({
|
|
buf: new Buffer(tokens[i + 2].slice(2), 'hex'),
|
|
len: parseInt(tokens[i + 1]),
|
|
opcodenum: opcodenum
|
|
});
|
|
i = i + 3;
|
|
} else {
|
|
this.chunks.push(opcodenum);
|
|
i = i + 1;
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
|
|
Script.prototype.toString = function() {
|
|
var str = "";
|
|
|
|
for (var i = 0; i < this.chunks.length; i++) {
|
|
var chunk = this.chunks[i];
|
|
if (typeof chunk === 'number') {
|
|
var opcodenum = chunk;
|
|
str = str + Opcode(opcodenum).toString() + " ";
|
|
} else {
|
|
var opcodenum = chunk.opcodenum;
|
|
if (opcodenum === Opcode.map.OP_PUSHDATA1 || opcodenum === Opcode.map.OP_PUSHDATA2 || opcodenum === Opcode.map.OP_PUSHDATA4)
|
|
str = str + Opcode(opcodenum).toString() + " " ;
|
|
str = str + chunk.len + " " ;
|
|
str = str + "0x" + chunk.buf.toString('hex') + " ";
|
|
}
|
|
}
|
|
|
|
return str.substr(0, str.length - 1);
|
|
};
|
|
|
|
module.exports = Script;
|
|
|