UNPKG

syscointx-js

Version:

A transaction creation library interfacing with coin selection for Syscoin.

167 lines (148 loc) 4.34 kB
'use strict' Object.defineProperty(exports, '__esModule', { value: true }) const types = require('./types') const typeforce = require('typeforce') const varuint = require('varuint-bitcoin') // https://github.com/feross/buffer/blob/master/index.js#L1127 function verifuint (value, max) { if (typeof value !== 'number') { throw new Error('cannot write a non-number as a number') } if (value < 0) { throw new Error('specified a negative value for writing an unsigned value') } if (value > max) throw new Error('RangeError: value out of range') if (Math.floor(value) !== value) { throw new Error('value has a fractional component') } } function readUInt64LE (buffer, offset) { const a = buffer.readUInt32LE(offset) let b = buffer.readUInt32LE(offset + 4) b *= 0x100000000 verifuint(b + a, 0x001fffffffffffff) return b + a } exports.readUInt64LE = readUInt64LE function writeUInt64LE (buffer, value, offset) { verifuint(value, 0x001fffffffffffff) buffer.writeInt32LE(value & -1, offset) buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4) return offset + 8 } exports.writeUInt64LE = writeUInt64LE function reverseBuffer (buffer) { if (buffer.length < 1) return buffer let j = buffer.length - 1 let tmp = 0 for (let i = 0; i < buffer.length / 2; i++) { tmp = buffer[i] buffer[i] = buffer[j] buffer[j] = tmp j-- } return buffer } exports.reverseBuffer = reverseBuffer function cloneBuffer (buffer) { const clone = Buffer.alloc(buffer.length) buffer.copy(clone) return buffer } exports.cloneBuffer = cloneBuffer /** * Helper class for serialization of bitcoin data types into a pre-allocated buffer. */ class BufferWriter { constructor (buffer, offset = 0) { this.buffer = buffer this.offset = offset typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]) } writeUInt8 (i) { this.offset = this.buffer.writeUInt8(i, this.offset) } writeUInt16 (i) { this.offset = this.buffer.writeUInt16LE(i, this.offset) } writeInt32 (i) { this.offset = this.buffer.writeInt32LE(i, this.offset) } writeUInt32 (i) { this.offset = this.buffer.writeUInt32LE(i, this.offset) } writeUInt64 (i) { this.offset = writeUInt64LE(this.buffer, i, this.offset) } writeVarInt (i) { varuint.encode(i, this.buffer, this.offset) this.offset += varuint.encode.bytes } writeSlice (slice) { if (this.buffer.length < this.offset + slice.length) { throw new Error('Cannot write slice out of bounds') } this.offset += slice.copy(this.buffer, this.offset) } writeVarSlice (slice) { this.writeVarInt(slice.length) this.writeSlice(slice) } writeVector (vector) { this.writeVarInt(vector.length) vector.forEach(buf => this.writeVarSlice(buf)) } } exports.BufferWriter = BufferWriter /** * Helper class for reading of bitcoin data types from a buffer. */ class BufferReader { constructor (buffer, offset = 0) { this.buffer = buffer this.offset = offset typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]) } readUInt8 () { const result = this.buffer.readUInt8(this.offset) this.offset++ return result } readUInt16 () { const result = this.buffer.readUInt16LE(this.offset) this.offset += 2 return result } readInt32 () { const result = this.buffer.readInt32LE(this.offset) this.offset += 4 return result } readUInt32 () { const result = this.buffer.readUInt32LE(this.offset) this.offset += 4 return result } readUInt64 () { const result = readUInt64LE(this.buffer, this.offset) this.offset += 8 return result } readVarInt () { const vi = varuint.decode(this.buffer, this.offset) this.offset += varuint.decode.bytes return vi } readSlice (n) { if (this.buffer.length < this.offset + n) { throw new Error('Cannot read slice out of bounds') } const result = this.buffer.slice(this.offset, this.offset + n) this.offset += n return result } readVarSlice () { return this.readSlice(this.readVarInt()) } readVector () { const count = this.readVarInt() const vector = [] for (let i = 0; i < count; i++) vector.push(this.readVarSlice()) return vector } } exports.BufferReader = BufferReader