Fixed script, script number and signature
This commit is contained in:
parent
fce08352f5
commit
3b77caa4f1
3 changed files with 47 additions and 56 deletions
|
@ -10,37 +10,49 @@ const OPS = require('bitcoin-ops')
|
|||
const REVERSE_OPS = require('bitcoin-ops/map')
|
||||
const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
|
||||
|
||||
function isOPInt (value) {
|
||||
function isOPInt (value:number): boolean {
|
||||
return types.Number(value) &&
|
||||
((value === OPS.OP_0) ||
|
||||
(value >= OPS.OP_1 && value <= OPS.OP_16) ||
|
||||
(value === OPS.OP_1NEGATE))
|
||||
}
|
||||
|
||||
function isPushOnlyChunk (value) {
|
||||
return types.Buffer(value) || isOPInt(value)
|
||||
function isPushOnlyChunk (value: number | Buffer): boolean {
|
||||
return types.Buffer(value) || isOPInt(<number>value)
|
||||
}
|
||||
|
||||
function isPushOnly (value) {
|
||||
export function isPushOnly (value: Array<number | Buffer>) {
|
||||
return types.Array(value) && value.every(isPushOnlyChunk)
|
||||
}
|
||||
|
||||
function asMinimalOP (buffer) {
|
||||
function asMinimalOP (buffer: Buffer): number | void {
|
||||
if (buffer.length === 0) return OPS.OP_0
|
||||
if (buffer.length !== 1) return
|
||||
if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0]
|
||||
if (buffer[0] === 0x81) return OPS.OP_1NEGATE
|
||||
}
|
||||
|
||||
function compile (chunks) {
|
||||
function chunksIsBuffer(buf: Buffer | Array<number | Buffer>): buf is Buffer {
|
||||
return Buffer.isBuffer(buf)
|
||||
}
|
||||
|
||||
function chunksIsArray(buf: Buffer | Array<number | Buffer>): buf is Array<number | Buffer> {
|
||||
return types.Array(buf)
|
||||
}
|
||||
|
||||
function singleChunkIsBuffer(buf: number | Buffer): buf is Buffer {
|
||||
return Buffer.isBuffer(buf)
|
||||
}
|
||||
|
||||
export function compile (chunks: Buffer | Array<number | Buffer>): Buffer {
|
||||
// TODO: remove me
|
||||
if (Buffer.isBuffer(chunks)) return chunks
|
||||
if (chunksIsBuffer(chunks)) return chunks
|
||||
|
||||
typeforce(types.Array, chunks)
|
||||
|
||||
const bufferSize = chunks.reduce(function (accum, chunk) {
|
||||
const bufferSize = chunks.reduce(function (accum: number, chunk) {
|
||||
// data chunk
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
if (singleChunkIsBuffer(chunk)) {
|
||||
// adhere to BIP62.3, minimal push policy
|
||||
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
|
||||
return accum + 1
|
||||
|
@ -58,7 +70,7 @@ function compile (chunks) {
|
|||
|
||||
chunks.forEach(function (chunk) {
|
||||
// data chunk
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
if (singleChunkIsBuffer(chunk)) {
|
||||
// adhere to BIP62.3, minimal push policy
|
||||
const opcode = asMinimalOP(chunk)
|
||||
if (opcode !== undefined) {
|
||||
|
@ -82,9 +94,9 @@ function compile (chunks) {
|
|||
return buffer
|
||||
}
|
||||
|
||||
function decompile (buffer) {
|
||||
export function decompile (buffer: Buffer | Array<number | Buffer>): Array<number | Buffer> {
|
||||
// TODO: remove me
|
||||
if (types.Array(buffer)) return buffer
|
||||
if (chunksIsArray(buffer)) return buffer
|
||||
|
||||
typeforce(types.Buffer, buffer)
|
||||
|
||||
|
@ -127,17 +139,17 @@ function decompile (buffer) {
|
|||
return chunks
|
||||
}
|
||||
|
||||
function toASM (chunks) {
|
||||
if (Buffer.isBuffer(chunks)) {
|
||||
export function toASM (chunks: Buffer | Array<number | Buffer>): string {
|
||||
if (chunksIsBuffer(chunks)) {
|
||||
chunks = decompile(chunks)
|
||||
}
|
||||
|
||||
return chunks.map(function (chunk) {
|
||||
// data?
|
||||
if (Buffer.isBuffer(chunk)) {
|
||||
if (singleChunkIsBuffer(chunk)) {
|
||||
const op = asMinimalOP(chunk)
|
||||
if (op === undefined) return chunk.toString('hex')
|
||||
chunk = op
|
||||
chunk = <number>op
|
||||
}
|
||||
|
||||
// opcode!
|
||||
|
@ -145,7 +157,7 @@ function toASM (chunks) {
|
|||
}).join(' ')
|
||||
}
|
||||
|
||||
function fromASM (asm) {
|
||||
export function fromASM (asm: string): Buffer {
|
||||
typeforce(types.String, asm)
|
||||
|
||||
return compile(asm.split(' ').map(function (chunkStr) {
|
||||
|
@ -158,49 +170,35 @@ function fromASM (asm) {
|
|||
}))
|
||||
}
|
||||
|
||||
function toStack (chunks) {
|
||||
export function toStack (chunks: Buffer | Array<number | Buffer>): Array<Buffer> {
|
||||
chunks = decompile(chunks)
|
||||
typeforce(isPushOnly, chunks)
|
||||
|
||||
return chunks.map(function (op) {
|
||||
if (Buffer.isBuffer(op)) return op
|
||||
if (singleChunkIsBuffer(op)) return op
|
||||
if (op === OPS.OP_0) return Buffer.allocUnsafe(0)
|
||||
|
||||
return scriptNumber.encode(op - OP_INT_BASE)
|
||||
})
|
||||
}
|
||||
|
||||
function isCanonicalPubKey (buffer) {
|
||||
export function isCanonicalPubKey (buffer: Buffer): boolean {
|
||||
return ecc.isPoint(buffer)
|
||||
}
|
||||
|
||||
function isDefinedHashType (hashType) {
|
||||
export function isDefinedHashType (hashType: number): boolean {
|
||||
const hashTypeMod = hashType & ~0x80
|
||||
|
||||
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
|
||||
return hashTypeMod > 0x00 && hashTypeMod < 0x04
|
||||
}
|
||||
|
||||
function isCanonicalScriptSignature (buffer) {
|
||||
export function isCanonicalScriptSignature (buffer: Buffer): boolean {
|
||||
if (!Buffer.isBuffer(buffer)) return false
|
||||
if (!isDefinedHashType(buffer[buffer.length - 1])) return false
|
||||
|
||||
return bip66.check(buffer.slice(0, -1))
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compile: compile,
|
||||
decompile: decompile,
|
||||
fromASM: fromASM,
|
||||
toASM: toASM,
|
||||
toStack: toStack,
|
||||
|
||||
number: require('./script_number'),
|
||||
signature: require('./script_signature'),
|
||||
|
||||
isCanonicalPubKey: isCanonicalPubKey,
|
||||
isCanonicalScriptSignature: isCanonicalScriptSignature,
|
||||
isPushOnly: isPushOnly,
|
||||
isDefinedHashType: isDefinedHashType
|
||||
}
|
||||
export {}
|
||||
export const number = require('./script_number')
|
||||
export const signature = require('./script_signature')
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const Buffer = require('safe-buffer').Buffer
|
||||
|
||||
function decode (buffer, maxLength, minimal) {
|
||||
export function decode (buffer: Buffer, maxLength?: number, minimal?: boolean): number {
|
||||
maxLength = maxLength || 4
|
||||
minimal = minimal === undefined ? true : minimal
|
||||
|
||||
|
@ -41,7 +41,7 @@ function scriptNumSize (i) {
|
|||
: 0
|
||||
}
|
||||
|
||||
function encode (number) {
|
||||
export function encode (number: number): Buffer {
|
||||
let value = Math.abs(number)
|
||||
const size = scriptNumSize(value)
|
||||
const buffer = Buffer.allocUnsafe(size)
|
||||
|
@ -60,9 +60,3 @@ function encode (number) {
|
|||
|
||||
return buffer
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
decode: decode,
|
||||
encode: encode
|
||||
}
|
||||
export {}
|
||||
|
|
|
@ -4,7 +4,7 @@ const typeforce = require('typeforce')
|
|||
const types = require('./types')
|
||||
|
||||
const ZERO = Buffer.alloc(1, 0)
|
||||
function toDER (x) {
|
||||
function toDER (x: Buffer): Buffer {
|
||||
let i = 0
|
||||
while (x[i] === 0) ++i
|
||||
if (i === x.length) return ZERO
|
||||
|
@ -13,7 +13,7 @@ function toDER (x) {
|
|||
return x
|
||||
}
|
||||
|
||||
function fromDER (x) {
|
||||
function fromDER (x: Buffer): Buffer {
|
||||
if (x[0] === 0x00) x = x.slice(1)
|
||||
const buffer = Buffer.alloc(32, 0)
|
||||
const bstart = Math.max(0, 32 - x.length)
|
||||
|
@ -21,8 +21,13 @@ function fromDER (x) {
|
|||
return buffer
|
||||
}
|
||||
|
||||
interface ScriptSignature {
|
||||
signature: Buffer
|
||||
hashType: number
|
||||
}
|
||||
|
||||
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
|
||||
function decode (buffer) {
|
||||
export function decode (buffer: Buffer): ScriptSignature {
|
||||
const hashType = buffer.readUInt8(buffer.length - 1)
|
||||
const hashTypeMod = hashType & ~0x80
|
||||
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
|
||||
|
@ -37,7 +42,7 @@ function decode (buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
function encode (signature, hashType) {
|
||||
export function encode (signature: Buffer, hashType: number): Buffer {
|
||||
typeforce({
|
||||
signature: types.BufferN(64),
|
||||
hashType: types.UInt8
|
||||
|
@ -57,9 +62,3 @@ function encode (signature, hashType) {
|
|||
hashTypeBuffer
|
||||
])
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
decode: decode,
|
||||
encode: encode
|
||||
}
|
||||
export {}
|
||||
|
|
Loading…
Add table
Reference in a new issue