add Script#prepend()

This commit is contained in:
Manuel Araoz 2014-11-28 12:57:19 -03:00
parent ebf97aa4bb
commit 4a6755d0d1
4 changed files with 81 additions and 39 deletions

View File

@ -227,7 +227,7 @@ Address._transformString = function(data, network, type){
* *
* Instantiate an address from a PublicKey instance * Instantiate an address from a PublicKey instance
* *
* @param {String} data - An instance of PublicKey * @param {PublicKey} data - An instance of PublicKey
* @param {String} network - The network: 'livenet' or 'testnet' * @param {String} network - The network: 'livenet' or 'testnet'
* @returns {Address} A new valid and frozen instance of an Address * @returns {Address} A new valid and frozen instance of an Address
*/ */

View File

@ -208,35 +208,66 @@ Script.prototype.isScriptHashIn = function() {
}); });
}; };
/**
* Adds a script element at the start of the script.
* @param {*} obj a string, number, Opcode, Bufer, or object to add
* @returns {Script} this script instance
*/
Script.prototype.prepend = function(obj) {
this._addByType(obj, true);
return this;
};
/**
* Adds a script element to the end of the script.
*
* @param {*} obj a string, number, Opcode, Bufer, or object to add
* @returns {Script} this script instance
*
*/
Script.prototype.add = function(obj) { Script.prototype.add = function(obj) {
this._addByType(obj, false);
return this;
};
Script.prototype._addByType = function(obj, prepend) {
if (typeof obj === 'string') { if (typeof obj === 'string') {
this._addOpcode(obj); this._addOpcode(obj, prepend);
} else if (typeof obj === 'number') { } else if (typeof obj === 'number') {
this._addOpcode(obj); this._addOpcode(obj, prepend);
} else if (obj.constructor && obj.constructor.name && obj.constructor.name === 'Opcode') { } else if (obj.constructor && obj.constructor.name && obj.constructor.name === 'Opcode') {
this._addOpcode(obj); this._addOpcode(obj, prepend);
} else if (Buffer.isBuffer(obj)) { } else if (Buffer.isBuffer(obj)) {
this._addBuffer(obj); this._addBuffer(obj, prepend);
} else if (typeof obj === 'object') { } else if (typeof obj === 'object') {
this.chunks.push(obj); this._insertAtPosition(obj, prepend);
} else { } else {
throw new Error('Invalid script chunk'); throw new Error('Invalid script chunk');
} }
return this;
}; };
Script.prototype._addOpcode = function(opcode) { Script.prototype._insertAtPosition = function(op, prepend) {
if (typeof opcode === 'number') { if (prepend) {
this.chunks.push(opcode); this.chunks.unshift(op);
} else if (opcode.constructor && opcode.constructor.name && opcode.constructor.name === 'Opcode') {
this.chunks.push(opcode.toNumber());
} else { } else {
this.chunks.push(Opcode(opcode).toNumber()); this.chunks.push(op);
} }
};
Script.prototype._addOpcode = function(opcode, prepend) {
var op;
if (typeof opcode === 'number') {
op = opcode;
} else if (opcode.constructor && opcode.constructor.name && opcode.constructor.name === 'Opcode') {
op = opcode.toNumber();
} else {
op = Opcode(opcode).toNumber();
}
this._insertAtPosition(op, prepend);
return this; return this;
}; };
Script.prototype._addBuffer = function(buf) { Script.prototype._addBuffer = function(buf, prepend) {
var opcodenum; var opcodenum;
var len = buf.length; var len = buf.length;
if (buf.length > 0 && buf.length < Opcode.map.OP_PUSHDATA1) { if (buf.length > 0 && buf.length < Opcode.map.OP_PUSHDATA1) {
@ -250,11 +281,11 @@ Script.prototype._addBuffer = function(buf) {
} else { } else {
throw new Error('You can\'t push that much data'); throw new Error('You can\'t push that much data');
} }
this.chunks.push({ this._insertAtPosition({
buf: buf, buf: buf,
len: len, len: len,
opcodenum: opcodenum opcodenum: opcodenum
}); }, prepend);
return this; return this;
}; };

1
test/mocha.opts Normal file
View File

@ -0,0 +1 @@
--recursive

View File

@ -251,37 +251,47 @@ describe('Script', function() {
}); });
describe('#add', function() { describe('#add and #prepend', function() {
it('should add these ops', function() { it('should add these ops', function() {
Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
Script().add('OP_1').add('OP_2').toString().should.equal('OP_1 OP_2');
Script().add(new Opcode('OP_CHECKMULTISIG')).toString().should.equal('OP_CHECKMULTISIG');
Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG');
}); });
}); it('should prepend these ops', function() {
Script().prepend('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
Script().prepend('OP_1').prepend('OP_2').toString().should.equal('OP_2 OP_1');
});
it('should add these push data', function() { it('should add and prepend correctly', function() {
var buf = new Buffer(1); Script().add('OP_1').prepend('OP_2').add('OP_3').prepend('OP_4').toString()
buf.fill(0); .should.equal('OP_4 OP_2 OP_1 OP_3');
Script().add(buf).toString().should.equal('1 0x00'); });
buf = new Buffer(255);
buf.fill(0);
Script().add(buf).toString().should.equal('OP_PUSHDATA1 255 0x' + buf.toString('hex'));
buf = new Buffer(256);
buf.fill(0);
Script().add(buf).toString().should.equal('OP_PUSHDATA2 256 0x' + buf.toString('hex'));
buf = new Buffer(Math.pow(2, 16));
buf.fill(0);
Script().add(buf).toString().should.equal('OP_PUSHDATA4 ' + Math.pow(2, 16) + ' 0x' + buf.toString('hex'));
});
it('should add both pushdata and non-pushdata chunks', function() { it('should add these push data', function() {
Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); var buf = new Buffer(1);
Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); buf.fill(0);
var buf = new Buffer(1); Script().add(buf).toString().should.equal('1 0x00');
buf.fill(0); buf = new Buffer(255);
Script().add(buf).toString().should.equal('1 0x00'); buf.fill(0);
}); Script().add(buf).toString().should.equal('OP_PUSHDATA1 255 0x' + buf.toString('hex'));
buf = new Buffer(256);
buf.fill(0);
Script().add(buf).toString().should.equal('OP_PUSHDATA2 256 0x' + buf.toString('hex'));
buf = new Buffer(Math.pow(2, 16));
buf.fill(0);
Script().add(buf).toString().should.equal('OP_PUSHDATA4 ' + Math.pow(2, 16) + ' 0x' + buf.toString('hex'));
});
it('should add both pushdata and non-pushdata chunks', function() {
Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG');
Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG');
var buf = new Buffer(1);
buf.fill(0);
Script().add(buf).toString().should.equal('1 0x00');
});
});
}); });