From 7d94d1b0684145d12f57b946555d7780b3ab2443 Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Wed, 28 May 2014 19:36:33 +1000 Subject: [PATCH] Script: add fromChunks and without --- src/script.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ test/script.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/src/script.js b/src/script.js index 188b0c3..8ee030b 100644 --- a/src/script.js +++ b/src/script.js @@ -1,4 +1,5 @@ var assert = require('assert') +var bufferutils = require('./bufferutils') var crypto = require('./crypto') var opcodes = require('./opcodes') @@ -367,4 +368,50 @@ Script.prototype.clone = function() { return new Script(this.buffer) } +Script.fromChunks = function(chunks) { + assert(Array.isArray(chunks), 'Expected Array, got: ' + chunks) + + var bufferSize = chunks.reduce(function(accum, chunk) { + var chunkSize = 1 + + // FIXME: transitionary + if (Array.isArray(chunk) || Buffer.isBuffer(chunk)) { + chunkSize = bufferutils.pushDataSize(chunk.length) + chunk.length + } + + return accum + chunkSize + }, 0.0) + + var buffer = new Buffer(bufferSize) + var offset = 0 + + chunks.forEach(function(chunk) { + // FIXME: transitionary + if (Array.isArray(chunk) || Buffer.isBuffer(chunk)) { + offset += bufferutils.writePushDataInt(buffer, chunk.length, offset) + + // FIXME: transitionary +// chunk.copy(buffer, offset) + for (var i = 0; i < chunk.length; ++i) { + buffer[offset + i] = chunk[i] + } + + offset += chunk.length + + } else { + buffer.writeUInt8(chunk, offset) + offset += 1 + } + }) + + return Script.fromBuffer(buffer) +} + +// FIXME: doesn't work for data chunks, maybe time to use buffertools.compare... +Script.prototype.without = function(needle) { + return Script.fromChunks(this.chunks.filter(function(op) { + return op !== needle + })) +} + module.exports = Script diff --git a/test/script.js b/test/script.js index 85cd768..6abbd55 100644 --- a/test/script.js +++ b/test/script.js @@ -1,6 +1,7 @@ var assert = require('assert') var crypto = require('../src/crypto') var networks = require('../src/networks') +var opcodes = require('../src/opcodes') var Address = require('../src/address') var ECPubKey = require('../src/ecpubkey') @@ -156,4 +157,35 @@ describe('Script', function() { }, /Not enough signatures provided/) }) }) + + describe('fromChunks', function() { + it('should match expected behaviour', function() { + var hash = new Buffer(32) + var script = Script.fromChunks([ + opcodes.OP_HASH160, + hash, + opcodes.OP_EQUAL + ]) + + assert.deepEqual(script, Script.createP2SHScriptPubKey(hash)) + }) + }) + + describe('without', function() { + var hex = 'a914e8c300c87986efa94c37c0519929019ef86eb5b487' + var script = Script.fromHex(hex) + + it('should return a script without the given value', function() { + var subScript = script.without(opcodes.OP_HASH160) + + assert.equal(subScript.toHex(), '14e8c300c87986efa94c37c0519929019ef86eb5b487') + }) + + it('shouldnt mutate the original script', function() { + var subScript = script.without(opcodes.OP_EQUAL) + + assert.notEqual(subScript.toHex(), hex) + assert.equal(script.toHex(), hex) + }) + }) })