5

Is it possible to get the current price of ETH in USD in a buyTokens function of a deployed solidity smart contract?

For instance, every time GETH starts up is determines the price of ETH during initialization.

Or, is the real way to do it with pre-calculation on a site using web3 to interact with the smart contract once it determines the USD value?

Thank you in advance!

4

You can get data through an oracle that calls an API, as blockchains themselves can't call APIs

Here is how to get data through a decentralized price feed. You can see a list of contract addresses and their price pair in the chainlink price feeds documentation.

pragma solidity ^0.6.0;

import "github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/interfaces/AggregatorInterface.sol";

contract ReferenceConsumer {
  AggregatorInterface internal ref;
  // For ETH-USD on ropsten, input the address:
  // 0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507

  constructor(address _aggregator) public {
    ref = AggregatorInterface(_aggregator);
  }

  function getLatestAnswer() public view returns (int256) {
    return ref.latestAnswer();
  }
}

A more thorough explanation and example of using Chainlink Price Feeds can be found on the Chainlink blog.

As @crissi mentioned, you can use an oracle like Chainlink or Oraclize to call an external API. Using it from one source means that it also has a single source of failure for your smart contract, so ideally, you'd pull from a decentralized node service. See Chainlink again for more information here.

Decentralized Price Feed

Another simpler method you could use that doesn't call an external API would be to use a Chainlink Reference Contract. All you need to do is get the address of the aggregator contract. For ETH-USD on ropsten, that address is 0x8468b2bDCE073A157E560AA4D9CcF6dB1DB98507. You can find a list of supported mainnet addresses here and testnet/mainnet addresses here.

These reference contracts are updated by a decentralized set of nodes to get the most recent price, without having the same single point of failure a centralized node has.

If you want to create your own group of centralized nodes to get the price, you can pull chainlink nodes as well with.

You can also pull from centralized nodes in Chainlink, but ideally you'd pull from a node network.

See this blog post for more information on external data collection.

Disclosure, I am the author of this blog post

3
  • 1
    Nice one Patrick. – Mikko Ohtamaa Jun 24 '20 at 8:21
  • 1
    The imported contract on github does not exist. – Alireza Zojaji Jun 24 '20 at 8:42
  • Fixed the broken github path, good call. – Patrick Collins Jun 24 '20 at 15:34
1

You can use any external APIs for this.

Inorder to call external APIs in contract, you have to use oraclize service.

Sample code for your reference:

    pragma solidity ^0.4.16;
    import "./usingOraclize.sol";  //Importing Oraclize
    contract TestOraclizeCall is usingOraclize {
            uint public price;
           event Log(string text);
           //Constructor
           function TestOraclizeCall() {
                 OAR = OraclizeAddrResolverI(0x5049063e4a7704ac155e4f1f42a4954bbef5bbde);
            }
      function __callback(bytes32 _myid, string _result) {
                 require (msg.sender == oraclize_cbAddress());
                 Log(_result);
                  price = parseInt(_result, 2);
        }
        function update() payable {
                oraclize_query("URL","json(https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD).USD");
        }

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.