@solarity/hardhat-migrate
Version:
The simplest way to deploy smart contracts
138 lines • 6.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseAdapter = void 0;
const ethers_1 = require("ethers");
const Adapter_1 = require("./Adapter");
const MinimalContract_1 = require("../MinimalContract");
const constants_1 = require("../../constants");
const utils_1 = require("../../utils");
const Stats_1 = require("../../tools/Stats");
const Reporter_1 = require("../../tools/reporters/Reporter");
const NetworkManager_1 = require("../../tools/network/NetworkManager");
const TransactionRunner_1 = require("../../tools/runners/TransactionRunner");
const TransactionProcessor_1 = require("../../tools/storage/TransactionProcessor");
class BaseAdapter extends Adapter_1.Adapter {
getRawBytecode(instance) {
return (0, utils_1.bytecodeToString)(instance.bytecode);
}
async fromInstance(instance, parameters) {
return new MinimalContract_1.MinimalContract(this._hre, this.getRawBytecode(instance), this.getInterface(instance), this.getContractName(instance, parameters));
}
async toInstance(instance, address, parameters) {
const signer = await NetworkManager_1.networkManager.getSigner(parameters.from);
const contractName = this.getContractName(instance, parameters);
let contract = new ethers_1.BaseContract(address, this.getInterface(instance), signer);
contract = this._insertAddressGetter(contract, address);
contract = await this._overrideConnectMethod(contract, this.getInterface(instance), contractName);
return this._insertHandlers(contract, contractName);
}
_insertHandlers(contract, contractName) {
const methodSet = new Set();
for (const methodFragments of this._getContractFunctionFragments(contract.interface)) {
if (methodFragments.stateMutability === "view" || methodFragments.stateMutability === "pure") {
continue;
}
const methodName = methodFragments.format();
const shortName = methodName.split("(")[0];
const oldMethod = contract[methodName];
const newMethod = this._wrapOldMethod(contractName, methodName, methodFragments, oldMethod, contract.runner);
(0, ethers_1.defineProperties)(newMethod, {
name: oldMethod.name,
getFragment: oldMethod.getFragment,
estimateGas: oldMethod.estimateGas,
populateTransaction: oldMethod.populateTransaction,
send: oldMethod.send,
staticCall: oldMethod.staticCall,
staticCallResult: oldMethod.staticCallResult,
});
Object.defineProperty(newMethod, "fragment", oldMethod.fragment);
contract[methodName] = newMethod;
if (!methodSet.has(shortName)) {
contract[shortName] = newMethod;
methodSet.add(shortName);
}
else {
contract[shortName] = undefined;
}
}
return contract;
}
async _overrideConnectMethod(contract, contractInterface, contractName) {
const defaultRunner = await NetworkManager_1.networkManager.getSigner();
contract.connect = (runner) => {
const newContract = new ethers_1.BaseContract(contract.target, contractInterface, runner ?? defaultRunner);
return this._insertHandlers(newContract, contractName);
};
return contract;
}
_insertAddressGetter(contract, contractAddress) {
contract.address = contractAddress;
return contract;
}
_getContractFunctionFragments(contractInterface) {
const result = [];
contractInterface.forEachFunction((fragment) => {
result.push(fragment);
});
return result;
}
_wrapOldMethod(contractName, methodName, methodFragments, oldMethod, runner) {
return async (...args) => {
const tx = await oldMethod.populateTransaction(...args);
tx.from = runner.address || (await runner.getAddress());
await (0, utils_1.fillParameters)(tx);
const methodString = (0, utils_1.getMethodString)(contractName, methodName, methodFragments, args);
const keyFields = this._getKeyFieldsFromTransaction(tx);
if (this._hre.config.migrate.execution.continue) {
return this._recoverTransaction(methodString, keyFields, oldMethod, args);
}
return this._sendTransaction(methodString, keyFields, oldMethod, args);
};
}
async _recoverTransaction(methodString, tx, oldMethod, args) {
try {
const savedTransaction = TransactionProcessor_1.TransactionProcessor?.tryRestoreSavedTransaction(tx);
Reporter_1.Reporter.notifyTransactionRecovery(methodString, savedTransaction);
return this._wrapTransactionFieldsToSave(savedTransaction);
}
catch {
Reporter_1.Reporter.notifyTransactionSendingInsteadOfRecovery(methodString);
return this._sendTransaction(methodString, tx, oldMethod, args);
}
}
async _sendTransaction(methodString, tx, oldMethod, args) {
const txResponse = (await oldMethod(...args));
const saveMetadata = {
migrationNumber: Stats_1.Stats.currentMigration,
methodName: methodString,
};
await TransactionRunner_1.TransactionRunner.reportTransactionResponse(txResponse, methodString);
TransactionProcessor_1.TransactionProcessor?.saveTransaction(tx, (await txResponse.wait()), saveMetadata);
return txResponse;
}
_wrapTransactionFieldsToSave(data) {
return {
wait(_confirms) {
return data.receipt;
},
};
}
_getKeyFieldsFromTransaction(tx) {
return {
name: this._getTransactionName(tx),
data: tx.data,
from: tx.from,
chainId: tx.chainId,
value: tx.value,
to: tx.to,
};
}
_getTransactionName(tx) {
if (tx.customData === undefined || tx.customData.txName === undefined) {
return constants_1.UNKNOWN_TRANSACTION_NAME;
}
return tx.customData.txName;
}
}
exports.BaseAdapter = BaseAdapter;
//# sourceMappingURL=BaseAdapter.js.map