Solidity

Chainlink“TypeError:在合約創建期間無法讀取不可變變數……”

  • October 20, 2021

我嘗試過多種方式使用@chainlink/contracts(松露、安全帽、混音)。

在所有情況下,我都會遇到一個錯誤,這似乎是chainlink庫深處的一些錯誤:

> Compilation warnings encountered:

   Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
  --> project:/contracts/CCGG_all.sol:139:3:
   |
139 |   constructor() VRFConsumerBase(__vrfCoordinatorAddress, __linkTokenAddress) public {
   |   ^ (Relevant source part starts here and spans across multiple lines).

,Warning: Visibility for constructor is ignored. If you want the contract to be non-deployable, making it "abstract" is sufficient.
 --> project:/contracts/Simple-Chainlink.sol:27:3:
  |
27 |   constructor() VRFConsumerBase(__vrfCoordinatorAddress, __linkTokenAddress) public {
  |   ^ (Relevant source part starts here and spans across multiple lines).


TypeError: Immutable variables cannot be read during contract creation time, which means they cannot be read in the constructor or any function or modifier called from it.
  --> @chainlink/contracts/src/v0.8/VRFConsumerBase.sol:167:5:
   |
167 |     LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
   |     ^^^^

,TypeError: Immutable variables cannot be read during contract creation time, which means they cannot be read in the constructor or any function or modifier called from it.
  --> @chainlink/contracts/src/v0.8/VRFConsumerBase.sol:167:26:
   |
167 |     LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
   |                          ^^^^^^^^^^^^^^

我還沒有找到任何解決方案……chainlink庫本身有問題嗎?為什麼它不起作用???驗證這些錯誤發生在 Solidity 編譯器 0.6.x 和 0.8x 上

以下是一些會產生此錯誤的程式碼範例(直接取自 chainlink 文件):

// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.7;
pragma experimental ABIEncoderV2;

import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";

contract Example is VRFConsumerBase {

 //   on Kovan Network
 //   address vrfCoordinatorAddress  = 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9;
 //   address linkTokenAddress       = 0xa36085F69e2889c224210F604D836748e7dC0088;
 //   address oracleKeyhash          = 0x6c3699283bda56ad74f6b855546425b68d482e983852a7a82979cc4807b641f4;

 //   on Rinkeby Network
 address __vrfCoordinatorAddress  = 0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B;
 address __linkTokenAddress       = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709;
 bytes32 __oracleKeyhash          = 0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311;
 
 uint256 fee;
 bytes32 keyHash;

 constructor() VRFConsumerBase(__vrfCoordinatorAddress, __linkTokenAddress) public {

     keyHash = __oracleKeyhash;

     fee = 0.1 * 10 ** 18; // 0.1 Link
     
 }
 
 function getRandomNumber(uint256 userProvidedSeed) public returns (bytes32 requestId) {
     return requestRandomness(keyHash, fee);
 }
 
 function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
   
   // something  
 }
 
}

您可以在Solidity v0.8.8及更高版本的建構子中讀取不可變變數:

編譯器特性

  • 不可變變數一旦初始化就可以在構造時讀取。

您看到的是警告,而不是錯誤。它們不會阻止合約的編譯。

除此之外,您的程式碼與 Chainlink 文件中的VRF 程式碼範例不同。文件中的版本不會讀取建構子中的不可變變數,所有內容都是硬編碼的。

最後,如前所述,如果您將編譯器更改為 v0.8.8,您應該能夠阻止此警告的發生

引用自:https://ethereum.stackexchange.com/questions/111859