Нет функции safeTransferFrom в экземпляре контракта ethers.js?
Я создаю экземпляр контракта в консоли hardhat следующим образом:
const contract_fac = await ethers.getContractFactory("ContractName");
const contract = await contract_fac.attach("CONTRACTADDR...");
Объект контракта имеет все общедоступные / внешние функции, кроме safeTransferFrom. Почему? Когда я вызываю его с помощью contract.safeTransferFrom(…), выдает ошибку JavaScript «safeTransferFrom не является функцией». Это баг или я чего-то не понимаю? Функция safeTransferFrom указана в файле abi.
Я использую шаблон токена OpenZeppelin (v. 4.2) 721 без изменений, Ethers.js (v. 5.4.1) и hardhat (v. 2.4.1).
3 ответа
(копирование из редактирования user1215772 для ясности ответа)
safeTransferFrom
является перегруженной функцией. В ethers.js синтаксис вызова перегруженной функции контракта отличается от синтаксиса вызова неперегруженной функции.
Перегруженные функции необходимо вызывать, указав сигнатуру функции.
Из документации ethers.js :
// ethers
const abi = [
"function getMessage(string) public view returns (string)",
"function getMessage() public view returns (string)"
]
const contract = new ethers.Contract(address, abi, signer);
// for ambiguous functions (two functions with the same
// name), the signature must also be specified
message = await contract['getMessage(string)']('nice');
Итак, для примера в вопросе:
Неправильный:
contract.safeTransferFrom(addr1, addr2, 1);
Правильный:
contract["safeTransferFrom(address,address,uint256)"](addr1, addr2, 1);
На каске мы сталкиваемся с аналогичной проблемой из-за перегрузки
Решение:
// Send NFT to another contract
const basicTransferTx = await basicNFTInstance['safeTransferFrom(address,address,uint256)'](
owner.address,
otherContract.address,
0 // token id
); // syntax is as such due to overloaded function
имейте в виду, что это может привести к сбою, если у вас есть пробелы. т.е. (адрес, адрес, uint256)