PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-bin/src/commands
Просмотр файла: cmdParseTx.ts
import * as utxolib from '@bitgo/utxo-lib';
import * as yargs from 'yargs';
import {
argToString,
formatTreeOrJson,
getNetworkOptionsDemand,
FormatTreeOrJson,
ReadStringOptions,
readStringOptions,
stringToBuffer,
} from '../args';
import { TxParser, TxParserArgs } from '../TxParser';
import {
fetchOutputSpends,
fetchPrevOutputs,
fetchPrevOutputSpends,
fetchTransactionHex,
fetchTransactionStatus,
getClient,
} from '../fetch';
import { getParserTxProperties } from '../ParserTx';
import { parseUnknown } from '../parseUnknown';
import { Parser } from '../Parser';
import { formatString } from './formatString';
export type ArgsParseTransaction = ReadStringOptions & {
network: utxolib.Network;
txid?: string;
blockHeight?: number;
txIndex?: number;
all: boolean;
cache: boolean;
format: FormatTreeOrJson;
fetchAll: boolean;
fetchStatus: boolean;
fetchInputs: boolean;
fetchSpends: boolean;
finalize: boolean;
parseSignatureData: boolean;
parseAsUnknown: boolean;
parseError: 'throw' | 'continue';
} & Omit<TxParserArgs, 'parseSignatureData'>;
export function getTxParser(argv: ArgsParseTransaction): TxParser {
if (argv.all) {
return new TxParser({ ...argv, ...TxParser.PARSE_ALL });
}
return new TxParser({
...argv,
parseSignatureData: {
script: argv.parseSignatureData,
ecdsa: argv.parseSignatureData,
schnorr: argv.parseSignatureData,
},
});
}
export const cmdParseTx = {
command: 'parseTx [path]',
aliases: ['parse', 'tx'],
describe:
'Display transaction components in human-readable form. ' +
'Supported formats are Partially Signed Bitcoin Transaction (PSBT), ' +
'bitcoinjs-lib encoding (Legacy) or fully signed transaction. ' +
'Bytes must be encoded in hex or base64 format.',
builder(b: yargs.Argv<unknown>): yargs.Argv<ArgsParseTransaction> {
return b
.options(readStringOptions)
.options(getNetworkOptionsDemand())
.option('txid', { type: 'string' })
.option('blockHeight', { type: 'number' })
.option('txIndex', { type: 'number' })
.option('fetchAll', { type: 'boolean', default: false })
.option('fetchStatus', { type: 'boolean', default: false })
.option('fetchInputs', { type: 'boolean', default: false })
.option('fetchSpends', { type: 'boolean', default: false })
.option('parseScriptAsm', { alias: 'scriptasm', type: 'boolean', default: false })
.option('parseScriptData', { alias: 'scriptdata', type: 'boolean', default: false })
.option('parseSignatureData', { alias: 'sigdata', type: 'boolean', default: false })
.option('parseOutputScript', { type: 'boolean', default: false })
.option('parseAsUnknown', {
type: 'boolean',
default: false,
description: 'show plain Javascript object without any post-processing',
})
.option('maxOutputs', { type: 'number' })
.option('vin', { type: 'number' })
.array('vin')
.option('vout', { type: 'number' })
.array('vout')
.option('finalize', {
type: 'boolean',
default: false,
description: 'finalize PSBT and parse result instead of PSBT',
})
.option('all', { type: 'boolean', default: false })
.option('cache', {
type: 'boolean',
default: false,
description: 'use local cache for http responses',
})
.option('format', formatTreeOrJson)
.option('parseError', { choices: ['continue', 'throw'], default: 'continue' } as const);
},
async handler(argv: yargs.Arguments<ArgsParseTransaction>): Promise<void> {
let data;
const httpClient = await getClient({ cache: argv.cache });
if (argv.txid || argv.blockHeight !== undefined || argv.txIndex !== undefined) {
data = await fetchTransactionHex(
httpClient,
{
txid: argv.txid,
blockHeight: argv.blockHeight,
txIndex: argv.txIndex,
},
argv.network
);
}
const string = await argToString(argv, data);
if (!string) {
throw new Error(`no txdata`);
}
const bytes = stringToBuffer(string, ['hex', 'base64']);
let tx = utxolib.bitgo.isPsbt(bytes)
? utxolib.bitgo.createPsbtFromBuffer(bytes, argv.network)
: utxolib.bitgo.createTransactionFromBuffer(bytes, argv.network, { amountType: 'bigint' });
const { id: txid } = getParserTxProperties(tx, undefined);
if (tx instanceof utxolib.bitgo.UtxoTransaction) {
if (argv.txid && txid !== argv.txid) {
throw new Error(`computed txid does not match txid argument`);
}
} else if (argv.finalize) {
tx.finalizeAllInputs();
tx = tx.extractTransaction();
}
if (argv.parseAsUnknown) {
console.log(formatString(parseUnknown(new Parser(), 'tx', tx), argv));
return;
}
if (argv.fetchAll) {
argv.fetchStatus = true;
argv.fetchInputs = true;
argv.fetchSpends = true;
}
const parsed = getTxParser(argv).parse(tx, {
status: argv.fetchStatus && txid ? await fetchTransactionStatus(httpClient, txid, argv.network) : undefined,
prevOutputs: argv.fetchInputs ? await fetchPrevOutputs(httpClient, tx) : undefined,
prevOutputSpends: argv.fetchSpends ? await fetchPrevOutputSpends(httpClient, tx) : undefined,
outputSpends:
argv.fetchSpends && tx instanceof utxolib.bitgo.UtxoTransaction
? await fetchOutputSpends(httpClient, tx)
: undefined,
});
console.log(formatString(parsed, argv));
},
} as const;
Выполнить команду
Для локальной разработки. Не используйте в интернете!