From e11019a083648400df0202424f5630858e39e9d8 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Thu, 18 Sep 2014 17:52:02 -0700 Subject: [PATCH] toJSON, fromJSON Every object should have toJSON and fromJSON methods so you can have a reliable way to store and retrieve objects. --- lib/block.js | 29 +++++++++++++++++++++++++++++ lib/blockheader.js | 23 +++++++++++++++++++++++ lib/bn.js | 10 ++++++++++ lib/script.js | 8 ++++++++ lib/transaction.js | 39 +++++++++++++++++++++++++++++++++++++++ lib/txin.js | 21 +++++++++++++++++++++ lib/txout.js | 17 +++++++++++++++++ lib/varint.js | 11 +++++++++++ test/block.js | 32 ++++++++++++++++++++++++++++++++ test/blockheader.js | 35 +++++++++++++++++++++++++++++++++++ test/bn.js | 17 +++++++++++++++++ test/script.js | 16 ++++++++++++++++ test/transaction.js | 35 +++++++++++++++++++++++++++++++++++ test/txin.js | 26 ++++++++++++++++++++++++++ test/txout.js | 31 +++++++++++++++++++++++++++++++ test/varint.js | 20 ++++++++++++++++++++ 16 files changed, 370 insertions(+) diff --git a/lib/block.js b/lib/block.js index 50249b363..3db8f2a46 100644 --- a/lib/block.js +++ b/lib/block.js @@ -29,6 +29,35 @@ Block.prototype.set = function(obj) { return this; }; +Block.prototype.fromJSON = function(json) { + var txs = []; + json.txs.forEach(function(tx) { + txs.push(Transaction().fromJSON(tx)); + }); + this.set({ + magicnum: json.magicnum, + blocksize: json.blocksize, + blockheader: Blockheader().fromJSON(json.blockheader), + txsvi: Varint().fromJSON(json.txsvi), + txs: txs + }); + return this; +}; + +Block.prototype.toJSON = function() { + var txs = []; + this.txs.forEach(function(tx) { + txs.push(tx.toJSON()); + }); + return { + magicnum: this.magicnum, + blocksize: this.blocksize, + blockheader: this.blockheader.toJSON(), + txsvi: this.txsvi.toJSON(), + txs: txs + }; +}; + Block.prototype.fromBuffer = function(buf) { return this.fromBufferReader(BufferReader(buf)); }; diff --git a/lib/blockheader.js b/lib/blockheader.js index d4ffc89cf..0d047a0b7 100644 --- a/lib/blockheader.js +++ b/lib/blockheader.js @@ -29,6 +29,29 @@ Blockheader.prototype.set = function(obj) { return this; }; +Blockheader.prototype.fromJSON = function(json) { + this.set({ + version: json.version, + prevblockidbuf: new Buffer(json.prevblockidbuf, 'hex'), + merklerootbuf: new Buffer(json.merklerootbuf, 'hex'), + time: json.time, + bits: json.bits, + nonce: json.nonce + }); + return this; +}; + +Blockheader.prototype.toJSON = function() { + return { + version: this.version, + prevblockidbuf: this.prevblockidbuf.toString('hex'), + merklerootbuf: this.merklerootbuf.toString('hex'), + time: this.time, + bits: this.bits, + nonce: this.nonce + }; +}; + Blockheader.prototype.fromBuffer = function(buf) { return this.fromBufferReader(BufferReader(buf)); }; diff --git a/lib/bn.js b/lib/bn.js index b841a5124..4754556a5 100644 --- a/lib/bn.js +++ b/lib/bn.js @@ -18,6 +18,16 @@ var reversebuf = function(buf, nbuf) { } }; +BN.prototype.toJSON = function() { + return this.toString(); +}; + +BN.prototype.fromJSON = function(str) { + var bn = BN(str); + bn.copy(this); + return this; +}; + BN.prototype.fromString = function(str) { var bn = BN(str); bn.copy(this); diff --git a/lib/script.js b/lib/script.js index affa32a96..18bd2b800 100644 --- a/lib/script.js +++ b/lib/script.js @@ -26,6 +26,14 @@ Script.prototype.set = function(obj) { 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 = []; diff --git a/lib/transaction.js b/lib/transaction.js index 55e7af694..e7762a242 100644 --- a/lib/transaction.js +++ b/lib/transaction.js @@ -32,6 +32,45 @@ Transaction.prototype.set = function(obj) { return this; }; +Transaction.prototype.fromJSON = function(json) { + var txins = []; + json.txins.forEach(function(txin) { + txins.push(Txin().fromJSON(txin)); + }); + var txouts = []; + json.txouts.forEach(function(txout) { + txouts.push(Txout().fromJSON(txout)); + }); + this.set({ + version: json.version, + txinsvi: Varint().fromJSON(json.txinsvi), + txins: txins, + txoutsvi: Varint().fromJSON(json.txoutsvi), + txouts: txouts, + nlocktime: json.nlocktime + }); + return this; +}; + +Transaction.prototype.toJSON = function() { + var txins = []; + this.txins.forEach(function(txin) { + txins.push(txin.toJSON()); + }); + var txouts = []; + this.txouts.forEach(function(txout) { + txouts.push(txout.toJSON()); + }); + return { + version: this.version, + txinsvi: this.txinsvi.toJSON(), + txins: txins, + txoutsvi: this.txoutsvi.toJSON(), + txouts: txouts, + nlocktime: this.nlocktime + }; +}; + Transaction.prototype.fromBuffer = function(buf) { return this.fromBufferReader(BufferReader(buf)); }; diff --git a/lib/txin.js b/lib/txin.js index bb36f8acd..044174500 100644 --- a/lib/txin.js +++ b/lib/txin.js @@ -27,6 +27,27 @@ Txin.prototype.set = function(obj) { return this; }; +Txin.prototype.fromJSON = function(json) { + this.set({ + txidbuf: new Buffer(json.txidbuf, 'hex'), + txoutnum: json.txoutnum, + scriptvi: Varint().fromJSON(json.scriptvi), + script: Script().fromJSON(json.script), + seqnum: json.seqnum + }); + return this; +}; + +Txin.prototype.toJSON = function() { + return { + txidbuf: this.txidbuf.toString('hex'), + txoutnum: this.txoutnum, + scriptvi: this.scriptvi.toJSON(), + script: this.script.toJSON(), + seqnum: this.seqnum + }; +}; + Txin.prototype.fromBuffer = function(buf) { return this.fromBufferReader(BufferReader(buf)); }; diff --git a/lib/txout.js b/lib/txout.js index ba644577b..05a4c73b8 100644 --- a/lib/txout.js +++ b/lib/txout.js @@ -26,6 +26,23 @@ Txout.prototype.set = function(obj) { return this; }; +Txout.prototype.fromJSON = function(json) { + this.set({ + valuebn: BN().fromJSON(json.valuebn), + scriptvi: Varint().fromJSON(json.scriptvi), + script: Script().fromJSON(json.script) + }); + return this; +}; + +Txout.prototype.toJSON = function() { + return { + valuebn: this.valuebn.toJSON(), + scriptvi: this.scriptvi.toJSON(), + script: this.script.toJSON() + }; +}; + Txout.prototype.fromBuffer = function(buf) { return this.fromBufferReader(BufferReader(buf)); }; diff --git a/lib/varint.js b/lib/varint.js index c114ae272..e959f2fbd 100644 --- a/lib/varint.js +++ b/lib/varint.js @@ -21,6 +21,17 @@ Varint.prototype.set = function(obj) { return this; }; +Varint.prototype.fromJSON = function(json) { + this.set({ + buf: new Buffer(json, 'hex') + }); + return this; +}; + +Varint.prototype.toJSON = function() { + return this.buf.toString('hex'); +}; + Varint.prototype.fromBuffer = function(buf) { this.buf = buf; return this; diff --git a/test/block.js b/test/block.js index dd8e90713..55aa05140 100644 --- a/test/block.js +++ b/test/block.js @@ -55,6 +55,38 @@ describe('Block', function() { }); + describe('#fromJSON', function() { + + it('should set these known values', function() { + var block = Block().set({ + magicnum: magicnum, + blocksize: blocksize, + blockheader: bh.toJSON(), + txsvi: txsvi.toJSON(), + txs: [txs[0].toJSON()] + }); + should.exist(block.magicnum); + should.exist(block.blocksize); + should.exist(block.blockheader); + should.exist(block.txsvi); + should.exist(block.txs); + }); + + }); + + describe('#toJSON', function() { + + it('should recover these known values', function() { + var json = block.toJSON(); + should.exist(json.magicnum); + should.exist(json.blocksize); + should.exist(json.blockheader); + should.exist(json.txsvi); + should.exist(json.txs); + }); + + }); + describe('#fromBuffer', function() { it('should make a block from this known buffer', function() { diff --git a/test/blockheader.js b/test/blockheader.js index 03a335f30..a4d7c24eb 100644 --- a/test/blockheader.js +++ b/test/blockheader.js @@ -53,6 +53,41 @@ describe('Blockheader', function() { }); + describe('#fromJSON', function() { + + it('should set all the variables', function() { + var bh = Blockheader().fromJSON({ + version: version, + prevblockidbuf: prevblockidbuf.toString('hex'), + merklerootbuf: merklerootbuf.toString('hex'), + time: time, + bits: bits, + nonce: nonce + }); + should.exist(bh.version); + should.exist(bh.prevblockidbuf); + should.exist(bh.merklerootbuf); + should.exist(bh.time); + should.exist(bh.bits); + should.exist(bh.nonce); + }); + + }); + + describe('#toJSON', function() { + + it('should set all the variables', function() { + var json = bh.toJSON(); + should.exist(json.version); + should.exist(json.prevblockidbuf); + should.exist(json.merklerootbuf); + should.exist(json.time); + should.exist(json.bits); + should.exist(json.nonce); + }); + + }); + describe('#fromBuffer', function() { it('should parse this known buffer', function() { diff --git a/test/bn.js b/test/bn.js index dbf8d5e82..03ef279a1 100644 --- a/test/bn.js +++ b/test/bn.js @@ -66,6 +66,23 @@ describe('BN', function() { }); + describe('#fromJSON', function() { + + it('should make BN from a string', function() { + BN().fromJSON('5').toString().should.equal('5'); + }); + + }); + + describe('#toJSON', function() { + + it('should make string from a BN', function() { + BN(5).toJSON().should.equal('5'); + BN().fromJSON('5').toJSON().should.equal('5'); + }); + + }); + describe('#fromString', function() { it('should make BN from a string', function() { diff --git a/test/script.js b/test/script.js index a8af6ca77..739f7dd0e 100644 --- a/test/script.js +++ b/test/script.js @@ -180,4 +180,20 @@ describe('Script', function() { }); + describe('#fromJSON', function() { + + it('should parse this known script', function() { + Script().fromJSON('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); + }); + + }); + + describe('#toJSON', function() { + + it('should output this known script', function() { + Script().fromString('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toJSON().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); + }); + + }); + }); diff --git a/test/transaction.js b/test/transaction.js index 9a9ef4ce5..ba6f6fe3e 100644 --- a/test/transaction.js +++ b/test/transaction.js @@ -53,6 +53,41 @@ describe('Transaction', function() { }); + describe('#fromJSON', function() { + + it('should set all the basic parameters', function() { + var tx = Transaction().fromJSON({ + version: 0, + txinsvi: Varint(1).toJSON(), + txins: [txin.toJSON()], + txoutsvi: Varint(1).toJSON(), + txouts: [txout.toJSON()], + nlocktime: 0 + }); + should.exist(tx.version); + should.exist(tx.txinsvi); + should.exist(tx.txins); + should.exist(tx.txoutsvi); + should.exist(tx.txouts); + should.exist(tx.nlocktime); + }); + + }); + + describe('#toJSON', function() { + + it('should recover all the basic parameters', function() { + var json = tx.toJSON(); + should.exist(json.version); + should.exist(json.txinsvi); + should.exist(json.txins); + should.exist(json.txoutsvi); + should.exist(json.txouts); + should.exist(json.nlocktime); + }); + + }); + describe('#fromBuffer', function() { it('should recover from this known tx', function() { diff --git a/test/txin.js b/test/txin.js index f441f63e6..92d386ab1 100644 --- a/test/txin.js +++ b/test/txin.js @@ -46,6 +46,32 @@ describe('Txin', function() { }); + describe('#fromJSON', function() { + + it('should set these vars', function() { + var txin2 = Txin().fromJSON(txin.toJSON()); + should.exist(txin2.txidbuf); + should.exist(txin2.txoutnum); + should.exist(txin2.scriptvi); + should.exist(txin2.script); + should.exist(txin2.seqnum); + }); + + }); + + describe('#toJSON', function() { + + it('should set these vars', function() { + var json = txin.toJSON() + should.exist(json.txidbuf); + should.exist(json.txoutnum); + should.exist(json.scriptvi); + should.exist(json.script); + should.exist(json.seqnum); + }); + + }); + describe('#fromBuffer', function() { it('should convert this known buffer', function() { diff --git a/test/txout.js b/test/txout.js index 59a9fb9ec..fc3cd9ab6 100644 --- a/test/txout.js +++ b/test/txout.js @@ -39,6 +39,37 @@ describe('Txout', function() { }); + describe('#fromJSON', function() { + + it('should set from this json', function() { + var txout = Txout().fromJSON({ + valuebn: valuebn.toJSON(), + scriptvi: scriptvi.toJSON(), + script: script.toJSON() + }); + should.exist(txout.valuebn); + should.exist(txout.scriptvi); + should.exist(txout.script); + }); + + }); + + describe('#toJSON', function() { + + it('should return this json', function() { + var txout = Txout().fromJSON({ + valuebn: valuebn.toJSON(), + scriptvi: scriptvi.toJSON(), + script: script.toJSON() + }); + var json = txout.toJSON(); + should.exist(json.valuebn); + should.exist(json.scriptvi); + should.exist(json.script); + }); + + }); + describe('#fromBuffer', function() { it('should make this txin from this known buffer', function() { diff --git a/test/varint.js b/test/varint.js index 23e1934cb..b19ae952c 100644 --- a/test/varint.js +++ b/test/varint.js @@ -28,6 +28,26 @@ describe('Varint', function() { }); + describe('#fromJSON', function() { + + it('should set a buffer', function() { + var buf = BufferWriter().writeVarintNum(5).concat(); + var varint = Varint().fromJSON(buf.toString('hex')); + varint.toNumber().should.equal(5); + }); + + }); + + describe('#toJSON', function() { + + it('should return a buffer', function() { + var buf = BufferWriter().writeVarintNum(5).concat(); + var varint = Varint().fromJSON(buf.toString('hex')); + varint.toJSON().should.equal('05'); + }); + + }); + describe('#fromBuffer', function() { it('should set a buffer', function() {