如何使用 ChainLink Solidity 智能合约修复 TypeError 和 DeclarationError?

How fix TypeError and DeclarationError with ChainLink Solidity smart contract?

我创建了一个智能合约,如果 ETH 的价格在锁定期间下降,则向每个用户return 存入的金额 + 一定金额。代码的最后一部分有两个问题。

第一个涉及绘制用户存款时以太坊的价格。我尝试了几种解决方案,但其中 none 似乎有效。问题出现在第 64 行mapping(uint => uint) ethPrice;。控制台 returns:

DeclarationError: Identifier already declared.
--> oracle.sol:65:5:
|
65 | mapping(uint => uint) ethPrice;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note: The previous declaration is here:
--> oracle.sol:63:5:
|
63 | uint public ethPrice = 0; 
| ^^^^^^^^^^^^^^^^^^^^^^^^

第二个在第 1 行找到。 91.msg.sender.transfer(amountToWithdraw);同传递函数。尽管在前面的函数中每个用户的地址都定义为 payable,但控制台继续 return 以下错误。控制台 returns:

TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".
--> oracle.sol:97:9:
|
97 | msg.sender.transfer(amountToWithdraw);
| ^^^^^^^^^^^^^^^^^^^

这两个问题严重导致智能合约失效,阻碍了最新功能的编码完成。我已经联系了几个人并查看了有关 solidity 编程的论坛,但似乎没有人能回答我的问题。

我希望我的问题能得到社区的解答,并能帮助任何其他人在未来尝试将 ChainLink 与 Solidity 结合使用。我很乐意听取有关此事的任何建议。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;


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

    // EACAggregatorProxy is used for chainlink oracle
interface EACAggregatorProxy {
    function latestAnswer() external view returns (int256);
}

contract oracleLink {

    // Address dev
    address public dev;
    // Dev's public deposit amount
    uint public devDeposit;
    // Array dev's public amount
    uint[] public devDeposits;

    // List each user and amount
    address[] public users;                   
    uint[] public totalDeposited;  

    // Mapping user's deposit
    mapping(address => uint) balances;

    // Deployer = dev & Dev deposit function 
    function deployerIsDeveloper() public payable {
        dev = msg.sender;
        devDeposit = msg.value;
        devDeposits.push(devDeposit);                   
    }

    // User's address
    address user;
    // Amount's address 
    uint amountDeposit;
    // Deadline time 
    uint256 deadline;

    // Amount's each user
    uint256 lockAmount = lockAmounts[msg.sender];
    // Mapping of deposit for each user        
    mapping(address => uint) lockAmounts;

    // Timestamp for each user 
    uint256 startTime = startTimes[block.timestamp];
    // Mapping timestamp for each user  
    mapping(uint => uint) startTimes; 

    // Kovan ETH/USD oracle address 
    address public chainLinkETHUSDAddress = 0x9326BFA02ADD2366b30bacB125260Af641031331;

    // ethPrice 
    uint public ethPrice = 0; 
    uint256 price = ethPrice;
    mapping(uint => uint) ethPrice;

    // Deposit function for each user 
    function deposit(uint256 numberOfSeconds) public payable {

        lockAmounts[msg.sender] = msg.value;
        startTimes[block.timestamp] = block.timestamp;
        
        user = msg.sender;           
        amountDeposit = msg.value;      
        
        users.push(user);                     
        totalDeposited.push(amountDeposit);

        deadline = block.timestamp + (numberOfSeconds * 1 seconds);

        int256 chainLinkEthPrice = EACAggregatorProxy(chainLinkETHUSDAddress).latestAnswer();
        ethPrice = uint(chainLinkEthPrice / 100000000);
        //return ethPrice = price;
        //price.push(ethPrice);
    }

    // Withdraw function for each user 
    function withdraw() public payable {
        require(block.timestamp >= deadline);
        uint amountToWithdraw = lockAmounts[msg.sender];
        lockAmounts[msg.sender] = 0; 
        msg.sender.transfer(amountToWithdraw); 
    }
}

对于第一个问题,Solidity 编译器说您用标识符声明了两个变量。在您的案例的详细信息中,您为 mappinguint 变量提供了 ethPrice。要解决此问题,请尝试以这种方式更改其中一个名称:

 uint256 price = ethPrice;
 mapping(uint => uint) mappingEthPrice;

第二个问题是 msg.sender 关键字不会自动转换为应付地址,要解决这个问题,您可以使用 payable() 函数,该函数允许您将 address 转换为 address payable. 在您的智能合约中,您必须以这种方式更改:

payable(msg.sender).transfer(amountToWithdraw); 

这应该是您修复的智能合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;


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

    // EACAggregatorProxy is used for chainlink oracle
interface EACAggregatorProxy {
    function latestAnswer() external view returns (int256);
}

contract oracleLink {

    // Address dev
    address public dev;
    // Dev's public deposit amount
    uint public devDeposit;
    // Array dev's public amount
    uint[] public devDeposits;

    // List each user and amount
    address[] public users;                   
    uint[] public totalDeposited;  

    // Mapping user's deposit
    mapping(address => uint) balances;

    // Deployer = dev & Dev deposit function 
    function deployerIsDeveloper() public payable {
        dev = msg.sender;
        devDeposit = msg.value;
        devDeposits.push(devDeposit);                   
    }

    // User's address
    address user;
    // Amount's address 
    uint amountDeposit;
    // Deadline time 
    uint256 deadline;

    // Amount's each user
    uint256 lockAmount = lockAmounts[msg.sender];
    // Mapping of deposit for each user        
    mapping(address => uint) lockAmounts;

    // Timestamp for each user 
    uint256 startTime = startTimes[block.timestamp];
    // Mapping timestamp for each user  
    mapping(uint => uint) startTimes; 

    // Kovan ETH/USD oracle address 
    address public chainLinkETHUSDAddress = 0x9326BFA02ADD2366b30bacB125260Af641031331;

    // ethPrice 
    uint public ethPrice = 0; 
    uint256 price = ethPrice;
    mapping(uint => uint) mappingEthPrice;

    // Deposit function for each user 
    function deposit(uint256 numberOfSeconds) public payable {

        lockAmounts[msg.sender] = msg.value;
        startTimes[block.timestamp] = block.timestamp;
        
        user = msg.sender;           
        amountDeposit = msg.value;      
        
        users.push(user);                     
        totalDeposited.push(amountDeposit);

        deadline = block.timestamp + (numberOfSeconds * 1 seconds);

        int256 chainLinkEthPrice = EACAggregatorProxy(chainLinkETHUSDAddress).latestAnswer();
        ethPrice = uint(chainLinkEthPrice / 100000000);
        //return ethPrice = price;
        //price.push(ethPrice);
    }

    // Withdraw function for each user 
    function withdraw() public payable {
        require(block.timestamp >= deadline);
        uint amountToWithdraw = lockAmounts[msg.sender];
        lockAmounts[msg.sender] = 0; 
        payable(msg.sender).transfer(amountToWithdraw); 
    }
}