0

my smart contract uses an Oracle to retrieve the price. The price is returned as a string in scientific notation, for example, "3e-8". How I can convert this to number (uint)? The token has 18 decimals, so the final value in this example should be 30000000000.

EtherPaul
  • 256
  • 3
  • 10
  • Be aware that this (and string manipulation in general) is going to be costly. – goodvibration Jul 14 '20 at 15:33
  • I know but do I have no choice, as the API returns data in such format – EtherPaul Jul 14 '20 at 15:35
  • Well, first question that arises - does it ALWAYS come in that format (i.e., e<+->)? Or does it possibly come in regular decimal notation? – goodvibration Jul 14 '20 at 15:40
  • This is the rate of myToken/ETH, so unless myToken is worth not a lot, it will come in that notation. I am using coingecko API. – EtherPaul Jul 14 '20 at 15:43
  • You didn't answer the question! – goodvibration Jul 14 '20 at 16:02
  • I don't know, I started working on this project yesterday. For now, it always comes like that, but who knows if in the future Coingecko decides to change their API. – EtherPaul Jul 14 '20 at 16:07
  • So you have a bit of a dependency problem here. I've never heard of this Coingecko service that you're mentioning, but I'd assume that they have some sort of way to configure this output, which in its current form is a problem not only to you, but to anyone else using this service. If they're not aware of that, then they will be when they find out that all of their clients are compelled to resolve this problem in their contracts. It is worse enough to parse a regular decimal string, let alone one that comes in scientific notation (let alone one that may come in both notations alternating). – goodvibration Jul 14 '20 at 16:10
  • Provable has a parseInt function but it converts 3e-8 to 38 (probably just skips all the non integers in string), so it doesn't solve the issue. – EtherPaul Jul 14 '20 at 16:14
  • Share this function here and someone will be able to adjust it to your needs. – goodvibration Jul 14 '20 at 16:15
  • There are no other APIs that I am aware of that returns the price of this token. Also, coingecko API is public, so it is easily implemented. – EtherPaul Jul 14 '20 at 16:16
  • I am importing provable and it is providing me parseInt out the box, the code for it can be found here: https://github.com/provable-things/ethereum-api/blob/master/provableAPI_0.6.sol – EtherPaul Jul 14 '20 at 16:17
  • There are more than 1300 lines of code in there! Please do a little bit of an effort, find that function and post it as part of your question. – goodvibration Jul 14 '20 at 16:21
  • What do you mean API? Do you receive that string in an off-chain script, and then send it as is to your contract??? – goodvibration Jul 14 '20 at 16:22
  • yes, you can play with this API: https://www.coingecko.com/api/documentations/v3 Provable allows calling and getting values from off-chain. – EtherPaul Jul 14 '20 at 16:41
  • You mean 3e8 == 300000000. 3e-8 == 0.00000003, which is simply zero if you tried to represent that as a uint256. – Luke Hutchison Jun 05 '22 at 01:43

2 Answers2

0

You're either going to have to find a library that does this, or write some string parsing yourself, to extract the signed number after the "e", add that to the ERC20's decimals() return value, and multiply the number before the "e" by 10**result. Other answers have suggested available Solidity code for parsing, but if you roll your own you'll need to do string slicing and character access. Search around.

Solidity: extracting (slicing) characters from a string

0

You can use the Provable's Computation Datasource, to do that https://docs.provable.xyz/#data-sources-computation.

Your use case resembles this example here https://github.com/provable-things/ethereum-examples/tree/master/solidity/computation-datasource/url-requests

Just make the relevant request to Coingecko inside a python script and then make the conversion you would expect onchain.

Please note that ARG0, ARG1, ARG2 you find inside the url-requests.py script

arg = [os.environ['ARG0'], os.environ['ARG1']]

parse 3rd arg into kwargs if available

if 'ARG2' in os.environ: kwargs = ast.literal_eval(os.environ['ARG2']) else: kwargs = {}

are environment variables defined at Docker level, relative to the values defined into the array given to the oraclize_query function defined inside UrlRequests.sol code.

The first element of the array specified should contain the IPFS multihash of the uploaded archive. (The value returned by IPFS add archive.zip) Then ARG0, ARG1, ... follows

Mauro
  • 1