PHP WebShell

Текущая директория: /opt/BitGoJS/node_modules/@hashgraph/sdk/src/contract

Просмотр файла: ContractFunctionResult.js

/*-
 * ‌
 * Hedera JavaScript SDK
 * ​
 * Copyright (C) 2020 - 2022 Hedera Hashgraph, LLC
 * ​
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ‍
 */

import ContractLogInfo from "./ContractLogInfo.js";
import ContractId from "./ContractId.js";
import AccountId from "../account/AccountId.js";
import BigNumber from "bignumber.js";
import * as hex from "../encoding/hex.js";
import * as utf8 from "../encoding/utf8.js";
import * as util from "../util.js";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { ParamType, defaultAbiCoder } from "@ethersproject/abi";
import Long from "long";

/**
 * @typedef {import("./ContractStateChange.js").default} ContractStateChange
 */

/**
 * @namespace proto
 * @typedef {import("@hashgraph/proto").proto.IContractFunctionResult} HashgraphProto.proto.IContractFunctionResult
 * @typedef {import("@hashgraph/proto").proto.IContractID} HashgraphProto.proto.IContractID
 */

/**
 * The result returned by a call to a smart contract function. This is part of the response to
 * a ContractCallLocal query, and is in the record for a ContractCall or ContractCreateInstance
 * transaction. The ContractCreateInstance transaction record has the results of the call to
 * the constructor.
 */
export default class ContractFunctionResult {
    /**
     * Constructor isn't part of the stable API
     *
     * @param {object} result
     * @param {boolean} result._createResult
     * @param {?ContractId} result.contractId
     * @param {?string} result.errorMessage
     * @param {Uint8Array} result.bloom
     * @param {Long} result.gasUsed
     * @param {ContractLogInfo[]} result.logs
     * @param {ContractId[]} result.createdContractIds
     * @param {Uint8Array | null} result.evmAddress
     * @param {Uint8Array} result.bytes
     * @param {Long} result.gas
     * @param {Long} result.amount
     * @param {Uint8Array} result.functionParameters
     * @param {?AccountId} result.senderAccountId
     * @param {ContractStateChange[]} result.stateChanges
     */
    constructor(result) {
        /**
         * Determines if this result came from `record.contractCreateResult` if true
         * or `record.contractCallResult` if false
         */
        this._createResult = result._createResult;

        /**
         * The smart contract instance whose function was called.
         */
        this.contractId = result.contractId;

        this.bytes = result.bytes;

        /**
         * Message In case there was an error during smart contract execution.
         */
        this.errorMessage = result.errorMessage;

        /**
         * Bloom filter for record
         */
        this.bloom = result.bloom;

        /**
         * Units of gas used  to execute contract.
         */
        this.gasUsed = result.gasUsed;

        /**
         * The log info for events returned by the function.
         */
        this.logs = result.logs;

        /**
         * @deprecated the list of smart contracts that were created by the function call.
         *
         * The created ids will now _also_ be externalized through internal transaction
         * records, where each record has its alias field populated with the new contract's
         * EVM address. (This is needed for contracts created with CREATE2, since
         * there is no longer a simple relationship between the new contract's 0.0.X id
         * and its Solidity address.)
         */
        // eslint-disable-next-line deprecation/deprecation
        this.createdContractIds = result.createdContractIds;

        this.evmAddress = result.evmAddress;

        /**
         * @deprecated - Use mirror node for contract traceability instead
         */
        // eslint-disable-next-line deprecation/deprecation
        this.stateChanges = result.stateChanges;

        /**
         * The amount of gas available for the call, aka the gasLimit.
         */
        this.gas = result.gas;

        /**
         * Number of tinybars sent (the function must be payable if this is nonzero).
         */
        this.amount = result.amount;

        /**
         * The parameters passed into the contract call.
         */
        this.functionParameters = result.functionParameters;

        /**
         * The account that is the "sender." If not present it is the accountId from the transactionId.
         *
         * This field should only be populated when the paired TransactionBody in the record stream is not a
         * ContractCreateTransactionBody or a ContractCallTransactionBody.
         */
        this.senderAccountId = result.senderAccountId;
    }

    /**
     * @param {HashgraphProto.proto.IContractFunctionResult} result
     * @param {boolean} _createResult
     * @returns {ContractFunctionResult}
     */
    static _fromProtobuf(result, _createResult) {
        const contractId =
            /** @type {HashgraphProto.proto.IContractID | null} */ (
                result.contractID
            );
        const gasUsed = /** @type {Long} */ (result.gasUsed);
        const gas = /** @type {Long} */ (result.gas ? result.gas : -1);
        const amount = /** @type {Long} */ (result.amount ? result.amount : -1);

        return new ContractFunctionResult({
            _createResult,
            bytes: /** @type {Uint8Array} */ (result.contractCallResult),
            contractId:
                contractId != null
                    ? ContractId._fromProtobuf(contractId)
                    : null,
            errorMessage:
                result.errorMessage != null ? result.errorMessage : null,
            bloom: /** @type {Uint8Array} */ (result.bloom),
            gasUsed:
                gasUsed instanceof Long ? gasUsed : Long.fromValue(gasUsed),
            logs: (result.logInfo != null ? result.logInfo : []).map((info) =>
                ContractLogInfo._fromProtobuf(info)
            ),
            createdContractIds: (result.createdContractIDs != null
                ? result.createdContractIDs
                : []
            ).map((contractId) => ContractId._fromProtobuf(contractId)),
            evmAddress:
                result.evmAddress != null && result.evmAddress.value != null
                    ? result.evmAddress.value
                    : null,
            stateChanges: [],
            gas: gas instanceof Long ? gas : Long.fromValue(gas),
            amount: amount instanceof Long ? amount : Long.fromValue(amount),
            functionParameters: /** @type {Uint8Array} */ (
                result.functionParameters
            ),
            senderAccountId:
                result.senderId != null
                    ? AccountId._fromProtobuf(result.senderId)
                    : null,
        });
    }

    /**
     * @returns {Uint8Array}
     */
    asBytes() {
        return this.bytes;
    }

    /**
     * @param {number} [index]
     * @returns {string}
     */
    getString(index) {
        return utf8.decode(this.getBytes(index));
    }

    /**
     * @private
     * @param {number} [index]
     * @returns {Uint8Array}
     */
    getBytes(index) {
        // Len should never be larger than Number.MAX
        // index * 32 is the position of the lenth
        // (index + 1) * 32 onward to (index + 1) * 32 + len will be the elements of the array
        // Arrays in solidity cannot be longer than 1024:
        // https://solidity.readthedocs.io/en/v0.4.21/introduction-to-smart-contracts.html
        const offset = this.getInt32(index);
        const len = util.safeView(this.bytes).getInt32(offset + 28);

        return this.bytes.subarray(offset + 32, offset + 32 + len);
    }

    /**
     * @param {number} [index]
     * @returns {Uint8Array}
     */
    getBytes32(index) {
        return this.bytes.subarray(
            (index != null ? index : 0) * 32,
            (index != null ? index : 0) * 32 + 32
        );
    }

    /**
     * @param {number} [index]
     * @returns {boolean}
     */
    getBool(index) {
        return this.bytes[(index != null ? index : 0) * 32 + 31] !== 0;
    }

    /**
     * @param {number} [index]
     * @returns {number}
     */
    getInt8(index) {
        const position = (index != null ? index : 0) * 32 + 31;
        return util.safeView(this.bytes).getInt8(position);
    }

    /**
     * @param {number} [index]
     * @returns {number}
     */
    getUint8(index) {
        return this.bytes[(index != null ? index : 0) * 32 + 31];
    }

    /**
     * @param {number} [index]
     * @returns {number}
     */
    getInt32(index) {
        // .getInt32() interprets as big-endian
        // Using DataView instead of Uint32Array because the latter interprets
        // using platform endianness which is little-endian on x86
        const position = (index != null ? index : 0) * 32 + 28;
        return util.safeView(this.bytes).getInt32(position);
    }

    /**
     * @param {number} [index]
     * @returns {number}
     */
    getUint32(index) {
        // .getUint32() interprets as big-endian
        // Using DataView instead of Uint32Array because the latter interprets
        // using platform endianness which is little-endian on x86
        const position = (index != null ? index : 0) * 32 + 28;
        return util.safeView(this.bytes).getUint32(position);
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt40(index) {
        const result = defaultAbiCoder.decode(
            ["int40"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint40(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(27, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt48(index) {
        const result = defaultAbiCoder.decode(
            ["int48"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint48(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(26, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt56(index) {
        const result = defaultAbiCoder.decode(
            ["int56"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint56(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(25, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt64(index) {
        const result = defaultAbiCoder.decode(
            ["int64"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint64(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(24, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt72(index) {
        const result = defaultAbiCoder.decode(
            ["int72"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint72(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(23, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt80(index) {
        const result = defaultAbiCoder.decode(
            ["int80"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint80(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(22, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt88(index) {
        const result = defaultAbiCoder.decode(
            ["int88"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint88(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(21, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt96(index) {
        const result = defaultAbiCoder.decode(
            ["int96"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint96(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(20, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt104(index) {
        const result = defaultAbiCoder.decode(
            ["int104"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint104(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(19, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt112(index) {
        const result = defaultAbiCoder.decode(
            ["int112"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint112(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(18, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt120(index) {
        const result = defaultAbiCoder.decode(
            ["int120"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint120(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(17, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt128(index) {
        const result = defaultAbiCoder.decode(
            ["int128"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint128(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(16, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt136(index) {
        const result = defaultAbiCoder.decode(
            ["int136"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint136(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(15, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt144(index) {
        const result = defaultAbiCoder.decode(
            ["int144"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint144(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(14, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt152(index) {
        const result = defaultAbiCoder.decode(
            ["int152"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint152(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(13, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt160(index) {
        const result = defaultAbiCoder.decode(
            ["int160"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint160(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(12, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt168(index) {
        const result = defaultAbiCoder.decode(
            ["int168"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint168(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(11, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt176(index) {
        const result = defaultAbiCoder.decode(
            ["int176"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint176(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(10, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt184(index) {
        const result = defaultAbiCoder.decode(
            ["int184"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint184(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(9, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt192(index) {
        const result = defaultAbiCoder.decode(
            ["int192"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint192(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(8, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt200(index) {
        const result = defaultAbiCoder.decode(
            ["int200"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint200(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(7, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt208(index) {
        const result = defaultAbiCoder.decode(
            ["int208"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint208(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(6, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt216(index) {
        const result = defaultAbiCoder.decode(
            ["int216"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint216(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(5, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt224(index) {
        const result = defaultAbiCoder.decode(
            ["int224"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint224(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(4, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt232(index) {
        const result = defaultAbiCoder.decode(
            ["int232"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint232(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(3, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt240(index) {
        const result = defaultAbiCoder.decode(
            ["int240"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint240(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(2, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt248(index) {
        const result = defaultAbiCoder.decode(
            ["int248"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint248(index) {
        return new BigNumber(
            hex.encode(this._getBytes32(index).subarray(1, 32)),
            16
        );
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getInt256(index) {
        const result = defaultAbiCoder.decode(
            ["int256"],
            this._getBytes32(index != null ? index : 0)
        );
        return new BigNumber(result.toString());
    }

    /**
     * @param {number} [index]
     * @returns {BigNumber}
     */
    getUint256(index) {
        return new BigNumber(hex.encode(this._getBytes32(index)), 16);
    }

    /**
     * @param {number} [index]
     * @returns {string}
     */
    getAddress(index) {
        return hex.encode(
            this.bytes.subarray(
                (index != null ? index : 0) * 32 + 12,
                (index != null ? index : 0) * 32 + 32
            )
        );
    }

    /**
     * @description Decode the data according to the array of types, each of which may be a string or ParamType.
     * @param {Array<string | ParamType>} types
     * @returns {string | any}
     */
    getResult(types) {
        return defaultAbiCoder.decode(types, this.bytes);
    }

    /**
     * @param {number} [index]
     * @returns {Uint8Array}
     */
    _getBytes32(index) {
        return this.bytes.subarray(
            (index != null ? index : 0) * 32,
            (index != null ? index : 0) * 32 + 32
        );
    }

    /**
     * @returns {HashgraphProto.proto.IContractFunctionResult}
     */
    _toProtobuf() {
        return {
            contractID:
                this.contractId != null ? this.contractId._toProtobuf() : null,
            contractCallResult: this.bytes,
            errorMessage: this.errorMessage,
            bloom: this.bloom,
            gasUsed: this.gasUsed,
            logInfo: this.logs.map((log) => log._toProtobuf()),
            // eslint-disable-next-line deprecation/deprecation
            createdContractIDs: this.createdContractIds.map((id) =>
                id._toProtobuf()
            ),
            evmAddress:
                this.evmAddress != null
                    ? {
                          value: this.evmAddress,
                      }
                    : null,
            gas: this.gas,
            amount: this.amount,
            functionParameters: this.functionParameters,
            senderId:
                this.senderAccountId != null
                    ? this.senderAccountId._toProtobuf()
                    : null,
        };
    }
}

Выполнить команду


Для локальной разработки. Не используйте в интернете!