Completely rewrote convertScriptSigAsm
it now gives identical output to esplora, tested with the following TXs (testnet): 88710a9a6751827490f260e307757543f533c0f18bcd6865794713d263d5f5a4 446b2aad074de94efa28a1e82d2e6016dcb8a8ca38aca1a5a8eac6ef54e56a2e 4cfc410092e9514c14f48b61e20d2d3baf540ae7e981a821dd8c05dd4b7cd591 4b55dde38173174ab09e5571ebffffca798ba11143d28b9770600ff376dc778a
This commit is contained in:
		
							parent
							
								
									ba92284e44
								
							
						
					
					
						commit
						dfb5ba5c36
					
				@ -147,7 +147,7 @@ class BitcoinApi implements AbstractBitcoinApi {
 | 
			
		||||
        scriptpubkey: vout.scriptPubKey.hex,
 | 
			
		||||
        scriptpubkey_address: vout.scriptPubKey && vout.scriptPubKey.address ? vout.scriptPubKey.address
 | 
			
		||||
          : vout.scriptPubKey.addresses ? vout.scriptPubKey.addresses[0] : '',
 | 
			
		||||
        scriptpubkey_asm: vout.scriptPubKey.asm ? this.convertScriptSigAsm(vout.scriptPubKey.asm) : '',
 | 
			
		||||
        scriptpubkey_asm: vout.scriptPubKey.asm ? this.convertScriptSigAsm(vout.scriptPubKey.hex) : '',
 | 
			
		||||
        scriptpubkey_type: this.translateScriptPubKeyType(vout.scriptPubKey.type),
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
@ -157,7 +157,7 @@ class BitcoinApi implements AbstractBitcoinApi {
 | 
			
		||||
        is_coinbase: !!vin.coinbase,
 | 
			
		||||
        prevout: null,
 | 
			
		||||
        scriptsig: vin.scriptSig && vin.scriptSig.hex || vin.coinbase || '',
 | 
			
		||||
        scriptsig_asm: vin.scriptSig && this.convertScriptSigAsm(vin.scriptSig.asm) || '',
 | 
			
		||||
        scriptsig_asm: vin.scriptSig && this.convertScriptSigAsm(vin.scriptSig.hex) || '',
 | 
			
		||||
        sequence: vin.sequence,
 | 
			
		||||
        txid: vin.txid || '',
 | 
			
		||||
        vout: vin.vout || 0,
 | 
			
		||||
@ -290,38 +290,61 @@ class BitcoinApi implements AbstractBitcoinApi {
 | 
			
		||||
    return transaction;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private convertScriptSigAsm(str: string): string {
 | 
			
		||||
    const a = str.split(' ');
 | 
			
		||||
  private convertScriptSigAsm(hex: string): string {
 | 
			
		||||
    const buf = Buffer.from(hex, 'hex');
 | 
			
		||||
 | 
			
		||||
    const b: string[] = [];
 | 
			
		||||
    a.forEach((chunk) => {
 | 
			
		||||
      if (chunk.substr(0, 3) === 'OP_') {
 | 
			
		||||
        chunk = chunk.replace(/^OP_(\d+)$/, 'OP_PUSHNUM_$1');
 | 
			
		||||
        chunk = chunk.replace('OP_CHECKSEQUENCEVERIFY', 'OP_CSV');
 | 
			
		||||
        chunk = chunk.replace('OP_CHECKLOCKTIMEVERIFY', 'OP_CLTV');
 | 
			
		||||
        b.push(chunk);
 | 
			
		||||
 | 
			
		||||
    let i = 0;
 | 
			
		||||
    while (i < buf.length) {
 | 
			
		||||
      const op = buf[i];
 | 
			
		||||
      if (op >= 0x01 && op <= 0x4e) {
 | 
			
		||||
        i++;
 | 
			
		||||
        let push: number;
 | 
			
		||||
        if (op === 0x4c) {
 | 
			
		||||
          push = buf.readUInt8(i);
 | 
			
		||||
          b.push('OP_PUSHDATA1');
 | 
			
		||||
          i += 1;
 | 
			
		||||
        } else if (op === 0x4d) {
 | 
			
		||||
          push = buf.readUInt16LE(i);
 | 
			
		||||
          b.push('OP_PUSHDATA2');
 | 
			
		||||
          i += 2;
 | 
			
		||||
        } else if (op === 0x4e) {
 | 
			
		||||
          push = buf.readUInt32LE(i);
 | 
			
		||||
          b.push('OP_PUSHDATA4');
 | 
			
		||||
          i += 4;
 | 
			
		||||
        } else {
 | 
			
		||||
          push = op;
 | 
			
		||||
          b.push('OP_PUSHBYTES_' + push);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const data = buf.slice(i, i + push);
 | 
			
		||||
        if (data.length !== push) {
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        b.push(data.toString('hex'));
 | 
			
		||||
        i += data.length;
 | 
			
		||||
      } else {
 | 
			
		||||
        chunk = chunk.replace('[ALL]', '01');
 | 
			
		||||
        if (chunk === '0') {
 | 
			
		||||
          b.push('OP_0');
 | 
			
		||||
        } else if (chunk.match(/^[^0]\d*$/)) {
 | 
			
		||||
          const chunkInt = parseInt(chunk, 10);
 | 
			
		||||
          if (chunkInt < 0) {
 | 
			
		||||
            b.push('OP_PUSHNUM_NEG' + -chunkInt);
 | 
			
		||||
        const opcode = bitcoinjs.script.toASM([ op ]);
 | 
			
		||||
        if (opcode && op < 0xfd) {
 | 
			
		||||
          if (opcode === 'OP_1NEGATE') {
 | 
			
		||||
            b.push('OP_PUSHNUM_NEG1');
 | 
			
		||||
          } else if (/^OP_(\d+)$/.test(opcode) && opcode !== 'OP_0') {
 | 
			
		||||
            b.push(opcode.replace(/^OP_(\d+)$/, 'OP_PUSHNUM_$1'));
 | 
			
		||||
          } else {
 | 
			
		||||
            b.push('OP_PUSHNUM_' + chunk);
 | 
			
		||||
            b.push(opcode
 | 
			
		||||
              .replace('OP_CHECKSEQUENCEVERIFY', 'OP_CSV')
 | 
			
		||||
              .replace('OP_CHECKLOCKTIMEVERIFY', 'OP_CLTV')
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          const dataLength = Math.round(chunk.length / 2);
 | 
			
		||||
          if (dataLength > 255) {
 | 
			
		||||
            b.push('OP_PUSHDATA2' + ' ' + chunk);
 | 
			
		||||
          } else if (dataLength > 75) {
 | 
			
		||||
            b.push('OP_PUSHDATA1' + ' ' + chunk);
 | 
			
		||||
          } else {
 | 
			
		||||
            b.push('OP_PUSHBYTES_' + dataLength + ' ' + chunk);
 | 
			
		||||
          }
 | 
			
		||||
          b.push('OP_RETURN_' + op);
 | 
			
		||||
        }
 | 
			
		||||
        i += 1;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return b.join(' ');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -332,21 +355,21 @@ class BitcoinApi implements AbstractBitcoinApi {
 | 
			
		||||
 | 
			
		||||
    if (vin.prevout.scriptpubkey_type === 'p2sh') {
 | 
			
		||||
      const redeemScript = vin.scriptsig_asm.split(' ').reverse()[0];
 | 
			
		||||
      vin.inner_redeemscript_asm = this.convertScriptSigAsm(bitcoinjs.script.toASM(Buffer.from(redeemScript, 'hex')));
 | 
			
		||||
      vin.inner_redeemscript_asm = this.convertScriptSigAsm(redeemScript);
 | 
			
		||||
      if (vin.witness && vin.witness.length > 2) {
 | 
			
		||||
        const witnessScript = vin.witness[vin.witness.length - 1];
 | 
			
		||||
        vin.inner_witnessscript_asm = this.convertScriptSigAsm(bitcoinjs.script.toASM(Buffer.from(witnessScript, 'hex')));
 | 
			
		||||
        vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (vin.prevout.scriptpubkey_type === 'v0_p2wsh' && vin.witness) {
 | 
			
		||||
      const witnessScript = vin.witness[vin.witness.length - 1];
 | 
			
		||||
      vin.inner_witnessscript_asm = this.convertScriptSigAsm(bitcoinjs.script.toASM(Buffer.from(witnessScript, 'hex')));
 | 
			
		||||
      vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (vin.prevout.scriptpubkey_type === 'v1_p2tr' && vin.witness && vin.witness.length > 1) {
 | 
			
		||||
      const witnessScript = vin.witness[vin.witness.length - 2];
 | 
			
		||||
      vin.inner_witnessscript_asm = this.convertScriptSigAsm(bitcoinjs.script.toASM(Buffer.from(witnessScript, 'hex')));
 | 
			
		||||
      vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user