PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/@stacks/transactions/dist/esm
Просмотр файла: authorization.js
import { Buffer, intToBigInt, intToBytes } from '@stacks/common';
import { AddressHashMode, AuthType, PubKeyEncoding, RECOVERABLE_ECDSA_SIG_LENGTH_BYTES, StacksMessageType, } from './constants';
import { BufferArray, cloneDeep, leftPadHex, txidFromData } from './utils';
import { addressFromPublicKeys, createEmptyAddress, createLPList, deserializeLPList, serializeLPList, } from './types';
import { compressPublicKey, createStacksPublicKey, deserializePublicKey, getPublicKey, isCompressed, publicKeyFromSignature, serializePublicKey, signWithKey, } from './keys';
import { DeserializationError, SerializationError, SigningError } from './errors';
class Deserializable {
static deserialize(bufferReader) {
const message = new this();
message.deserialize(bufferReader);
return message;
}
}
export function createMessageSignature(signature) {
const length = Buffer.from(signature, 'hex').byteLength;
if (length != RECOVERABLE_ECDSA_SIG_LENGTH_BYTES) {
throw Error('Invalid signature');
}
return {
type: StacksMessageType.MessageSignature,
data: signature,
};
}
export function emptyMessageSignature() {
return {
type: StacksMessageType.MessageSignature,
data: Buffer.alloc(RECOVERABLE_ECDSA_SIG_LENGTH_BYTES, 0x00).toString('hex'),
};
}
export function serializeMessageSignature(messageSignature) {
const bufferArray = new BufferArray();
bufferArray.appendHexString(messageSignature.data);
return bufferArray.concatBuffer();
}
export function deserializeMessageSignature(bufferReader) {
return createMessageSignature(bufferReader.readBuffer(RECOVERABLE_ECDSA_SIG_LENGTH_BYTES).toString('hex'));
}
var AuthFieldType;
(function (AuthFieldType) {
AuthFieldType[AuthFieldType["PublicKeyCompressed"] = 0] = "PublicKeyCompressed";
AuthFieldType[AuthFieldType["PublicKeyUncompressed"] = 1] = "PublicKeyUncompressed";
AuthFieldType[AuthFieldType["SignatureCompressed"] = 2] = "SignatureCompressed";
AuthFieldType[AuthFieldType["SignatureUncompressed"] = 3] = "SignatureUncompressed";
})(AuthFieldType || (AuthFieldType = {}));
export function createTransactionAuthField(pubKeyEncoding, contents) {
return {
pubKeyEncoding,
type: StacksMessageType.TransactionAuthField,
contents,
};
}
export function serializeTransactionAuthField(field) {
const bufferArray = new BufferArray();
switch (field.contents.type) {
case StacksMessageType.PublicKey:
if (field.pubKeyEncoding == PubKeyEncoding.Compressed) {
bufferArray.appendByte(AuthFieldType.PublicKeyCompressed);
bufferArray.push(serializePublicKey(field.contents));
}
else {
bufferArray.appendByte(AuthFieldType.PublicKeyUncompressed);
bufferArray.push(serializePublicKey(compressPublicKey(field.contents.data)));
}
break;
case StacksMessageType.MessageSignature:
if (field.pubKeyEncoding == PubKeyEncoding.Compressed) {
bufferArray.appendByte(AuthFieldType.SignatureCompressed);
}
else {
bufferArray.appendByte(AuthFieldType.SignatureUncompressed);
}
bufferArray.push(serializeMessageSignature(field.contents));
break;
}
return bufferArray.concatBuffer();
}
export function deserializeTransactionAuthField(bufferReader) {
const authFieldType = bufferReader.readUInt8Enum(AuthFieldType, n => {
throw new DeserializationError(`Could not read ${n} as AuthFieldType`);
});
switch (authFieldType) {
case AuthFieldType.PublicKeyCompressed:
return createTransactionAuthField(PubKeyEncoding.Compressed, deserializePublicKey(bufferReader));
case AuthFieldType.PublicKeyUncompressed:
return createTransactionAuthField(PubKeyEncoding.Uncompressed, deserializePublicKey(bufferReader));
case AuthFieldType.SignatureCompressed:
return createTransactionAuthField(PubKeyEncoding.Compressed, deserializeMessageSignature(bufferReader));
case AuthFieldType.SignatureUncompressed:
return createTransactionAuthField(PubKeyEncoding.Uncompressed, deserializeMessageSignature(bufferReader));
default:
throw new Error(`Unknown auth field type: ${JSON.stringify(authFieldType)}`);
}
}
export function createSingleSigSpendingCondition(hashMode, pubKey, nonce, fee) {
const signer = addressFromPublicKeys(0, hashMode, 1, [createStacksPublicKey(pubKey)]).hash160;
const keyEncoding = isCompressed(createStacksPublicKey(pubKey))
? PubKeyEncoding.Compressed
: PubKeyEncoding.Uncompressed;
return {
hashMode,
signer,
nonce: intToBigInt(nonce, false),
fee: intToBigInt(fee, false),
keyEncoding,
signature: emptyMessageSignature(),
};
}
export function createMultiSigSpendingCondition(hashMode, numSigs, pubKeys, nonce, fee) {
const stacksPublicKeys = pubKeys.map(createStacksPublicKey);
const signer = addressFromPublicKeys(0, hashMode, numSigs, stacksPublicKeys).hash160;
return {
hashMode,
signer,
nonce: intToBigInt(nonce, false),
fee: intToBigInt(fee, false),
fields: [],
signaturesRequired: numSigs,
};
}
export function isSingleSig(condition) {
return 'signature' in condition;
}
function clearCondition(condition) {
const cloned = cloneDeep(condition);
cloned.nonce = 0;
cloned.fee = 0;
if (isSingleSig(cloned)) {
cloned.signature = emptyMessageSignature();
}
else {
cloned.fields = [];
}
return Object.assign(Object.assign({}, cloned), { nonce: BigInt(0), fee: BigInt(0) });
}
export function serializeSingleSigSpendingCondition(condition) {
const bufferArray = new BufferArray();
bufferArray.appendByte(condition.hashMode);
bufferArray.appendHexString(condition.signer);
bufferArray.push(intToBytes(condition.nonce, false, 8));
bufferArray.push(intToBytes(condition.fee, false, 8));
bufferArray.appendByte(condition.keyEncoding);
bufferArray.push(serializeMessageSignature(condition.signature));
return bufferArray.concatBuffer();
}
export function serializeMultiSigSpendingCondition(condition) {
const bufferArray = new BufferArray();
bufferArray.appendByte(condition.hashMode);
bufferArray.appendHexString(condition.signer);
bufferArray.push(intToBytes(condition.nonce, false, 8));
bufferArray.push(intToBytes(condition.fee, false, 8));
const fields = createLPList(condition.fields);
bufferArray.push(serializeLPList(fields));
const numSigs = Buffer.alloc(2);
numSigs.writeUInt16BE(condition.signaturesRequired, 0);
bufferArray.push(numSigs);
return bufferArray.concatBuffer();
}
export function deserializeSingleSigSpendingCondition(hashMode, bufferReader) {
const signer = bufferReader.readBuffer(20).toString('hex');
const nonce = BigInt('0x' + bufferReader.readBuffer(8).toString('hex'));
const fee = BigInt('0x' + bufferReader.readBuffer(8).toString('hex'));
const keyEncoding = bufferReader.readUInt8Enum(PubKeyEncoding, n => {
throw new DeserializationError(`Could not parse ${n} as PubKeyEncoding`);
});
const signature = deserializeMessageSignature(bufferReader);
return {
hashMode,
signer,
nonce,
fee,
keyEncoding,
signature,
};
}
export function deserializeMultiSigSpendingCondition(hashMode, bufferReader) {
const signer = bufferReader.readBuffer(20).toString('hex');
const nonce = BigInt('0x' + bufferReader.readBuffer(8).toString('hex'));
const fee = BigInt('0x' + bufferReader.readBuffer(8).toString('hex'));
const fields = deserializeLPList(bufferReader, StacksMessageType.TransactionAuthField)
.values;
const signaturesRequired = bufferReader.readUInt16BE();
return {
hashMode,
signer,
nonce,
fee,
fields,
signaturesRequired,
};
}
export function serializeSpendingCondition(condition) {
if (isSingleSig(condition)) {
return serializeSingleSigSpendingCondition(condition);
}
else {
return serializeMultiSigSpendingCondition(condition);
}
}
export function deserializeSpendingCondition(bufferReader) {
const hashMode = bufferReader.readUInt8Enum(AddressHashMode, n => {
throw new DeserializationError(`Could not parse ${n} as AddressHashMode`);
});
if (hashMode === AddressHashMode.SerializeP2PKH || hashMode === AddressHashMode.SerializeP2WPKH) {
return deserializeSingleSigSpendingCondition(hashMode, bufferReader);
}
else {
return deserializeMultiSigSpendingCondition(hashMode, bufferReader);
}
}
export function makeSigHashPreSign(curSigHash, authType, fee, nonce) {
const hashLength = 32 + 1 + 8 + 8;
const sigHash = curSigHash +
Buffer.from([authType]).toString('hex') +
intToBytes(fee, false, 8).toString('hex') +
intToBytes(nonce, false, 8).toString('hex');
if (Buffer.from(sigHash, 'hex').byteLength !== hashLength) {
throw Error('Invalid signature hash length');
}
return txidFromData(Buffer.from(sigHash, 'hex'));
}
function makeSigHashPostSign(curSigHash, pubKey, signature) {
const hashLength = 32 + 1 + RECOVERABLE_ECDSA_SIG_LENGTH_BYTES;
const pubKeyEncoding = isCompressed(pubKey)
? PubKeyEncoding.Compressed
: PubKeyEncoding.Uncompressed;
const sigHash = curSigHash + leftPadHex(pubKeyEncoding.toString(16)) + signature.data;
const sigHashBuffer = Buffer.from(sigHash, 'hex');
if (sigHashBuffer.byteLength > hashLength) {
throw Error('Invalid signature hash length');
}
return txidFromData(sigHashBuffer);
}
export function nextSignature(curSigHash, authType, fee, nonce, privateKey) {
const sigHashPreSign = makeSigHashPreSign(curSigHash, authType, fee, nonce);
const signature = signWithKey(privateKey, sigHashPreSign);
const publicKey = getPublicKey(privateKey);
const nextSigHash = makeSigHashPostSign(sigHashPreSign, publicKey, signature);
return {
nextSig: signature,
nextSigHash,
};
}
export function nextVerification(initialSigHash, authType, fee, nonce, pubKeyEncoding, signature) {
const sigHashPreSign = makeSigHashPreSign(initialSigHash, authType, fee, nonce);
const publicKey = createStacksPublicKey(publicKeyFromSignature(sigHashPreSign, signature, pubKeyEncoding));
const nextSigHash = makeSigHashPostSign(sigHashPreSign, publicKey, signature);
return {
pubKey: publicKey,
nextSigHash,
};
}
function newInitialSigHash() {
const spendingCondition = createSingleSigSpendingCondition(AddressHashMode.SerializeP2PKH, '', 0, 0);
spendingCondition.signer = createEmptyAddress().hash160;
spendingCondition.keyEncoding = PubKeyEncoding.Compressed;
spendingCondition.signature = emptyMessageSignature();
return spendingCondition;
}
function verify(condition, initialSigHash, authType) {
if (isSingleSig(condition)) {
return verifySingleSig(condition, initialSigHash, authType);
}
else {
return '';
}
}
function verifySingleSig(condition, initialSigHash, authType) {
const { nextSigHash } = nextVerification(initialSigHash, authType, condition.fee, condition.nonce, condition.keyEncoding, condition.signature);
return nextSigHash;
}
export class Authorization extends Deserializable {
constructor(authType, spendingConditions, sponsorSpendingCondition) {
super();
this.authType = authType;
if (spendingConditions) {
this.spendingCondition = Object.assign(Object.assign({}, spendingConditions), { nonce: intToBigInt(spendingConditions.nonce, false), fee: intToBigInt(spendingConditions.fee, false) });
}
if (sponsorSpendingCondition) {
this.sponsorSpendingCondition = Object.assign(Object.assign({}, sponsorSpendingCondition), { nonce: intToBigInt(sponsorSpendingCondition.nonce, false), fee: intToBigInt(sponsorSpendingCondition.fee, false) });
}
}
intoInitialSighashAuth() {
if (this.spendingCondition) {
switch (this.authType) {
case AuthType.Standard:
return new Authorization(AuthType.Standard, clearCondition(this.spendingCondition));
case AuthType.Sponsored:
return new Authorization(AuthType.Sponsored, clearCondition(this.spendingCondition), newInitialSigHash());
default:
throw new SigningError('Unexpected authorization type for signing');
}
}
throw new Error('Authorization missing SpendingCondition');
}
setFee(amount) {
switch (this.authType) {
case AuthType.Standard:
this.spendingCondition.fee = intToBigInt(amount, false);
break;
case AuthType.Sponsored:
this.sponsorSpendingCondition.fee = intToBigInt(amount, false);
break;
}
}
getFee() {
switch (this.authType) {
case AuthType.Standard:
return this.spendingCondition.fee;
case AuthType.Sponsored:
return this.sponsorSpendingCondition.fee;
default:
return BigInt(0);
}
}
setNonce(nonce) {
this.spendingCondition.nonce = intToBigInt(nonce, false);
}
setSponsorNonce(nonce) {
this.sponsorSpendingCondition.nonce = intToBigInt(nonce, false);
}
setSponsor(sponsorSpendingCondition) {
this.sponsorSpendingCondition = Object.assign(Object.assign({}, sponsorSpendingCondition), { nonce: intToBigInt(sponsorSpendingCondition.nonce, false), fee: intToBigInt(sponsorSpendingCondition.fee, false) });
}
verifyOrigin(initialSigHash) {
switch (this.authType) {
case AuthType.Standard:
return verify(this.spendingCondition, initialSigHash, AuthType.Standard);
case AuthType.Sponsored:
return verify(this.spendingCondition, initialSigHash, AuthType.Standard);
default:
throw new SigningError('Invalid origin auth type');
}
}
serialize() {
const bufferArray = new BufferArray();
if (this.authType === undefined) {
throw new SerializationError('"authType" is undefined');
}
bufferArray.appendByte(this.authType);
switch (this.authType) {
case AuthType.Standard:
if (this.spendingCondition === undefined) {
throw new SerializationError('"spendingCondition" is undefined');
}
bufferArray.push(serializeSpendingCondition(this.spendingCondition));
break;
case AuthType.Sponsored:
if (this.spendingCondition === undefined) {
throw new SerializationError('"spendingCondition" is undefined');
}
if (this.sponsorSpendingCondition === undefined) {
throw new SerializationError('"spendingCondition" is undefined');
}
bufferArray.push(serializeSpendingCondition(this.spendingCondition));
bufferArray.push(serializeSpendingCondition(this.sponsorSpendingCondition));
break;
default:
throw new SerializationError(`Unexpected transaction AuthType while serializing: ${JSON.stringify(this.authType)}`);
}
return bufferArray.concatBuffer();
}
deserialize(bufferReader) {
this.authType = bufferReader.readUInt8Enum(AuthType, n => {
throw new DeserializationError(`Could not parse ${n} as AuthType`);
});
switch (this.authType) {
case AuthType.Standard:
this.spendingCondition = deserializeSpendingCondition(bufferReader);
break;
case AuthType.Sponsored:
this.spendingCondition = deserializeSpendingCondition(bufferReader);
this.sponsorSpendingCondition = deserializeSpendingCondition(bufferReader);
break;
default:
throw new DeserializationError(`Unexpected transaction AuthType while deserializing: ${JSON.stringify(this.authType)}`);
}
}
}
export class StandardAuthorization extends Authorization {
constructor(spendingCondition) {
super(AuthType.Standard, spendingCondition);
}
}
export class SponsoredAuthorization extends Authorization {
constructor(originSpendingCondition, sponsorSpendingCondition) {
let sponsorSC = sponsorSpendingCondition;
if (!sponsorSC) {
sponsorSC = createSingleSigSpendingCondition(AddressHashMode.SerializeP2PKH, '0'.repeat(66), 0, 0);
}
super(AuthType.Sponsored, originSpendingCondition, sponsorSC);
}
}
//# sourceMappingURL=authorization.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!