UNPKG

@nomiclabs/buidler-ethers

Version:
144 lines (124 loc) 3.76 kB
import { readArtifact } from "@nomiclabs/buidler/plugins"; import { BuidlerRuntimeEnvironment, NetworkConfig, } from "@nomiclabs/buidler/types"; import { ethers } from "ethers"; export async function getSigners(bre: BuidlerRuntimeEnvironment) { const accounts = await bre.ethers.provider.listAccounts(); return accounts.map((account: string) => bre.ethers.provider.getSigner(account) ); } export function getContractFactory( bre: BuidlerRuntimeEnvironment, name: string, signer?: ethers.Signer ): Promise<ethers.ContractFactory>; export function getContractFactory( bre: BuidlerRuntimeEnvironment, abi: any[], bytecode: ethers.utils.BytesLike | string, signer?: ethers.Signer ): Promise<ethers.ContractFactory>; export async function getContractFactory( bre: BuidlerRuntimeEnvironment, nameOrAbi: string | any[], bytecodeOrSigner?: ethers.Signer | ethers.utils.BytesLike | string, signer?: ethers.Signer ) { if (typeof nameOrAbi === "string") { return getContractFactoryByName( bre, nameOrAbi, bytecodeOrSigner as ethers.Signer | undefined ); } return getContractFactoryByAbiAndBytecode( bre, nameOrAbi, bytecodeOrSigner as ethers.utils.BytesLike | string, signer ); } export async function getContractFactoryByName( bre: BuidlerRuntimeEnvironment, name: string, signer?: ethers.Signer ) { const artifact = await readArtifact(bre.config.paths.artifacts, name); return getContractFactoryByAbiAndBytecode( bre, artifact.abi, artifact.bytecode, signer ); } export async function getContractFactoryByAbiAndBytecode( bre: BuidlerRuntimeEnvironment, abi: any[], bytecode: ethers.utils.BytesLike | string, signer?: ethers.Signer ) { if (signer === undefined) { const signers = await bre.ethers.getSigners(); signer = signers[0]; } const abiWithAddedGas = addGasToAbiMethodsIfNecessary( bre.network.config, abi ); return new bre.ethers.ContractFactory(abiWithAddedGas, bytecode, signer); } export async function getContractAt( bre: BuidlerRuntimeEnvironment, nameOrAbi: string | any[], address: string, signer?: ethers.Signer ) { if (typeof nameOrAbi === "string") { const factory = await getContractFactoryByName(bre, nameOrAbi, signer); return factory.attach(address); } if (signer === undefined) { const signers = await bre.ethers.getSigners(); signer = signers[0]; } const abiWithAddedGas = addGasToAbiMethodsIfNecessary( bre.network.config, nameOrAbi ); return new bre.ethers.Contract(address, abiWithAddedGas, signer); } // This helper adds a `gas` field to the ABI function elements if the network // is set up to use a fixed amount of gas. // This is done so that ethers doesn't automatically estimate gas limits on // every call. function addGasToAbiMethodsIfNecessary( networkConfig: NetworkConfig, abi: any[] ): any[] { if (networkConfig.gas === "auto" || networkConfig.gas === undefined) { return abi; } // ethers adds 21000 to whatever the abi `gas` field has. This may lead to // OOG errors, as people may set the default gas to the same value as the // block gas limit, especially on Buidler EVM. // To avoid this, we substract 21000. // HOTFIX: We substract 1M for now. See: https://github.com/ethers-io/ethers.js/issues/1058#issuecomment-703175279 const gasLimit = ethers.BigNumber.from(networkConfig.gas) .sub(1000000) .toHexString(); const modifiedAbi: any[] = []; for (const abiElement of abi) { if (abiElement.type !== "function") { modifiedAbi.push(abiElement); continue; } modifiedAbi.push({ ...abiElement, gas: gasLimit, }); } return modifiedAbi; }