RPC option to report bitcoins in satoshi units. #3249

issue gastonmorixe opened this issue on November 14, 2013
  1. gastonmorixe commented at 9:35 AM on November 14, 2013: none

    I think the proper way to report bitcoin is in satoshi units, the smallest unit today.

    To not break compatibility with current RPC clients, I think of adding this in a opt-in way. There could be a setting called something like "RPC-unit-satoshis" or the like.

    I'd love to hear why this arguments against it.

    Thanks, ton.

  2. laanwj commented at 10:24 AM on November 14, 2013: member

    Personally I don't like this. The 10^-8 is an implementation detail. It makes sense to use it internally in programs, but I don't like exposing it on interfaces.

    Changing this now also leaves open the way to disaster, imagine what could happen if a site used the wrong unit in RPC.

    We had a similar discussion for BIP 0021 (Bitcoin URI scheme). Eventually we decided to simply use a BTC amount instead of messing around with different units/representations as that is most straightforward and clear.

  3. schildbach commented at 10:39 AM on November 14, 2013: contributor

    Yes, and also we can now be sure implementations can deal with fractional numbers. If we had started with Satoshis, everyone would have used integers and the switch to fractions of Satoshis would be more prone to errors.

  4. jgarzik commented at 12:20 PM on November 14, 2013: contributor

    Given all the problems with existing floating point implementations, and existing JSON implementations, and how use of floating point has already lead to incorrect values following a multiplication or division etc. I have always supported the use of satoshis -- all integer -- in the RPC interface.

    However, given that that decision was made years ago, backwards compat makes it difficult to switch now. Even a "use-satoshis" option is not without danger, as @laanwj indicates. I do not think it is a large danger, because an error would likely result in sending too little rather than sending too much. But it is still a danger.

  5. laanwj commented at 12:38 PM on November 14, 2013: member

    @jgarzik That's a completely different discussion. JSON always represents numbers as doubles (well that's not strictly true I should say almost all implementations do). Moving the decimal point around does not solve that.

    But I'd be all for "send coin amounts as strings instead of numbers" option, so that people may be less tempted to use floating point for monetary values with all the risk it entails. This would also be pretty harmless if misconfigured (result in parse errors not incorrect amounts).

  6. super3 commented at 7:23 PM on November 15, 2013: contributor

    If you place it in config like the others said that might lead to terrible mistakes. Although I think it would be reasonable to add it in the actual RPC call. For example,

     bitcoin-cli getbalance --satoshi
    

    Or something to that effect. I'd rather this be implemented in a wrapper than the core client.

  7. laanwj commented at 8:34 AM on November 21, 2013: member

    Sorry, I'm going to close this. Adding additional options just because some like their RPC values a shade of green instead of purple is a certain way toward madness. Adding the option will just give more maintenance and testing complexity.

    A choice was made once to use BTC and there is no convincing reason to switch to anything else. Also it is easy enough to provide a wrapper that converts the values to whatever unit you like.

  8. laanwj closed this on Nov 21, 2013

  9. laanwj commented at 10:28 AM on November 21, 2013: member

    Reopening, I may have been too trigger happy, though I still think it's a terrible idea to just change the multiplication factor, as it does nothing to fix precision issues that people are having from JSON RPC implementations. If anything, it would hide inherent floating point precision issues (and would keep using double internally for monetary amounts just as happily).

  10. laanwj reopened this on Nov 21, 2013

  11. luke-jr commented at 10:47 AM on November 21, 2013: member

    @laanwj bitcoind doesn't use double for monetary amounts internally at all... not sure what you mean by that?

  12. laanwj commented at 10:53 AM on November 21, 2013: member

    @luke-jr We're talking about users of the API here, not so much bitcoind itself.

  13. gastonmorixe commented at 1:24 AM on November 22, 2013: none

    Guys, I still thinking that an opt-in config option would not hurt anyone, but will clearly make conversions way easier and safer for the ones who opt to use it. I may not see your points though.

  14. super3 commented at 1:34 AM on November 22, 2013: contributor

    @imton What language are you using?

  15. gastonmorixe commented at 1:47 AM on November 22, 2013: none

    @super3 I am using RoR, and I took all measures to handle them safely, using RubyMoney/money & money-rails gem.

    Still, It will be better if I didn't even have to convert them back from float to handle satoshis as int, as I do in ruby money.

  16. laanwj commented at 3:38 AM on November 22, 2013: member

    @imton The point is there is nothing safer in returning large values instead of smaller, up-to-8-digit precision JSON values. The problem is that javascript (which is at the base of JSON), as well as many other implementations, use doubles for number representation. Double is a floating point format, which means that the mantissa has a limited precision, not the number of decimals after the dot.

    Sure, you can patch your JSON RPC parser to use integers instead, or maybe yours does already, but if you are going to patch your JSON RPC parser you can do it just as well in the current situation: make it return a Decimal or fixed point format for numbers.

    Btw @luke-jr, what you say is not entirely correct, we indeed use uint64 as internal format but we do use doubles in the intermediate conversion for JSON RPC, see

    int64_t AmountFromValue(const Value& value)
    {
        double dAmount = value.get_real();
        if (dAmount <= 0.0 || dAmount > 21000000.0)
            throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
        int64_t nAmount = roundint64(dAmount * COIN);
        if (!MoneyRange(nAmount))
            throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
        return nAmount;
    }
    
    Value ValueFromAmount(int64_t amount)
    {
        return (double)amount / (double)COIN;
    }
    

    This has caused an issue at least once with an upgrade of json::spirit. #3126 which somehow formatted numbers differently.

    When we'd use strings we could avoid converting to double intermediate format at all and be fixed-point all the way to the client.

  17. laanwj commented at 6:15 PM on May 2, 2014: member

    The -rpcamount option that's added in #3759 allows this. Please help testing.

  18. laanwj commented at 8:08 AM on July 31, 2014: member

    I had a pull (#3759) open for a long time that exposed this option and no one bothered to even test it. Seems very-low priority so I'm closing this issue.

    A future JSON-RPC interface revision will likely switch to integer, satoshi units, but these are far-future plans (see #3806).

  19. laanwj closed this on Jul 31, 2014

  20. gastonmorixe commented at 11:25 AM on July 31, 2014: none

    Thanks anyway

  21. gdm85 commented at 2:53 PM on January 15, 2015: contributor

    @laanwj do you think it would be possible to repropose/re-open #3759? I am willing to rebase it if there's some consensus/interest

  22. laanwj commented at 8:28 AM on January 16, 2015: member

    @gdm85 As discussed on IRC - I think you'll find zero interest in that in practice. The RPC interface is just what it is, clients have grown to our interface instead of the other way around, and too much would be broken by changing that.

  23. gdm85 commented at 8:43 AM on January 16, 2015: contributor

    @laanwj yes, agree. Your idea of a future library approach sounds interesting, although I'd prefer also to see a reference RPC implementation in @bitcoin here on github.

  24. Bushstar referenced this in commit 3b0f8ff8b3 on Apr 8, 2020
  25. Bushstar referenced this in commit d2c85b9ea1 on Apr 8, 2020
  26. MarcoFalke locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-26 09:16 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me