UNPKG

@vbyte/btc-dev

Version:

Batteries-included toolset for plebian bitcoin development

81 lines (80 loc) 2.4 kB
import { Buff, Stream } from '@vbyte/buff'; import { get_asm_code, } from './words.js'; const MAX_WORD_SIZE = 520; export function encode_script(words, varint = false) { if (words.length === 0) return Buff.num(0, 1); const bytes = []; for (const word of words) { bytes.push(encode_script_word(word)); } const buffer = Buff.join(bytes); return (varint) ? buffer.prepend(Buff.varint(buffer.length, 'le')) : buffer; } export function encode_script_word(word) { let buff; if (typeof (word) === 'string') { if (word.startsWith('OP_')) { const asm_code = get_asm_code(word); return Buff.num(asm_code, 1); } else if (Buff.is_hex(word)) { buff = Buff.hex(word); } else { buff = Buff.str(word); } } else if (typeof (word) === 'number') { buff = Buff.num(word); } else if (word instanceof Uint8Array) { buff = new Buff(word); } else { throw new Error('invalid word type:' + typeof (word)); } if (buff.length === 1 && buff[0] <= 16) { if (buff[0] !== 0) buff[0] += 0x50; } else if (buff.length > MAX_WORD_SIZE) { let words; words = split_script_word(buff); words = words.map(e => prefix_word_size(e)); buff = Buff.join(words); } else { buff = prefix_word_size(buff); } return buff; } export function split_script_word(word) { const words = []; const buff = new Stream(word); while (buff.size > MAX_WORD_SIZE) { words.push(buff.read(MAX_WORD_SIZE)); } words.push(buff.read(buff.size)); return words; } export function prefix_word_size(word) { const varint = get_size_varint(word.length); return Buff.join([varint, word]); } export function get_size_varint(size) { const OP_PUSHDATA1 = Buff.num(0x4c, 1); const OP_PUSHDATA2 = Buff.num(0x4d, 1); switch (true) { case (size <= 0x4b): return Buff.num(size); case (size > 0x4b && size < 0x100): return Buff.join([OP_PUSHDATA1, Buff.num(size, 1, 'le')]); case (size >= 0x100 && size <= MAX_WORD_SIZE): return Buff.join([OP_PUSHDATA2, Buff.num(size, 2, 'le')]); default: throw new Error('Invalid word size:' + size.toString()); } }