6

I was trying to print uint timeStamp by typing return timeStamp; right below return price; from this code:

pragma solidity ^0.6.7;

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

contract PriceConsumerV3 {

AggregatorV3Interface internal priceFeed;

/**
 * Network: Kovan
 * Aggregator: BTC/USD
 * Address: 0x6135b13325bfC4B00278B4abC5e20bbce2D6580e
 */
constructor() public {
    priceFeed = AggregatorV3Interface(0x6135b13325bfC4B00278B4abC5e20bbce2D6580e);
}

/**
 * Returns the latest price
 */
function getThePrice() public view returns (int) {
    (
        uint80 roundID, 
        int price,
        uint startedAt,
        uint timeStamp,
        uint80 answeredInRound
    ) = priceFeed.latestRoundData();
    return price;
    return timeStamp;
}
}

When I compiled the code above on the Remix Compiler, it replied:

TypeError: Return argument type uint256 is not implicitly convertible to expected type (type of first return variable) int256. return timeStamp; ^-------^

I tend to think that I would just have to type int256 return timeStamp or something similar instead of return timeStamp; but I can't figure it out.

Feedback is appreciated.

user3840170
  • 26,597
  • 4
  • 30
  • 62
NoahVerner
  • 937
  • 2
  • 9
  • 24

1 Answers1

10

You can typecast the uint to int using this syntax:

return int(timeStamp);

Note: This will overflow (in Solidity 0.7.x and older) or throw an exception (in Solidity 0.8+) for values between 2^255 (int max value) and 2^256-1 (uint max value). But this is most likely just a theoretical case, because timestamp is not expected to have this large value.


Mind that this line is unreachable, because you're already returning price on the previous line.

(
    uint80 roundID, 
    int price,
    uint startedAt,
    uint timeStamp,
    uint80 answeredInRound
) = priceFeed.latestRoundData();
return price; // the `price` is returned, and the function doesn't execute after this line
return timeStamp; // this is ignored because of the early return on previous line

If you want to return multiple values, you can use this syntax:

// note the multiple datatypes in the `returns` block
function getThePriceAndTimestamp() public view returns (int, uint) {
    (
        uint80 roundID, 
        int price,
        uint startedAt,
        uint timeStamp,
        uint80 answeredInRound
    ) = priceFeed.latestRoundData();
    return (price, timeStamp); // here returning multiple values
}
Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
  • Oh, btw, does the above mean the return statement can only be used once per function declared? – NoahVerner Jul 17 '21 at 18:36
  • 1
    You can use multiple returns. It makes sense in a conditional return (example: `if(user.isActive == false) { return 0; } else { return user.score; }`) ... Just in your particular case the second would be **always** ignored. – Petr Hejda Jul 17 '21 at 18:42
  • @PetrHejda I think you meant to say `2^255` instead of `2^255-1` in the note about the Solidity v0.8 exception? `2^255-1` is `type(int256).max`, and so it fits within `int256`. – Paul Razvan Berg Dec 01 '22 at 12:12
  • @PaulRazvanBerg Yes, that was my miscalculation. Thank you, I fixed in in the post. – Petr Hejda Dec 01 '22 at 14:48