diff --git a/lib/address.js b/lib/address.js index 4ddcd21..0f80a20 100644 --- a/lib/address.js +++ b/lib/address.js @@ -105,6 +105,8 @@ Address.prototype._classifyArguments = function(data, network, type) { return Address._transformScript(data, network); } else if (typeof(data) === 'string') { return Address._transformString(data, network, type); + } else if (_.isObject(data)) { + return Address._transformObject(data); } else { throw new TypeError('First argument is an unrecognized data format.'); } @@ -132,6 +134,23 @@ Address._transformHash = function(hash){ return info; }; +/** + * Deserializes an address serialized through `Address#toObject()` + * @param {Object} data + * @param {string} data.hash - the hash that this address encodes + * @param {string} data.type - either 'pubkeyhash' or 'scripthash' + * @param {Network=} data.network - the name of the network associated + * @return {Address} + */ +Address._transformObject = function(data) { + $.checkArgument(data.hash, 'Must provide a `hash` property'); + $.checkArgument(data.type, 'Must provide a `type` property'); + data.hashBuffer = new Buffer(data.hash, 'hex'); + data.network = Networks.get(data.network) || Networks.defaultNetwork; + + return data; +}; + /** * Internal function to discover the network and type based on the first data byte * diff --git a/lib/transaction/transaction.js b/lib/transaction/transaction.js index b86ace0..a76f396 100644 --- a/lib/transaction/transaction.js +++ b/lib/transaction/transaction.js @@ -203,6 +203,9 @@ Transaction.prototype.fromJSON = function(json) { outputs.forEach(function(output) { self.outputs.push(Output.fromJSON(output)); }); + if (json.change) { + this.change(json.change); + } this.version = json.version; this.nLockTime = json.nLockTime; return this; @@ -218,6 +221,7 @@ Transaction.prototype.toObject = function toObject() { outputs.push(output.toObject()); }); return { + change: this._change ? this._change.toObject() : undefined, version: this.version, inputs: inputs, outputs: outputs, @@ -233,6 +237,9 @@ Transaction.prototype.fromObject = function(transaction) { _.each(transaction.outputs, function(output) { self.addOutput(new Output(output)); }); + if (transaction.change) { + this.change(transaction.change); + } this.nLockTime = transaction.nLockTime; this.version = transaction.version; }; diff --git a/test/address.js b/test/address.js index e2d41fc..82d8189 100644 --- a/test/address.js +++ b/test/address.js @@ -233,7 +233,7 @@ describe('Address', function() { it('should error because of unrecognized data format', function() { (function() { return new Address(new Error()); - }).should.throw('First argument is an unrecognized data format.'); + }).should.throw(bitcore.errors.InvalidArgument); }); it('should error because of incorrect format for pubkey hash', function() { diff --git a/test/transaction/transaction.js b/test/transaction/transaction.js index 2aeeaa8..2a36acf 100644 --- a/test/transaction/transaction.js +++ b/test/transaction/transaction.js @@ -214,6 +214,16 @@ describe('Transaction', function() { }); }); + describe('serialization', function() { + it('stores the change address correctly', function() { + var serialized = new Transaction() + .change(changeAddress) + .toObject(); + var deserialized = new Transaction(serialized); + expect(deserialized._change.toString()).to.equal(changeAddress); + }); + }); + describe('checked serialize', function() { it('fails if no change address was set', function() { var transaction = new Transaction()