PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/algosdk/dist/cjs/src
Просмотр файла: logicsig.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.tealSignFromProgram = exports.tealSign = exports.logicSigFromByte = exports.signLogicSigTransaction = exports.signLogicSigTransactionObject = exports.makeLogicSig = exports.LogicSigAccount = exports.LogicSig = exports.sanityCheckProgram = void 0;
const nacl = __importStar(require("./nacl/naclWrappers"));
const address = __importStar(require("./encoding/address"));
const encoding = __importStar(require("./encoding/encoding"));
const multisig_1 = require("./multisig");
const utils = __importStar(require("./utils/utils"));
const txnBuilder = __importStar(require("./transaction"));
const address_1 = require("./encoding/address");
/** sanityCheckProgram performs heuristic program validation:
* check if passed in bytes are Algorand address or is B64 encoded, rather than Teal bytes
*
* @param program - Program bytes to check
*/
function sanityCheckProgram(program) {
if (!program || program.length === 0)
throw new Error('empty program');
const lineBreakOrd = '\n'.charCodeAt(0);
const blankSpaceOrd = ' '.charCodeAt(0);
const tildeOrd = '~'.charCodeAt(0);
const isPrintable = (x) => blankSpaceOrd <= x && x <= tildeOrd;
const isAsciiPrintable = program.every((x) => x === lineBreakOrd || isPrintable(x));
if (isAsciiPrintable) {
const programStr = Buffer.from(program).toString();
if ((0, address_1.isValidAddress)(programStr))
throw new Error('requesting program bytes, get Algorand address');
if (Buffer.from(programStr, 'base64').toString('base64') === programStr)
throw new Error('program should not be b64 encoded');
throw new Error('program bytes are all ASCII printable characters, not looking like Teal byte code');
}
}
exports.sanityCheckProgram = sanityCheckProgram;
/**
LogicSig implementation
*/
class LogicSig {
constructor(program, programArgs) {
this.tag = Buffer.from('Program');
if (programArgs &&
(!Array.isArray(programArgs) ||
!programArgs.every((arg) => arg.constructor === Uint8Array || Buffer.isBuffer(arg)))) {
throw new TypeError('Invalid arguments');
}
let args;
if (programArgs != null)
args = programArgs.map((arg) => new Uint8Array(arg));
sanityCheckProgram(program);
this.logic = program;
this.args = args;
this.sig = undefined;
this.msig = undefined;
}
// eslint-disable-next-line camelcase
get_obj_for_encoding() {
const obj = {
l: this.logic,
};
if (this.args) {
obj.arg = this.args;
}
if (this.sig) {
obj.sig = this.sig;
}
else if (this.msig) {
obj.msig = this.msig;
}
return obj;
}
// eslint-disable-next-line camelcase
static from_obj_for_encoding(encoded) {
const lsig = new LogicSig(encoded.l, encoded.arg);
lsig.sig = encoded.sig;
lsig.msig = encoded.msig;
return lsig;
}
/**
* Performs signature verification
* @param publicKey - Verification key (derived from sender address or escrow address)
*/
verify(publicKey) {
if (this.sig && this.msig) {
return false;
}
try {
sanityCheckProgram(this.logic);
}
catch (e) {
return false;
}
const toBeSigned = utils.concatArrays(this.tag, this.logic);
if (!this.sig && !this.msig) {
const hash = nacl.genericHash(toBeSigned);
return utils.arrayEqual(hash, publicKey);
}
if (this.sig) {
return nacl.verify(toBeSigned, this.sig, publicKey);
}
return (0, multisig_1.verifyMultisig)(toBeSigned, this.msig, publicKey);
}
/**
* Compute hash of the logic sig program (that is the same as escrow account address) as string address
* @returns String representation of the address
*/
address() {
const toBeSigned = utils.concatArrays(this.tag, this.logic);
const hash = nacl.genericHash(toBeSigned);
return address.encodeAddress(new Uint8Array(hash));
}
/**
* Creates signature (if no msig provided) or multi signature otherwise
* @param secretKey - Secret key to sign with
* @param msig - Multisig account as \{version, threshold, addrs\}
*/
sign(secretKey, msig) {
if (msig == null) {
this.sig = this.signProgram(secretKey);
}
else {
const subsigs = msig.addrs.map((addr) => ({
pk: address.decodeAddress(addr).publicKey,
}));
this.msig = {
v: msig.version,
thr: msig.threshold,
subsig: subsigs,
};
const [sig, index] = this.singleSignMultisig(secretKey, this.msig);
this.msig.subsig[index].s = sig;
}
}
/**
* Appends a signature to multi signature
* @param secretKey - Secret key to sign with
*/
appendToMultisig(secretKey) {
if (this.msig === undefined) {
throw new Error('no multisig present');
}
const [sig, index] = this.singleSignMultisig(secretKey, this.msig);
this.msig.subsig[index].s = sig;
}
signProgram(secretKey) {
const toBeSigned = utils.concatArrays(this.tag, this.logic);
const sig = nacl.sign(toBeSigned, secretKey);
return sig;
}
singleSignMultisig(secretKey, msig) {
let index = -1;
const myPk = nacl.keyPairFromSecretKey(secretKey).publicKey;
for (let i = 0; i < msig.subsig.length; i++) {
const { pk } = msig.subsig[i];
if (utils.arrayEqual(pk, myPk)) {
index = i;
break;
}
}
if (index === -1) {
throw new Error('invalid secret key');
}
const sig = this.signProgram(secretKey);
return [sig, index];
}
toByte() {
return encoding.encode(this.get_obj_for_encoding());
}
static fromByte(encoded) {
const decodedObj = encoding.decode(encoded);
return LogicSig.from_obj_for_encoding(decodedObj);
}
}
exports.LogicSig = LogicSig;
/**
* Represents an account that can sign with a LogicSig program.
*/
class LogicSigAccount {
/**
* Create a new LogicSigAccount. By default this will create an escrow
* LogicSig account. Call `sign` or `signMultisig` on the newly created
* LogicSigAccount to make it a delegated account.
*
* @param program - The compiled TEAL program which contains the logic for
* this LogicSig.
* @param args - An optional array of arguments for the program.
*/
constructor(program, args) {
this.lsig = new LogicSig(program, args);
this.sigkey = undefined;
}
// eslint-disable-next-line camelcase
get_obj_for_encoding() {
const obj = {
lsig: this.lsig.get_obj_for_encoding(),
};
if (this.sigkey) {
obj.sigkey = this.sigkey;
}
return obj;
}
// eslint-disable-next-line camelcase
static from_obj_for_encoding(encoded) {
const lsigAccount = new LogicSigAccount(encoded.lsig.l, encoded.lsig.arg);
lsigAccount.lsig = LogicSig.from_obj_for_encoding(encoded.lsig);
lsigAccount.sigkey = encoded.sigkey;
return lsigAccount;
}
/**
* Encode this object into msgpack.
*/
toByte() {
return encoding.encode(this.get_obj_for_encoding());
}
/**
* Decode a msgpack object into a LogicSigAccount.
* @param encoded - The encoded LogicSigAccount.
*/
static fromByte(encoded) {
const decodedObj = encoding.decode(encoded);
return LogicSigAccount.from_obj_for_encoding(decodedObj);
}
/**
* Check if this LogicSigAccount has been delegated to another account with a
* signature.
*
* Note this function only checks for the presence of a delegation signature.
* To verify the delegation signature, use `verify`.
*/
isDelegated() {
return !!(this.lsig.sig || this.lsig.msig);
}
/**
* Verifies this LogicSig's program and signatures.
* @returns true if and only if the LogicSig program and signatures are valid.
*/
verify() {
const addr = this.address();
return this.lsig.verify(address.decodeAddress(addr).publicKey);
}
/**
* Get the address of this LogicSigAccount.
*
* If the LogicSig is delegated to another account, this will return the
* address of that account.
*
* If the LogicSig is not delegated to another account, this will return an
* escrow address that is the hash of the LogicSig's program code.
*/
address() {
if (this.lsig.sig && this.lsig.msig) {
throw new Error('LogicSig has too many signatures. At most one of sig or msig may be present');
}
if (this.lsig.sig) {
if (!this.sigkey) {
throw new Error('Signing key for delegated account is missing');
}
return address.encodeAddress(this.sigkey);
}
if (this.lsig.msig) {
const msigMetadata = {
version: this.lsig.msig.v,
threshold: this.lsig.msig.thr,
pks: this.lsig.msig.subsig.map((subsig) => subsig.pk),
};
return address.encodeAddress(address.fromMultisigPreImg(msigMetadata));
}
return this.lsig.address();
}
/**
* Turns this LogicSigAccount into a delegated LogicSig. This type of LogicSig
* has the authority to sign transactions on behalf of another account, called
* the delegating account. Use this function if the delegating account is a
* multisig account.
*
* @param msig - The multisig delegating account
* @param secretKey - The secret key of one of the members of the delegating
* multisig account. Use `appendToMultisig` to add additional signatures
* from other members.
*/
signMultisig(msig, secretKey) {
this.lsig.sign(secretKey, msig);
}
/**
* Adds an additional signature from a member of the delegating multisig
* account.
*
* @param secretKey - The secret key of one of the members of the delegating
* multisig account.
*/
appendToMultisig(secretKey) {
this.lsig.appendToMultisig(secretKey);
}
/**
* Turns this LogicSigAccount into a delegated LogicSig. This type of LogicSig
* has the authority to sign transactions on behalf of another account, called
* the delegating account. If the delegating account is a multisig account,
* use `signMultisig` instead.
*
* @param secretKey - The secret key of the delegating account.
*/
sign(secretKey) {
this.lsig.sign(secretKey);
this.sigkey = nacl.keyPairFromSecretKey(secretKey).publicKey;
}
}
exports.LogicSigAccount = LogicSigAccount;
/**
* makeLogicSig creates LogicSig object from program and arguments
*
* @deprecated Use new LogicSigAccount(...) instead
*
* @param program - Program to make LogicSig from
* @param args - Arguments as array of Uint8Array
* @returns LogicSig object
*/
function makeLogicSig(program, args) {
return new LogicSig(program, args);
}
exports.makeLogicSig = makeLogicSig;
function signLogicSigTransactionWithAddress(txn, lsig, lsigAddress) {
if (!lsig.verify(lsigAddress)) {
throw new Error('Logic signature verification failed. Ensure the program and signature are valid.');
}
const signedTxn = {
lsig: lsig.get_obj_for_encoding(),
txn: txn.get_obj_for_encoding(),
};
if (!nacl.bytesEqual(lsigAddress, txn.from.publicKey)) {
signedTxn.sgnr = Buffer.from(lsigAddress);
}
return {
txID: txn.txID().toString(),
blob: encoding.encode(signedTxn),
};
}
/**
* signLogicSigTransactionObject takes a transaction and a LogicSig object and
* returns a signed transaction.
*
* @param txn - The transaction to sign.
* @param lsigObject - The LogicSig object that will sign the transaction.
*
* @returns Object containing txID and blob representing signed transaction.
*/
function signLogicSigTransactionObject(txn, lsigObject) {
let lsig;
let lsigAddress;
if (lsigObject instanceof LogicSigAccount) {
lsig = lsigObject.lsig;
lsigAddress = address.decodeAddress(lsigObject.address()).publicKey;
}
else {
lsig = lsigObject;
if (lsig.sig) {
// For a LogicSig with a non-multisig delegating account, we cannot derive
// the address of that account from only its signature, so assume the
// delegating account is the sender. If that's not the case, the signing
// will fail.
lsigAddress = txn.from.publicKey;
}
else if (lsig.msig) {
const msigMetadata = {
version: lsig.msig.v,
threshold: lsig.msig.thr,
pks: lsig.msig.subsig.map((subsig) => subsig.pk),
};
lsigAddress = address.fromMultisigPreImg(msigMetadata);
}
else {
lsigAddress = address.decodeAddress(lsig.address()).publicKey;
}
}
return signLogicSigTransactionWithAddress(txn, lsig, lsigAddress);
}
exports.signLogicSigTransactionObject = signLogicSigTransactionObject;
/**
* signLogicSigTransaction takes a transaction and a LogicSig object and returns
* a signed transaction.
*
* @param txn - The transaction to sign.
* @param lsigObject - The LogicSig object that will sign the transaction.
*
* @returns Object containing txID and blob representing signed transaction.
* @throws error on failure
*/
function signLogicSigTransaction(txn, lsigObject) {
const algoTxn = txnBuilder.instantiateTxnIfNeeded(txn);
return signLogicSigTransactionObject(algoTxn, lsigObject);
}
exports.signLogicSigTransaction = signLogicSigTransaction;
/**
* logicSigFromByte accepts encoded logic sig bytes and attempts to call logicsig.fromByte on it,
* returning the result
*/
function logicSigFromByte(encoded) {
return LogicSig.fromByte(encoded);
}
exports.logicSigFromByte = logicSigFromByte;
const SIGN_PROGRAM_DATA_PREFIX = Buffer.from('ProgData');
/**
* tealSign creates a signature compatible with ed25519verify opcode from program hash
* @param sk - uint8array with secret key
* @param data - buffer with data to sign
* @param programHash - string representation of teal program hash (= contract address for LogicSigs)
*/
function tealSign(sk, data, programHash) {
const parts = utils.concatArrays(address.decodeAddress(programHash).publicKey, data);
const toBeSigned = Buffer.from(utils.concatArrays(SIGN_PROGRAM_DATA_PREFIX, parts));
return nacl.sign(toBeSigned, sk);
}
exports.tealSign = tealSign;
/**
* tealSignFromProgram creates a signature compatible with ed25519verify opcode from raw program bytes
* @param sk - uint8array with secret key
* @param data - buffer with data to sign
* @param program - buffer with teal program
*/
function tealSignFromProgram(sk, data, program) {
const lsig = new LogicSig(program);
const contractAddress = lsig.address();
return tealSign(sk, data, contractAddress);
}
exports.tealSignFromProgram = tealSignFromProgram;
//# sourceMappingURL=logicsig.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!