mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 04:05:52 +00:00
UInt160 can be an account or a plain hash.
The UInt160 class used to be hardcoded to be an Account. This commit changes it so it can be used as an account or a plain hash. It will try to automatically self-classify based on how it is initialized. In the future we may want to have some dedicated classes rather than a single configurable UInt160.
This commit is contained in:
@@ -15,6 +15,7 @@ var sjcl = utils.sjcl;
|
||||
var UInt128 = require('./uint128').UInt128;
|
||||
var UInt160 = require('./uint160').UInt160;
|
||||
var UInt256 = require('./uint256').UInt256;
|
||||
var Base = require('./base').Base;
|
||||
|
||||
var amount = require('./amount');
|
||||
var Amount = amount.Amount;
|
||||
@@ -381,6 +382,7 @@ var STAmount = exports.Amount = new SerializedType({
|
||||
var currency = STCurrency.parse(so);
|
||||
var issuer_bytes = so.read(20);
|
||||
var issuer = UInt160.from_bytes(issuer_bytes);
|
||||
issuer.set_version(Base.VER_ACCOUNT_ID);
|
||||
var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97;
|
||||
var mantissa_bytes = value_bytes.slice(1);
|
||||
mantissa_bytes[0] &= 0x3f;
|
||||
@@ -441,6 +443,7 @@ var STAccount = exports.Account = new SerializedType({
|
||||
}
|
||||
|
||||
var result = UInt160.from_bytes(so.read(len));
|
||||
result.set_version(Base.VER_ACCOUNT_ID);
|
||||
|
||||
//console.log('PARSED 160:', result.to_json());
|
||||
if (false && !result.is_valid()) {
|
||||
@@ -529,6 +532,7 @@ var STPathSet = exports.PathSet = new SerializedType({
|
||||
/*var bta = so.read(20);
|
||||
console.log('BTA:', bta);*/
|
||||
entry.account = STHash160.parse(so);
|
||||
entry.account.set_version(Base.VER_ACCOUNT_ID);
|
||||
}
|
||||
if (tag_byte & this.typeCurrency) {
|
||||
//console.log('entry.currency');
|
||||
@@ -541,6 +545,7 @@ var STPathSet = exports.PathSet = new SerializedType({
|
||||
if (tag_byte & this.typeIssuer) {
|
||||
//console.log('entry.issuer');
|
||||
entry.issuer = STHash160.parse(so); //should know to use Base58?
|
||||
entry.issuer.set_version(Base.VER_ACCOUNT_ID);
|
||||
//console.log('DONE WITH ISSUER!');
|
||||
}
|
||||
|
||||
|
||||
@@ -129,9 +129,6 @@ UInt.prototype.parse_generic = function (j) {
|
||||
if ('string' !== typeof j) {
|
||||
this._value = NaN;
|
||||
}
|
||||
else if (j[0] === "r") {
|
||||
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
|
||||
}
|
||||
else if (this.constructor.width === j.length) {
|
||||
this._value = new BigInteger(utils.stringToArray(j), 256);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ var Base = require('./base').Base;
|
||||
var UInt160 = extend(function () {
|
||||
// Internal form: NaN or BigInteger
|
||||
this._value = NaN;
|
||||
this._version_byte = void(0);
|
||||
}, UInt);
|
||||
|
||||
UInt160.width = 20;
|
||||
@@ -28,6 +29,16 @@ var HEX_ONE = UInt160.HEX_ONE = '0000000000000000000000000000000000000
|
||||
var STR_ZERO = UInt160.STR_ZERO = utils.hexToString(HEX_ZERO);
|
||||
var STR_ONE = UInt160.STR_ONE = utils.hexToString(HEX_ONE);
|
||||
|
||||
UInt160.prototype.set_version = function (j) {
|
||||
this._version_byte = j;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
UInt160.prototype.get_version = function () {
|
||||
return this._version_byte;
|
||||
};
|
||||
|
||||
// value = NaN on error.
|
||||
UInt160.prototype.parse_json = function (j) {
|
||||
// Canonicalize and validate
|
||||
@@ -36,13 +47,30 @@ UInt160.prototype.parse_json = function (j) {
|
||||
}
|
||||
|
||||
if (typeof j === 'number' && !isNaN(j)) {
|
||||
// Allow raw numbers - DEPRECATED
|
||||
// This is used mostly by the test suite and is supported
|
||||
// as a legacy feature only. DO NOT RELY ON THIS BEHAVIOR.
|
||||
this._value = new BigInteger(String(j));
|
||||
this._version_byte = Base.VER_ACCOUNT_ID;
|
||||
} else if (typeof j !== 'string') {
|
||||
this._value = NaN;
|
||||
} else if (j[0] === 'r') {
|
||||
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
|
||||
this._version_byte = Base.VER_ACCOUNT_ID;
|
||||
} else {
|
||||
this._value = NaN;
|
||||
this.parse_hex(j);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
UInt160.prototype.parse_generic = function (j) {
|
||||
UInt.prototype.parse_generic.call(this, j);
|
||||
|
||||
if (isNaN(this._value)) {
|
||||
if ("string" === typeof j && j[0] === 'r') {
|
||||
this._value = Base.decode_check(Base.VER_ACCOUNT_ID, j);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -50,17 +78,22 @@ UInt160.prototype.parse_json = function (j) {
|
||||
|
||||
// XXX Json form should allow 0 and 1, C++ doesn't currently allow it.
|
||||
UInt160.prototype.to_json = function (opts) {
|
||||
var opts = opts || {};
|
||||
var output = NaN;
|
||||
opts = opts || {};
|
||||
|
||||
if (this._value instanceof BigInteger) {
|
||||
output = Base.encode_check(Base.VER_ACCOUNT_ID, this.to_bytes());
|
||||
// If this value has a type, return a Base58 encoded string.
|
||||
if ("number" === typeof this._version_byte) {
|
||||
var output = Base.encode_check(this._version_byte, this.to_bytes());
|
||||
if (opts.gateways && output in opts.gateways) {
|
||||
output = opts.gateways[output];
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
} else {
|
||||
return this.to_hex();
|
||||
}
|
||||
}
|
||||
return NaN;
|
||||
};
|
||||
|
||||
exports.UInt160 = UInt160;
|
||||
|
||||
@@ -36,7 +36,7 @@ describe('Amount', function() {
|
||||
assert.deepEqual(new BigInteger(), UInt160.from_generic('0')._value);
|
||||
});
|
||||
it('Parse 0 export', function () {
|
||||
assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_generic('0').to_json());
|
||||
assert.strictEqual(UInt160.ACCOUNT_ZERO, UInt160.from_generic('0').set_version(0).to_json());
|
||||
});
|
||||
it('Parse 1', function () {
|
||||
assert.deepEqual(new BigInteger([1]), UInt160.from_generic('1')._value);
|
||||
|
||||
@@ -378,19 +378,37 @@ describe('Serialized types', function() {
|
||||
|
||||
describe('Hash160', function() {
|
||||
it('Serialize 0', function () {
|
||||
var hex = '0000000000000000000000000000000000000000';
|
||||
var base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, 'rrrrrrrrrrrrrrrrrrrrrhoLvTp');
|
||||
assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000000');
|
||||
types.Hash160.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Hash160.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
});
|
||||
it('Serialize 1', function () {
|
||||
var hex = '0000000000000000000000000000000000000001';
|
||||
var base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji';
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, 'rrrrrrrrrrrrrrrrrrrrBZbvji');
|
||||
assert.strictEqual(so.to_hex(), '0000000000000000000000000000000000000001');
|
||||
types.Hash160.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Hash160.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
});
|
||||
it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function () {
|
||||
var hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
|
||||
var base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi';
|
||||
var so = new SerializedObject();
|
||||
types.Hash160.serialize(so, 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi');
|
||||
assert.strictEqual(so.to_hex(), 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF');
|
||||
types.Hash160.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Hash160.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), hex);
|
||||
});
|
||||
it('Parse 0', function () {
|
||||
var val = '0000000000000000000000000000000000000000';
|
||||
@@ -410,6 +428,14 @@ describe('Serialized types', function() {
|
||||
var num = types.Hash160.parse(so);
|
||||
assert.strictEqual(num.to_hex(), val);
|
||||
});
|
||||
it('Parse 0 as JSON', function () {
|
||||
// Hash160 should be returned as hex in JSON, unlike
|
||||
// addresses.
|
||||
var val = '0000000000000000000000000000000000000000';
|
||||
var so = new SerializedObject(val);
|
||||
var num = types.Hash160.parse(so);
|
||||
assert.strictEqual(num.to_json(), val);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Hash256', function() {
|
||||
@@ -539,6 +565,60 @@ describe('Serialized types', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Account', function() {
|
||||
it('Serialize 0', function () {
|
||||
var hex = '0000000000000000000000000000000000000000';
|
||||
var base58 = 'rrrrrrrrrrrrrrrrrrrrrhoLvTp';
|
||||
var so = new SerializedObject();
|
||||
types.Account.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Account.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
});
|
||||
it('Serialize 1', function () {
|
||||
var hex = '0000000000000000000000000000000000000001';
|
||||
var base58 = 'rrrrrrrrrrrrrrrrrrrrBZbvji';
|
||||
var so = new SerializedObject();
|
||||
types.Account.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Account.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
});
|
||||
it('Serialize FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', function () {
|
||||
var hex = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
|
||||
var base58 = 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi';
|
||||
var so = new SerializedObject();
|
||||
types.Account.serialize(so, base58);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
|
||||
so = new SerializedObject();
|
||||
types.Account.serialize(so, hex);
|
||||
assert.strictEqual(so.to_hex(), "14"+hex);
|
||||
});
|
||||
it('Parse 0', function () {
|
||||
var val = '140000000000000000000000000000000000000000';
|
||||
var so = new SerializedObject(val);
|
||||
var num = types.Account.parse(so);
|
||||
assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrrhoLvTp');
|
||||
});
|
||||
it('Parse 1', function () {
|
||||
var val = '140000000000000000000000000000000000000001';
|
||||
var so = new SerializedObject(val);
|
||||
var num = types.Account.parse(so);
|
||||
assert.strictEqual(num.to_json(), 'rrrrrrrrrrrrrrrrrrrrBZbvji');
|
||||
});
|
||||
it('Parse HASH160_MAX', function () {
|
||||
var val = '14FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF';
|
||||
var so = new SerializedObject(val);
|
||||
var num = types.Account.parse(so);
|
||||
assert.strictEqual(num.to_json(), 'rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi');
|
||||
});
|
||||
});
|
||||
|
||||
describe('PathSet', function() {
|
||||
it('Serialize single empty path [[]]', function () {
|
||||
var so = new SerializedObject();
|
||||
|
||||
Reference in New Issue
Block a user