PHP WebShell
Текущая директория: /opt/BitGoJS/modules/utxo-lib/src/bitgo/bitcoincash
Просмотр файла: address.ts
/**
* Wrapper around `cashaddress` library.
*
* Performs some address sanitation:
* - add prefix if missing
* - normalize to lower-case
* - reject mixed-case
*
* Based on these documents
*
* - https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
* - https://www.bitcoinabc.org/cashaddr/
*/
import * as cashaddress from 'cashaddress';
import * as bitcoinjs from 'bitcoinjs-lib';
import { getNetworkName, isBitcoinCash, isECash, Network, networks } from '../../networks';
import { AddressFormat } from '../../addressFormat';
/**
* @param name
* @param output
* @return the encoded pubkeyhash or scripthash
*/
function getHashFromOutputScript(name: string, output: Buffer): Buffer | undefined {
type PaymentFunc = ({ output }: { output: Buffer }) => bitcoinjs.Payment;
const func = (bitcoinjs.payments as unknown as Record<string, PaymentFunc>)[name];
if (!func) {
throw new Error(`no payment with name ${name}`);
}
try {
return func({ output }).hash;
} catch (e) {
return undefined;
}
}
/**
* @param network
* @return network-specific cashaddr prefix
*/
export function getPrefix(network: Network): string {
switch (network) {
case networks.bitcoincash:
return 'bitcoincash';
case networks.bitcoincashTestnet:
return 'bchtest';
case networks.ecash:
return 'ecash';
case networks.ecashTest:
return 'ectest';
default:
throw new Error(`unsupported prefix for ${getNetworkName(network)}`);
}
}
/**
* @param outputScript
* @param network
* @return outputScript encoded as cashaddr (prefixed, lowercase)
*/
export function fromOutputScriptToCashAddress(outputScript: Buffer, network: Network): string {
if (!isBitcoinCash(network) && !isECash(network)) {
throw new Error(`invalid network`);
}
for (const [paymentName, scriptType] of [
['p2pkh', 'pubkeyhash'],
['p2sh', 'scripthash'],
]) {
const hash = getHashFromOutputScript(paymentName, outputScript);
if (hash) {
return cashaddress.encode(getPrefix(network), scriptType as cashaddress.ScriptType, hash);
}
}
throw new Error(`could not determine hash for outputScript`);
}
/**
* @param address - Accepts addresses with and without prefix. Accepts all-lowercase and all-uppercase addresses. Rejects mixed-case addresses.
* @param network
* @return decoded output script
*/
export function toOutputScriptFromCashAddress(address: string, network: Network): Buffer {
if (!isBitcoinCash(network) && !isECash(network)) {
throw new Error(`invalid network`);
}
if (address === address.toUpperCase()) {
address = address.toLowerCase();
}
if (address !== address.toLowerCase()) {
throw new Error(`mixed-case addresses not allowed`);
}
if (!address.startsWith(getPrefix(network) + ':')) {
address = `${getPrefix(network)}:${address}`;
}
const decoded = cashaddress.decode(address);
let outputScript: Buffer | undefined;
switch (decoded.version) {
case 'scripthash':
outputScript = bitcoinjs.payments.p2sh({ hash: decoded.hash }).output;
break;
case 'pubkeyhash':
outputScript = bitcoinjs.payments.p2pkh({ hash: decoded.hash }).output;
break;
default:
throw new Error(`unknown version ${decoded.version}`);
}
if (!outputScript) {
throw new Error(`could not determine output script`);
}
return outputScript;
}
/**
* @param outputScript
* @param format
* @param network
* @return address in specified format
*/
export function fromOutputScriptWithFormat(outputScript: Buffer, format: AddressFormat, network: Network): string {
if (!isBitcoinCash(network) && !isECash(network)) {
throw new Error(`invalid network`);
}
if (format === 'cashaddr') {
return fromOutputScriptToCashAddress(outputScript, network);
}
if (format === 'default') {
return bitcoinjs.address.fromOutputScript(outputScript, network as bitcoinjs.Network);
}
throw new Error(`invalid format`);
}
/**
* @param address
* @param format
* @param network
* @return output script from address in specified format
*/
export function toOutputScriptWithFormat(address: string, format: AddressFormat, network: Network): Buffer {
if (!isBitcoinCash(network) && !isECash(network)) {
throw new Error(`invalid network`);
}
if (format === 'cashaddr') {
return toOutputScriptFromCashAddress(address, network);
}
if (format === 'default') {
return bitcoinjs.address.toOutputScript(address, network as bitcoinjs.Network);
}
throw new Error(`invalid format`);
}
Выполнить команду
Для локальной разработки. Не используйте в интернете!