Ошибка тестирования при вызове функции для внеконтрактной учетной записи

При тестировании нашего VRF getRandomNumber(s) с помощью тестовых помощников мы продолжаем получать ошибку: транзакция возвращена: вызов функции на неконтрактную учетную запись по адресу:

require(LINK.balanceOf(address(this))> fee, «Недостаточно ССЫЛКИ для инициализации вызова функции»);

LINK здесь используется правильно. В чем смысл / проблема внеконтрактной учетной записи?

1 ответ

Любой LINK.xxx()вызов относится к внешнему контракту LINK, которого нет в вашем коде. Это контракт, уже развернутый в сети, поэтому вы, скорее всего, передаете адрес LINK конструктору вашего контракта.

Чтобы заставить его работать в тесте, вам нужно что-то имитировать, чтобы ваш тест не вызывал реальный интерфейс. Одним из способов было бы издеваться над вашим getRandomNumberфункция. так как это public, это должно быть легко выполнимо с помощью имитирующих утилит Waffle: https://ethereum-waffle.readthedocs.io/en/latest/mock-contract.html.

В качестве альтернативы (вероятно, более законной, но дольше) вы можете издеваться над всем LINKдоговор:

  1. Есть немного Mocks.solдоговор:
            pragma solidity ^0.8.7;
    
    import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
    
    abstract contract LinkMock is LinkTokenInterface {}
    
  2. Инициализируйте его как макет в своем тесте и передайте его адрес вашему макету контракта в качестве первого аргумента, как указано в документации VRF:
            import { waffle } from 'hardhat'
    import { abi as linkMockAbi } from '../artifacts/contracts/Mocks.sol/LinkMock.json'
    
    const [deployer, vrfCoordinatorMock, ...actors] = waffle.provider.getWallets()
    
    const getContract = async ({ mockedLinkBalance }: { mockedLinkBalance: string }) => {
      const linkMockContract = await waffle.deployMockContract(deployer, linkMockAbi)
    
      // Mocks the external LINK contract that we don't have access to during tests
      await linkMockContract.mock.balanceOf.returns(ethers.utils.parseEther(mockedLinkBalance))
      await linkMockContract.mock.transferAndCall.returns(true)
    
      return waffle.deployContract(deployer, ContractJson, [
        vrfCoordinatorMock.address,
        linkMockContract.address,
       '0x0000000000000000000000000000000000000000000000000000000000000000',
        '100000000000000000',
      ])
    }
    
  3. Вызов rawFulfillRandomness()который VRF называет сам, всякий раз, когда вы хотите имитировать VRF, генерирующий случайность:
            const contract = await getContract()
    await contract.connect(vrfCoordinatorMock).rawFulfillRandomness('0x0000000000000000000000000000000000000000000000000000000000000000', mockedRandomnessValue)
    

Обратите внимание, что я жестко закодирован requestIdдля краткости в приведенном выше примере. Вам придется придумать способ заглушить его, если вы полагаетесь на его значение в своем контракте.

Другие вопросы по тегам