ethers.js/lib.esm/contract/factory.js

112 lines
4.1 KiB
JavaScript
Raw Normal View History

2022-09-05 23:57:11 +03:00
import { Interface } from "../abi/index.js";
import { getCreateAddress } from "../address/index.js";
2022-11-09 10:57:02 +03:00
import { concat, defineProperties, getBytes, hexlify, assert, assertArgument } from "../utils/index.js";
2022-09-05 23:57:11 +03:00
import { BaseContract, copyOverrides, resolveArgs } from "./contract.js";
// A = Arguments to the constructor
// I = Interface of deployed contracts
2023-06-02 00:52:58 +03:00
/**
* A **ContractFactory** is used to deploy a Contract to the blockchain.
*/
2022-09-05 23:57:11 +03:00
export class ContractFactory {
2023-06-02 00:52:58 +03:00
/**
* The Contract Interface.
*/
2022-09-05 23:57:11 +03:00
interface;
2023-06-02 00:52:58 +03:00
/**
* The Contract deployment bytecode. Often called the initcode.
*/
2022-09-05 23:57:11 +03:00
bytecode;
2023-06-02 00:52:58 +03:00
/**
* The ContractRunner to deploy the Contract as.
*/
2022-09-05 23:57:11 +03:00
runner;
2023-06-02 00:52:58 +03:00
/**
* Create a new **ContractFactory** with %%abi%% and %%bytecode%%,
* optionally connected to %%runner%%.
*
* The %%bytecode%% may be the ``bytecode`` property within the
* standard Solidity JSON output.
*/
2022-09-05 23:57:11 +03:00
constructor(abi, bytecode, runner) {
const iface = Interface.from(abi);
// Dereference Solidity bytecode objects and allow a missing `0x`-prefix
if (bytecode instanceof Uint8Array) {
2022-09-16 05:58:45 +03:00
bytecode = hexlify(getBytes(bytecode));
2022-09-05 23:57:11 +03:00
}
else {
if (typeof (bytecode) === "object") {
bytecode = bytecode.object;
}
2023-02-19 06:18:42 +03:00
if (!bytecode.startsWith("0x")) {
2022-09-05 23:57:11 +03:00
bytecode = "0x" + bytecode;
}
2022-09-16 05:58:45 +03:00
bytecode = hexlify(getBytes(bytecode));
2022-09-05 23:57:11 +03:00
}
defineProperties(this, {
bytecode, interface: iface, runner: (runner || null)
});
}
2023-06-14 04:47:44 +03:00
attach(target) {
return new BaseContract(target, this.interface, this.runner);
}
2023-06-02 00:52:58 +03:00
/**
* Resolves to the transaction to deploy the contract, passing %%args%%
* into the constructor.
*/
2022-09-05 23:57:11 +03:00
async getDeployTransaction(...args) {
let overrides = {};
const fragment = this.interface.deploy;
if (fragment.inputs.length + 1 === args.length) {
overrides = await copyOverrides(args.pop());
}
if (fragment.inputs.length !== args.length) {
throw new Error("incorrect number of arguments to constructor");
}
const resolvedArgs = await resolveArgs(this.runner, fragment.inputs, args);
const data = concat([this.bytecode, this.interface.encodeDeploy(resolvedArgs)]);
return Object.assign({}, overrides, { data });
}
2023-06-02 00:52:58 +03:00
/**
* Resolves to the Contract deployed by passing %%args%% into the
* constructor.
*
* This will resovle to the Contract before it has been deployed to the
* network, so the [[BaseContract-waitForDeployment]] should be used before
* sending any transactions to it.
*/
2022-09-05 23:57:11 +03:00
async deploy(...args) {
const tx = await this.getDeployTransaction(...args);
2022-11-09 10:57:02 +03:00
assert(this.runner && typeof (this.runner.sendTransaction) === "function", "factory runner does not support sending transactions", "UNSUPPORTED_OPERATION", {
operation: "sendTransaction"
});
2022-09-05 23:57:11 +03:00
const sentTx = await this.runner.sendTransaction(tx);
const address = getCreateAddress(sentTx);
return new BaseContract(address, this.interface, this.runner, sentTx);
}
2023-06-02 00:52:58 +03:00
/**
* Return a new **ContractFactory** with the same ABI and bytecode,
* but connected to %%runner%%.
*/
2022-09-05 23:57:11 +03:00
connect(runner) {
return new ContractFactory(this.interface, this.bytecode, runner);
}
2023-06-02 00:52:58 +03:00
/**
* Create a new **ContractFactory** from the standard Solidity JSON output.
*/
2022-09-05 23:57:11 +03:00
static fromSolidity(output, runner) {
2022-11-09 10:57:02 +03:00
assertArgument(output != null, "bad compiler output", "output", output);
2022-09-05 23:57:11 +03:00
if (typeof (output) === "string") {
output = JSON.parse(output);
}
const abi = output.abi;
let bytecode = "";
if (output.bytecode) {
bytecode = output.bytecode;
}
else if (output.evm && output.evm.bytecode) {
bytecode = output.evm.bytecode;
}
return new this(abi, bytecode, runner);
}
}
//# sourceMappingURL=factory.js.map