I am trying to put together an archive that will store contract address, metadata and abi etc. in a db for use by Dapps outside of hardhat. (This archiver is written inside hardhat but read outside of it)
In particular I'd like to store the abi, in json format, so that I can access and run the contract in a non-hardhat environment using ethers.js
This works well enough when the contract doesn't require libraries, but:
I have a "prototype" contract (BKProto
) which includes two functions common to every smart contract I write: BKContractName
and BKContractVersion
. I use the abi of BKProto to get the name and version of the contracts I'm storing.
I pass each contract I create to the archiver in the form of ethers.js Contract object.
I cast each contract in the BKProto
class created by the Hardhat typechain so I can read the name and version of the contract. Then I try to get the contractFactory object for each contract so I can retrieve the abi json and store it in the archive.
The code below (starting let factory
) works just fine for contracts which don't depend on libraries. But if they do, I can't get the factory this way -- I get the error: NomicLabsHardhatPluginError: The contract MyContract is missing links for the following libraries: contracts/MyLibrary.sol:MyLibrary
So . . . I am wondering if, within the hardhat environment, is there an easy way to retrieve the abi of a deployed contract, using the name of the contract? Or just using a contract instance provided as a param to this function?
The reason is that I use ethers, but not hardhat in some DApps which create the Contract object using the new
syntax to call its various functions.
let myContract = new Contract(address, abi, signer);
Suggestions appreciated.
private async extractRecordFromContract(projectName: string, contract: Contract) : ArchiveRecord {
let deployer = await contract.signer.getAddress();
let con = contract as BKProto
let name = await con.BKContractName();
let version = await con.BKVersion();
let factory = await ethers.getContractFactory(await con.BKContractName())
let abi = factory.interface.format(ethers.utils.FormatTypes.json)
//now store this data in the db.