bitcoin-util
Advanced tools
Comparing version 1.0.0 to 2.0.0
42
index.js
@@ -7,4 +7,5 @@ var buffertools | ||
} | ||
var BN = require('bn.js') | ||
var nullHash = new Buffer('0000000000000000000000000000000000000000000000000000000000000000', 'hex') | ||
function isHexString (str) { | ||
@@ -22,23 +23,15 @@ return !(typeof str !== 'string' || str.length === 0 || str.length % 2) | ||
function compressTarget (target) { | ||
if (!target.bitLength) { | ||
// if target is not a BN | ||
if (Buffer.isBuffer(target)) { | ||
// target is Buffer | ||
target = new BN(target.toString('hex'), 16) | ||
} else if (isHexString(target)) { | ||
// target is hex string | ||
var buf = new Buffer(target, 'hex') | ||
buf = buffertools.reverse(buf) | ||
target = new BN(buf.toString('hex'), 16) | ||
} else { | ||
throw new Error('target must be of type "BN" (from bn.js package), "Buffer", or a hex string') | ||
} | ||
if (!Buffer.isBuffer(target)) { | ||
throw new Error('target must be a "Buffer"') | ||
} | ||
if (target.length !== 32) { | ||
throw new Error('target must be 32 bytes long') | ||
} | ||
var nBits = target.bitLength() | ||
var targetString = target.toString(16) | ||
var exponent = Math.ceil(nBits / 8) | ||
if (targetString.length % 2 === 1) targetString = '0' + targetString | ||
var mantissa = Number.parseInt(targetString.substr(0, 6), 16) | ||
if (mantissa & 0x800000) { | ||
for (var i = 0; i < 29; i++) { | ||
if (target[i]) break | ||
} | ||
var exponent = 32 - i | ||
var mantissa = target.readUInt32BE(i) >> 8 & 0x00ffffff | ||
if (mantissa & 0x00800000) { | ||
mantissa >>= 8 | ||
@@ -54,6 +47,8 @@ exponent++ | ||
} | ||
var exponent = bits >>> 24 | ||
if (exponent <= 3) throw new Error('target exponent must be > 3') | ||
if (exponent > 32) throw new Error('target exponent must be < 32') | ||
var mantissa = bits & 0x007fffff | ||
var exponent = ((bits >>> 24) * 8) - 24 | ||
exponent = Math.max(exponent, 0) | ||
var target = (new BN(mantissa)).iushln(exponent) | ||
var target = new Buffer(32).fill(0) | ||
target.writeUInt32BE(mantissa << 8, 32 - exponent) | ||
return target | ||
@@ -63,2 +58,3 @@ } | ||
module.exports = { | ||
nullHash: nullHash, | ||
toHash: toHash, | ||
@@ -65,0 +61,0 @@ compressTarget: compressTarget, |
{ | ||
"name": "bitcoin-util", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "Utility functions for Bitcoin hashes and targets", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -17,10 +17,10 @@ # bitcoin-util | ||
Takes a hex string that contains a Bitcoin hash as input, and returns a Bitcoin-protocol-friendly Big-endian Buffer. Throws an error if the hex string is not of length 64 (representing a 256-bit hash). | ||
Takes a hex string that contains a Bitcoin hash as input, and returns a Bitcoin-protocol-friendly little-endian Buffer. Throws an error if the hex string is not of length 64 (representing a 256-bit hash). | ||
#### `toCompactTarget(n)` | ||
#### `compressTarget(target)` | ||
Converts the difficulty target `n` to its compact representation (used in the "bits" field in block headers). `n` can be a `Buffer`, hex string, or `BN` (from the [`bn.js`](https://github.com/indutny/bn.js) package). | ||
Converts the difficulty target `target` to its compact representation (used in the "bits" field in block headers). `target` should be a `Buffer` (little-endian, the zeroes should be at the end). Returns a `number`. | ||
## NOTE | ||
#### `expandTarget(bits)` | ||
`bitcoin-util` uses the [`buffertools`](https://github.com/bnoordhuis/node-buffertools) package as a dependency, which is a compiled native module. When browserifying, the [`browserify-buffertools`](https://github.com/maraoz/browserify-buffertools) package will be used instead (to keep browser compatibility). | ||
Converts the compressed target integer `bits` to its target hash representation. Returns a `Buffer`. |
116
test.js
var test = require('tap').test | ||
var BN = require('bn.js') | ||
var u = require('./') | ||
var buffertools | ||
try { | ||
buffertools = require('buffertools') | ||
} catch (e) { | ||
buffertools = require('browserify-buffertools') | ||
} | ||
test('toHash', function (t) { | ||
@@ -23,35 +15,28 @@ t.throws(function () { u.toHash('012345') }, 'throws for invalid hash length') | ||
var targets = [ | ||
{ | ||
compact: 0x1d00ffff, | ||
expanded: '00000000ffff0000000000000000000000000000000000000000000000000000' | ||
}, | ||
{ | ||
compact: 0x04054321, | ||
expanded: '0000000000000000000000000000000000000000000000000000000005432100' | ||
}, | ||
{ | ||
compact: 0x04123456, | ||
expanded: '0000000000000000000000000000000000000000000000000000000012345600' | ||
}, | ||
{ | ||
compact: 0x05009234, | ||
expanded: '0000000000000000000000000000000000000000000000000000000092340000' | ||
}, | ||
{ | ||
compact: 0x20123456, | ||
expanded: '1234560000000000000000000000000000000000000000000000000000000000' | ||
} | ||
] | ||
test('compressTarget', function (t) { | ||
var targets = [ | ||
{ | ||
hex: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', | ||
compact: 0x2200ffff | ||
}, | ||
{ | ||
hex: 'ffff0000000000000000000000000000000000000000000000000000', | ||
compact: 0x1d00ffff | ||
}, | ||
{ | ||
hex: 'ffff0000000000000000000000000000000000000000000000000001', | ||
compact: 0x1d00ffff | ||
}, | ||
{ | ||
hex: '7fff0000000000000000000000000000000000000000000000000000', | ||
compact: 0x1c7fff00 | ||
}, | ||
{ | ||
hex: '00', | ||
compact: 0 | ||
} | ||
] | ||
t.test('bn.js', function (t) { | ||
t.test('compress targets', function (t) { | ||
targets.forEach(function (target) { | ||
var bn = new BN(target.hex, 'hex') | ||
t.equal(u.compressTarget(bn), target.compact, target) | ||
}) | ||
t.end() | ||
}) | ||
t.test('Buffer', function (t) { | ||
targets.forEach(function (target) { | ||
var buf = new Buffer(target.hex, 'hex') | ||
var buf = new Buffer(target.expanded, 'hex') | ||
t.equal(u.compressTarget(buf), target.compact, target) | ||
@@ -61,13 +46,11 @@ }) | ||
}) | ||
t.test('hex string', function (t) { | ||
targets.forEach(function (target) { | ||
var reversed = new Buffer(target.hex, 'hex') | ||
reversed = buffertools.reverse(reversed).toString('hex') | ||
t.equal(u.compressTarget(reversed), target.compact, target) | ||
t.test('invalid type', function (t) { | ||
t.throws(function () { | ||
u.compressTarget(123) | ||
}) | ||
t.end() | ||
}) | ||
t.test('invalid type', function (t) { | ||
t.test('invalid length', function (t) { | ||
t.throws(function () { | ||
u.compressTarget(123) | ||
u.compressTarget(new Buffer('test')) | ||
}) | ||
@@ -80,27 +63,24 @@ t.end() | ||
test('expandTarget', function (t) { | ||
var targets = [ | ||
{ | ||
hex: 'ffff0000000000000000000000000000000000000000000000000000', | ||
compact: 0x1d00ffff | ||
}, | ||
{ | ||
hex: '7fff0000000000000000000000000000000000000000000000000000', | ||
compact: 0x1c7fff00 | ||
}, | ||
{ | ||
hex: '9b31b000000000000000000000000000000000000000000', | ||
compact: 0x1809b31b | ||
}, | ||
{ | ||
hex: '0', | ||
compact: 0 | ||
} | ||
] | ||
targets.forEach(function (target) { | ||
t.equal(u.expandTarget(target.compact).toString('hex'), target.hex, target) | ||
t.test('matches expected target', function (t) { | ||
targets.forEach(function (target) { | ||
t.equal(u.expandTarget(target.compact).toString('hex'), target.expanded, target) | ||
}) | ||
t.end() | ||
}) | ||
t.throws(function () { | ||
u.expandTarget(0xff00ff00ff) | ||
t.test('invalid length', function (t) { | ||
t.throws(function () { | ||
u.expandTarget(0xff00ff00ff) | ||
}) | ||
t.end() | ||
}) | ||
t.test('invalid exponent', function (t) { | ||
t.throws(function () { | ||
u.expandTarget(0x00ffffff) | ||
}) | ||
t.throws(function () { | ||
u.expandTarget(0xffffffff) | ||
}) | ||
t.end() | ||
}) | ||
t.end() | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
5706
132