Merge pull request #736 from braydonf/feature/to-object

Added `toObject` methods to return an `object` and modified `toJSON` to return a `string`. Closes #732
This commit is contained in:
Manuel Aráoz 2014-12-13 12:22:50 -03:00
commit 5477a2d857
24 changed files with 129 additions and 94 deletions

View File

@ -105,6 +105,19 @@ DON'T:
var bufferUtil = require('./util/buffer');
```
### G7 - General: Standard Methods
When possible, bitcore objects should have standard methods on an instance prototype:
* `toObject` - A plain JavaScript object that can be JSON stringified
* `toJSON` - A JSON stringified object of the instance
* `toString` - A string representation of the instance
* `toBuffer` - A hex Buffer
These should have a matching static method that can be used for instantiation:
* `fromJSON` - Should handle both JSON from `toJSON` and plain JavaScript object from `toObject`
* `fromString` - Should be able to instantiate with output from `toString`
* `fromBuffer` - Should likewise be able to instantiate from output from `toBuffer`
### E1 - Errors: Use bitcore.Errors
We've designed a structure for Errors to follow and are slowly migrating to it.
@ -233,7 +246,7 @@ the change the branch introduces. Some examples for such branches are:
```sh
git checkout -b test/some-module
git checkout -b feature/some-new-stuff
git checkout -b fix/some-bug
git checkout -b fix/some-bug
git checkout -b remove/some-file
```
@ -244,7 +257,7 @@ git pull --rebase bitpay master
```
Note that we require rebasing your branch instead of mergeing it, for commit
readability reasons.
readability reasons.
After that, you can push the changes to your fork, by doing:
```sh

View File

@ -1,5 +1,6 @@
'use strict';
var $ = require('./util/preconditions');
var base58check = require('./encoding/base58check');
var Networks = require('./networks');
var Hash = require('./crypto/hash');
@ -316,6 +317,10 @@ Address.fromJSON = function fromJSON(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
$.checkState(
JSUtil.isHexa(json.hash),
'Unexpected hash property, "' + json.hash + '", expected to be hex.'
);
var hashBuffer = new Buffer(json.hash, 'hex');
return new Address(hashBuffer, json.network, json.type);
};
@ -390,7 +395,7 @@ Address.prototype.toBuffer = function() {
/**
* @returns {Object} An object of the address
*/
Address.prototype.toJSON = function toJSON() {
Address.prototype.toObject = function toObject() {
return {
hash: this.hashBuffer.toString('hex'),
type: this.type,
@ -398,6 +403,13 @@ Address.prototype.toJSON = function toJSON() {
};
};
/**
* @returns {Object} An object of the address
*/
Address.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* Will return a the string representation of the address
*

View File

@ -70,7 +70,7 @@ Block._fromJSON = function _fromJSON(data) {
magicnum: data.magicnum,
blocksize: data.blocksize,
blockheader: BlockHeader.fromJSON(data.blockheader),
txsvi: Varint().fromJSON(data.txsvi),
txsvi: Varint().fromString(data.txsvi),
txs: txs
};
return info;
@ -144,9 +144,9 @@ Block.fromRawBlock = function fromRawBlock(data) {
};
/**
* @returns {Object} - A JSON object with the block properties
* @returns {Object} - A plain object with the block properties
*/
Block.prototype.toJSON = function toJSON() {
Block.prototype.toObject = function toObject() {
var txs = [];
this.txs.forEach(function(tx) {
txs.push(tx.toJSON());
@ -154,12 +154,19 @@ Block.prototype.toJSON = function toJSON() {
return {
magicnum: this.magicnum,
blocksize: this.blocksize,
blockheader: this.blockheader.toJSON(),
txsvi: this.txsvi.toJSON(),
blockheader: this.blockheader.toObject(),
txsvi: this.txsvi.toString(),
txs: txs
};
};
/**
* @returns {String} - A JSON string
*/
Block.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* @returns {Buffer} - A buffer of the block
*/

View File

@ -139,9 +139,9 @@ BlockHeader.fromBufferReader = function fromBufferReader(br) {
};
/**
* @returns {Object} - A JSON object of the BlockHeader
* @returns {Object} - A plain object of the BlockHeader
*/
BlockHeader.prototype.toJSON = function toJSON() {
BlockHeader.prototype.toObject = function toObject() {
return {
version: this.version,
prevblockidbuf: this.prevblockidbuf.toString('hex'),
@ -152,6 +152,13 @@ BlockHeader.prototype.toJSON = function toJSON() {
};
};
/**
* @returns {String} - A JSON string
*/
BlockHeader.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* @returns {Buffer} - A Buffer of the BlockHeader
*/

View File

@ -19,16 +19,6 @@ var reversebuf = function(buf) {
return buf2;
};
BN.prototype.toJSON = function() {
return this.toString();
};
BN.prototype.fromJSON = function(str) {
var bn = BN(str);
bn.copy(this);
return this;
};
BN.prototype.fromNumber = function(n) {
var bn = BN(n);
bn.copy(this);

View File

@ -26,14 +26,14 @@ Varint.prototype.set = function(obj) {
return this;
};
Varint.prototype.fromJSON = function(json) {
Varint.prototype.fromString = function(str) {
this.set({
buf: new Buffer(json, 'hex')
buf: new Buffer(str, 'hex')
});
return this;
};
Varint.prototype.toJSON = function() {
Varint.prototype.toString = function() {
return this.buf.toString('hex');
};

View File

@ -406,7 +406,7 @@ HDPrivateKey.prototype.toString = function() {
*
* @return {Object}
*/
HDPrivateKey.prototype.toJSON = function() {
HDPrivateKey.prototype.toObject = function toObject() {
return {
network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name,
depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
@ -420,6 +420,10 @@ HDPrivateKey.prototype.toJSON = function() {
};
};
HDPrivateKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
HDPrivateKey.DefaultDepth = 0;
HDPrivateKey.DefaultFingerprint = 0;
HDPrivateKey.DefaultChildIndex = 0;

View File

@ -366,7 +366,7 @@ HDPublicKey.prototype.toString = function () {
* * xpubkey: the string with the base58 representation of this extended key
* * checksum: the base58 checksum of xpubkey
*/
HDPublicKey.prototype.toJSON = function () {
HDPublicKey.prototype.toObject = function toObject() {
return {
network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name,
depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
@ -380,6 +380,10 @@ HDPublicKey.prototype.toJSON = function () {
};
};
HDPublicKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
HDPublicKey.Hardened = 0x80000000;
HDPublicKey.RootElementAlias = ['m', 'M'];

View File

@ -310,11 +310,9 @@ PrivateKey.prototype.toAddress = function() {
};
/**
* Will output the PrivateKey to a WIF string
*
* @returns {String} A WIF representation of the private key
* @returns {Object} A plain object representation
*/
PrivateKey.prototype.toJSON = function() {
PrivateKey.prototype.toObject = function toObject() {
return {
bn: this.bn.toString('hex'),
compressed: this.compressed,
@ -322,6 +320,10 @@ PrivateKey.prototype.toJSON = function() {
};
};
PrivateKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* Will output the PrivateKey to a WIF string
*

View File

@ -6,7 +6,6 @@ var Point = require('./crypto/point');
var JSUtil = require('./util/js');
/**
*
* Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'.
*
* @example
@ -137,7 +136,6 @@ PublicKey._transformDER = function(buf){
};
/**
*
* Internal function to transform X into a public key point
*
* @param {Boolean} odd - If the point is above or below the x axis
@ -155,7 +153,6 @@ PublicKey._transformX = function(odd, x){
};
/**
*
* Instantiate a PublicKey from JSON
*
* @param {String} json - A JSON string
@ -172,7 +169,6 @@ PublicKey.fromJSON = function(json) {
};
/**
*
* Instantiate a PublicKey from a PrivateKey
*
* @param {PrivateKey} privkey - An instance of PrivateKey
@ -184,7 +180,6 @@ PublicKey.fromPrivateKey = function(privkey) {
};
/**
*
* Instantiate a PublicKey from a Buffer
*
* @param {Buffer} buf - A DER hex buffer
@ -196,7 +191,6 @@ PublicKey.fromBuffer = function(buf) {
};
/**
*
* Instantiate a PublicKey from a Point
*
* @param {Point} point - A Point instance
@ -210,7 +204,6 @@ PublicKey.fromPoint = function(point, compressed){
};
/**
*
* Instantiate a PublicKey from a DER Buffer
*
* @param {Buffer} buf - A DER Buffer
@ -222,7 +215,6 @@ PublicKey.fromDER = function(buf) {
};
/**
*
* Instantiate a PublicKey from a DER hex encoded string
*
* @param {String} str - A DER hex string
@ -236,7 +228,6 @@ PublicKey.fromString = function(str, encoding) {
};
/**
*
* Instantiate a PublicKey from an X Point
*
* @param {Boolean} odd - If the point is above or below the x axis
@ -250,7 +241,6 @@ PublicKey.fromX = function(odd, x) {
/**
*
* Check if there would be any errors when initializing a PublicKey
*
* @param {String} data - The encoded data in various formats
@ -268,7 +258,6 @@ PublicKey.getValidationError = function(data) {
};
/**
*
* Check if the parameters are valid
*
* @param {String} data - The encoded data in various formats
@ -280,12 +269,9 @@ PublicKey.isValid = function(data) {
};
/**
*
* Will output the PublicKey to JSON
*
* @returns {Object} A JSON object
* @returns {Object} A plain object of the PublicKey
*/
PublicKey.prototype.toJSON = function() {
PublicKey.prototype.toObject = function toObject() {
return {
x: this.point.getX().toString('hex'),
y: this.point.getY().toString('hex'),
@ -293,8 +279,11 @@ PublicKey.prototype.toJSON = function() {
};
};
PublicKey.prototype.toJSON = function toJSON(){
return JSON.stringify(this.toObject());
};
/**
*
* Will output the PublicKey to a Buffer
*
* @returns {Buffer} A DER hex encoded buffer
@ -305,7 +294,6 @@ PublicKey.prototype.toBuffer = function() {
};
/**
*
* Will output the PublicKey to a DER Buffer
*
* @returns {Buffer} A DER hex encoded buffer
@ -338,7 +326,6 @@ PublicKey.prototype.toDER = function(compressed) {
};
/**
*
* Will return an address for the public key
*
* @returns {Address} An address generated from the public key
@ -348,7 +335,6 @@ PublicKey.prototype.toAddress = function(network) {
};
/**
*
* Will output the PublicKey to a DER encoded hex string
*
* @returns {String} A DER hex encoded string
@ -359,7 +345,6 @@ PublicKey.prototype.toString = function() {
};
/**
*
* Will return a string formatted for the console
*
* @returns {String} Public key

View File

@ -4,7 +4,7 @@ var _ = require('lodash');
var BufferWriter = require('../../encoding/bufferwriter');
var buffer = require('buffer');
var bufferUtil = require('../../util/buffer');
var jsUtil = require('../../util/js');
var JSUtil = require('../../util/js');
var Script = require('../../script');
function Input(params) {
@ -28,7 +28,7 @@ Object.defineProperty(Input.prototype, 'script', {
});
Input.prototype._fromObject = function(params) {
if (_.isString(params.prevTxId) && jsUtil.isHexa(params.prevTxId)) {
if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) {
params.prevTxId = new buffer.Buffer(params.prevTxId, 'hex');
}
this.prevTxId = params.prevTxId;
@ -40,7 +40,7 @@ Input.prototype._fromObject = function(params) {
return this;
};
Input.prototype.toJSON = function() {
Input.prototype.toObject = function toObject() {
return {
prevTxId: this.prevTxId,
outputIndex: this.outputIndex,
@ -49,7 +49,14 @@ Input.prototype.toJSON = function() {
};
};
Input.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
Input.fromJSON = function(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
return new Input({
prevTxId: json.prevTxId || json.txidbuf,
outputIndex: json.outputIndex || json.txoutnum,

View File

@ -4,6 +4,7 @@ var _ = require('lodash');
var BN = require('../crypto/bn');
var buffer = require('buffer');
var bufferUtil = require('../util/buffer');
var JSUtil = require('../util/js');
var BufferWriter = require('../encoding/bufferwriter');
var Script = require('../script');
@ -53,14 +54,21 @@ Output.prototype._fromObject = function(param) {
return this;
};
Output.prototype.toJSON = function() {
Output.prototype.toObject = function toObject() {
return {
satoshis: this.satoshis,
script: this._scriptBuffer.toString('hex')
};
};
Output.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
Output.fromJSON = function(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
return new Output({
satoshis: json.satoshis || -(-json.valuebn),
script: new Script(json.script)

View File

@ -6,6 +6,7 @@ var assert = require('assert');
var util = require('../util/js');
var bufferUtil = require('../util/buffer');
var JSUtil = require('../util/js');
var BufferReader = require('../encoding/bufferreader');
var BufferWriter = require('../encoding/bufferwriter');
var Hash = require('../crypto/hash');
@ -121,6 +122,9 @@ Transaction.prototype.fromBufferReader = function(reader) {
};
Transaction.prototype.fromJSON = function(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
var self = this;
this.inputs = [];
var inputs = json.inputs || json.txins;
@ -137,7 +141,7 @@ Transaction.prototype.fromJSON = function(json) {
return this;
};
Transaction.prototype.toJSON = function() {
Transaction.prototype.toObject = function toObject() {
var inputs = [];
this.inputs.forEach(function(input) {
inputs.push(input.toJSON());
@ -154,11 +158,12 @@ Transaction.prototype.toJSON = function() {
};
};
Transaction.prototype.fromString = function(string) {
this.fromBuffer(new buffer.Buffer(string, 'hex'));
Transaction.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
Transaction.prototype.fromObject = function(object) {
Transaction.prototype.fromString = function(string) {
this.fromBuffer(new buffer.Buffer(string, 'hex'));
};
Transaction.prototype._newTransaction = function() {

View File

@ -175,17 +175,21 @@ Unit.prototype.toString = function() {
};
/**
* Will return a the JSON object representation of the unit
* Will return a plain object representation of the Unit
*
* @returns {Object} An object with the keys: amount and code
*/
Unit.prototype.toJSON = function toJSON(){
Unit.prototype.toObject = function toObject() {
return {
amount: this._amount,
code: this._code
};
};
Unit.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* Will return a string formatted for the console
*

View File

@ -163,7 +163,7 @@ URI.prototype._parseAmount = function(amount) {
return Unit.fromBTC(amount).toSatoshis();
};
URI.prototype.toJSON = function() {
URI.prototype.toObject = function toObject() {
var json = {};
for (var i = 0; i < URI.Members.length; i++) {
var m = URI.Members[i];
@ -179,6 +179,10 @@ URI.prototype.toJSON = function() {
return json;
};
URI.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/**
* Will return a the string representation of the URI
*

View File

@ -363,7 +363,7 @@ describe('Address', function() {
});
it('should output/input a JSON string', function() {
var json = JSON.stringify(new Address(str).toJSON());
var json = new Address(str).toJSON();
var address = Address.fromJSON(json);
address.toString().should.equal(str);
});

View File

@ -107,8 +107,8 @@ describe('Block', function() {
describe('#toJSON', function() {
it('should recover these known values', function() {
var block = Block(json);
var b = block.toJSON();
var block = Block.fromJSON(json);
var b = JSON.parse(block.toJSON());
should.exist(b.magicnum);
should.exist(b.blocksize);
should.exist(b.blockheader);

View File

@ -87,7 +87,7 @@ describe('BlockHeader', function() {
describe('#toJSON', function() {
it('should set all the variables', function() {
var json = bh.toJSON();
var json = JSON.parse(bh.toJSON());
should.exist(json.version);
should.exist(json.prevblockidbuf);
should.exist(json.merklerootbuf);

View File

@ -67,23 +67,6 @@ 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() {

View File

@ -36,22 +36,22 @@ describe('Varint', function() {
});
describe('#fromJSON', function() {
describe('#fromString', function() {
it('should set a buffer', function() {
var buf = BufferWriter().writeVarintNum(5).concat();
var varint = Varint().fromJSON(buf.toString('hex'));
var varint = Varint().fromString(buf.toString('hex'));
varint.toNumber().should.equal(5);
});
});
describe('#toJSON', function() {
describe('#toString', 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');
var varint = Varint().fromString(buf.toString('hex'));
varint.toString().should.equal('05');
});
});

View File

@ -132,11 +132,11 @@ describe('PrivateKey', function() {
describe('#json', function() {
it('should input/output json', function() {
var json = {
var json = JSON.stringify({
bn: '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a',
compressed: false,
network: 'livenet'
};
});
PrivateKey.fromJSON(json).toJSON().should.deep.equal(json);
});

View File

@ -124,11 +124,11 @@ describe('PublicKey', function() {
describe('#json', function() {
it('should input/ouput json', function() {
var json = {
var json = JSON.stringify({
x: '1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a',
y: '7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341',
compressed: false
};
});
PublicKey.fromJSON(json).toJSON().should.deep.equal(json);
});

View File

@ -124,7 +124,7 @@ describe('Unit', function() {
});
it('should input/output JSON', function() {
var json = {amount:1.3, code:'BTC'};
var json = JSON.stringify({amount:1.3, code:'BTC'});
var unit = Unit.fromJSON(json);
unit.toJSON().should.deep.equal(json);
});

View File

@ -146,12 +146,12 @@ describe('URI', function() {
});
it('should input/output JSON', function() {
var json = {
var json = JSON.stringify({
address: '1DP69gMMvSuYhbnxsi4EJEFufUAbDrEQfj',
message: 'Donation for project xyz',
label: 'myLabel',
other: 'xD'
};
});
URI.fromJSON(json).toJSON().should.deep.equal(json);
});