Buffers, identities, and randomNumbers.

This commit is contained in:
Eric Martindale 2014-10-01 21:08:06 -04:00
parent 43d21e9f02
commit f01ebd97d2
4 changed files with 242 additions and 38 deletions

5
examples/identity.js Normal file
View File

@ -0,0 +1,5 @@
var Identity = require('../lib/identity');
var identity = new Identity( 0x02 );
console.log( identity.toString() );

View File

@ -1,15 +1,17 @@
exports.mainnet = {
pubkeyhash: 0x00,
privkey: 0x80,
scripthash: 0x05,
bip32pubkey: 0x0488b21e,
pubkeyhash: 0x00,
identpersist: 0x01,
identephem: 0x02,
privkey: 0x80,
scripthash: 0x05,
bip32pubkey: 0x0488b21e,
bip32privkey: 0x0488ade4,
};
exports.testnet = {
pubkeyhash: 0x6f,
privkey: 0xef,
scripthash: 0xc4,
bip32pubkey: 0x043587cf,
pubkeyhash: 0x6f,
privkey: 0xef,
scripthash: 0xc4,
bip32pubkey: 0x043587cf,
bip32privkey: 0x04358394,
};

View File

@ -1,12 +1,14 @@
var base58check = require('./base58check');
var constants = require('./constants');
var Hash = require('./hash');
var Pubkey = require('./pubkey');
var Script = require('./script');
var constants = require('./constants');
var Hash = require('./hash');
var Pubkey = require('./pubkey');
var Script = require('./script');
var Random = require('./random');
function Identity(buf) {
if (!(this instanceof Identity))
return new Identity(buf);
// TODO: instantiate identities without providing any configuration
if (!(this instanceof Identity)) return new Identity(buf);
if (Buffer.isBuffer(buf)) {
this.fromBuffer(buf);
} else if (typeof buf === 'string') {
@ -19,9 +21,9 @@ function Identity(buf) {
};
Identity.prototype.set = function(obj) {
this.hashbuf = obj.hashbuf || this.hashbuf || null;
this.networkstr = obj.networkstr || this.networkstr || 'mainnet';
this.typestr = obj.typestr || this.typestr || 'pubkeyhash';
this.hashbuf = obj.hashbuf || this.hashbuf || null;
this.networkstr = obj.networkstr || this.networkstr || 'mainnet';
this.typestr = obj.typestr || this.typestr || 'identephem';
return this;
};
@ -29,18 +31,13 @@ Identity.prototype.fromBuffer = function(buf) {
if (buf.length !== 1 + 20)
throw new Error('Identity buffers must be exactly 21 bytes');
var version = buf[0];
if (version === constants['mainnet']['pubkeyhash']) {
if (version === constants['mainnet']['identephem']) {
this.networkstr = 'mainnet';
this.typestr = 'pubkeyhash';
} else if (version === constants['mainnet']['scripthash']) {
this.typestr = 'identephem';
} else if (version === constants['mainnet']['identpersist']) {
this.networkstr = 'mainnet';
this.typestr = 'scripthash';
} else if (version === constants['testnet']['pubkeyhash']) {
this.networkstr = 'testnet';
this.typestr = 'pubkeyhash';
} else if (version === constants['testnet']['scripthash']) {
this.networkstr = 'testnet';
this.typestr = 'scripthash';
this.typestr = 'identpersist';
} else {
this.networkstr = 'unknown';
this.typestr = 'unknown';
@ -56,21 +53,14 @@ Identity.prototype.fromHashbuf = function(hashbuf, networkstr, typestr) {
throw new Error('hashbuf must be exactly 20 bytes');
this.hashbuf = hashbuf;
this.networkstr = networkstr || 'mainnet';
this.typestr = typestr || 'pubkeyhash';
this.typestr = typestr || 'identephem';
return this;
};
Identity.prototype.fromPubkey = function(pubkey, networkstr) {
this.hashbuf = Hash.sha256ripemd160(pubkey.toBuffer());
this.networkstr = networkstr || 'mainnet';
this.typestr = 'pubkeyhash';
return this;
};
Identity.prototype.fromScript = function(script, networkstr) {
this.hashbuf = Hash.sha256ripemd160(script.toBuffer());
this.networkstr = networkstr || 'mainnet';
this.typestr = 'scripthash';
this.typestr = 'identephem';
return this;
};
@ -98,6 +88,9 @@ Identity.prototype.isValid = function() {
};
Identity.prototype.toBuffer = function() {
console.log(this.networkstr); process.exit();
version = new Buffer([constants[this.networkstr][this.typestr]]);
var buf = Buffer.concat([version, this.hashbuf]);
return buf;
@ -112,8 +105,8 @@ Identity.prototype.validate = function() {
throw new Error('hash must be a buffer of 20 bytes');
if (this.networkstr !== 'mainnet' && this.networkstr !== 'testnet')
throw new Error('networkstr must be "mainnet" or "testnet"');
if (this.typestr !== 'pubkeyhash' && this.typestr !== 'scripthash')
throw new Error('typestr must be "pubkeyhash" or "scripthash"');
if (this.typestr !== 'identephem' && this.typestr !== 'scripthash')
throw new Error('typestr must be "identephem" or "scripthash"');
return this;
};

204
test/identity.js Normal file
View File

@ -0,0 +1,204 @@
var should = require('chai').should();
var constants = require('../lib/constants');
var Pubkey = require('../lib/pubkey');
var Identity = require('../lib/identity');
var Script = require('../lib/script');
describe('Identity', function() {
var pubkeyhash = new Buffer('3c3fa3d4adcaf8f52d5b1843975e122548269937', 'hex');
var buf = Buffer.concat([new Buffer([0]), pubkeyhash]);
var str = '16VZnHwRhwrExfeHFHGjwrgEMq8VcYPs9r';
it('should create a new identity object', function() {
var identity = new Identity();
should.exist(identity);
identity = Identity(buf);
should.exist(identity);
identity = Identity(str);
should.exist(identity);
});
describe('@isValid', function() {
it('should validate this valid identity string', function() {
Identity.isValid(str).should.equal(true);
});
it('should invalidate this valid identity string', function() {
Identity.isValid(str.substr(1)).should.equal(false);
});
});
describe('#fromBuffer', function() {
it('should make an identity from a buffer', function() {
Identity().fromBuffer(buf).toString().should.equal(str);
});
});
describe('#fromHashbuf', function() {
it('should make an identity from a hashbuf', function() {
Identity().fromHashbuf(pubkeyhash).toString().should.equal(str);
var a = Identity().fromHashbuf(pubkeyhash, 'testnet', 'scripthash');
a.networkstr.should.equal('testnet');
a.typestr.should.equal('scripthash');
});
it('should throw an error for invalid length hashbuf', function() {
(function() {
Identity().fromHashbuf(buf);
}).should.throw('hashbuf must be exactly 20 bytes');
});
});
describe('#fromPubkey', function() {
it('should make this identity from a compressed pubkey', function() {
var pubkey = new Pubkey();
pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
var identity = new Identity();
identity.fromPubkey(pubkey);
identity.toString().should.equal('19gH5uhqY6DKrtkU66PsZPUZdzTd11Y7ke');
});
it('should make this identity from an uncompressed pubkey', function() {
var pubkey = new Pubkey();
pubkey.fromDER(new Buffer('0285e9737a74c30a873f74df05124f2aa6f53042c2fc0a130d6cbd7d16b944b004', 'hex'));
var identity = new Identity();
pubkey.compressed = false;
identity.fromPubkey(pubkey, 'mainnet');
identity.toString().should.equal('16JXnhxjJUhxfyx4y6H4sFcxrgt8kQ8ewX');
});
});
describe('#fromScript', function() {
it('should make this identity from a script', function() {
var script = Script().fromString("OP_CHECKMULTISIG");
var identity = Identity().fromScript(script);
identity.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm');
});
it('should make this identity from other script', function() {
var script = Script().fromString("OP_CHECKSIG OP_HASH160");
var identity = Identity().fromScript(script);
identity.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7');
});
});
describe('#fromString', function() {
it('should derive from this known identity string mainnet', function() {
var identity = new Identity();
identity.fromString(str);
identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
});
it('should derive from this known identity string testnet', function() {
var identity = new Identity();
identity.fromString(str);
identity.networkstr = 'testnet';
identity.fromString(identity.toString());
identity.toString().should.equal('mm1X5M2QWyHVjn7txrF7mmtZDpjCXzoa98');
});
it('should derive from this known identity string mainnet scripthash', function() {
var identity = new Identity();
identity.fromString(str);
identity.networkstr = 'mainnet';
identity.typestr = 'scripthash';
identity.fromString(identity.toString());
identity.toString().should.equal('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
});
it('should derive from this known identity string testnet scripthash', function() {
var identity = new Identity();
identity.fromString(str);
identity.networkstr = 'testnet';
identity.typestr = 'scripthash';
identity.fromString(identity.toString());
identity.toString().should.equal('2MxjnmaMtsJfyFcyG3WZCzS2RihdNuWqeX4');
});
});
describe('#isValid', function() {
it('should describe this valid identity as valid', function() {
var identity = new Identity();
identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
identity.isValid().should.equal(true);
});
it('should describe this identity with unknown network as invalid', function() {
var identity = new Identity();
identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
identity.networkstr = 'unknown';
identity.isValid().should.equal(false);
});
it('should describe this identity with unknown type as invalid', function() {
var identity = new Identity();
identity.fromString('37BahqRsFrAd3qLiNNwLNV3AWMRD7itxTo');
identity.typestr = 'unknown';
identity.isValid().should.equal(false);
});
});
describe('#toBuffer', function() {
it('should output this known hash', function() {
var identity = new Identity();
identity.fromString(str);
identity.toBuffer().slice(1).toString('hex').should.equal(pubkeyhash.toString('hex'));
});
});
describe('#toString', function() {
it('should output the same thing that was input', function() {
var identity = new Identity();
identity.fromString(str);
identity.toString().should.equal(str);
});
});
describe('#validate', function() {
it('should not throw an error on this valid identity', function() {
var identity = new Identity();
identity.fromString(str);
should.exist(identity.validate());
});
it('should throw an error on this invalid network', function() {
var identity = new Identity();
identity.fromString(str);
identity.networkstr = 'unknown';
(function() {
identity.validate();
}).should.throw('networkstr must be "mainnet" or "testnet"');
});
it('should throw an error on this invalid type', function() {
var identity = new Identity();
identity.fromString(str);
identity.typestr = 'unknown';
(function() {
identity.validate();
}).should.throw('typestr must be "pubkeyhash" or "scripthash"');
});
});
});