btcutil: format BTC amounts with trailing zeroes

so that sat amounts can be read without counting zeroes

before:
 350sat = 0.0000035 BTC
3500sat = 0.000035 BTC

after:
 350sat = 0.00000350 BTC
3500sat = 0.00003500 BTC

fixes #1995
This commit is contained in:
Carsten Otto 2023-06-18 10:15:20 +02:00
parent f5eeb10d03
commit 725b36bf09
3 changed files with 38 additions and 6 deletions

View File

@ -6,8 +6,10 @@ package btcutil
import (
"errors"
"fmt"
"math"
"strconv"
"strings"
)
// AmountUnit describes a method of converting an Amount to something
@ -101,11 +103,20 @@ func (a Amount) ToBTC() float64 {
// Format formats a monetary amount counted in bitcoin base units as a
// string for a given unit. The conversion will succeed for any unit,
// however, known units will be formated with an appended label describing
// however, known units will be formatted with an appended label describing
// the units with SI notation, or "Satoshi" for the base unit.
func (a Amount) Format(u AmountUnit) string {
units := " " + u.String()
return strconv.FormatFloat(a.ToUnit(u), 'f', -int(u+8), 64) + units
formatted := strconv.FormatFloat(a.ToUnit(u), 'f', -int(u+8), 64)
// When formatting full BTC, add trailing zeroes for numbers
// with decimal point to ease reading of sat amount.
if u == AmountBTC {
if strings.Contains(formatted, ".") {
return fmt.Sprintf("%.8f%s", a.ToUnit(u), units)
}
}
return formatted + units
}
// String is the equivalent of calling Format with AmountBTC.

View File

@ -136,8 +136,29 @@ func TestAmountUnitConversions(t *testing.T) {
name: "BTC",
amount: 44433322211100,
unit: AmountBTC,
converted: 444333.22211100,
s: "444333.222111 BTC",
converted: 444333.222111,
s: "444333.22211100 BTC",
},
{
name: "a thousand satoshi as BTC",
amount: 1000,
unit: AmountBTC,
converted: 0.00001,
s: "0.00001000 BTC",
},
{
name: "a single satoshi as BTC",
amount: 1,
unit: AmountBTC,
converted: 0.00000001,
s: "0.00000001 BTC",
},
{
name: "amount with trailing zero but no decimals",
amount: 1000000000,
unit: AmountBTC,
converted: 10,
s: "10 BTC",
},
{
name: "mBTC",

View File

@ -20,7 +20,7 @@ func ExampleAmount() {
// Output:
// Zero Satoshi: 0 BTC
// 100,000,000 Satoshis: 1 BTC
// 100,000 Satoshis: 0.001 BTC
// 100,000 Satoshis: 0.00100000 BTC
}
func ExampleNewAmount() {
@ -69,7 +69,7 @@ func ExampleAmount_unitConversions() {
// Output:
// Satoshi to kBTC: 444.333222111 kBTC
// Satoshi to BTC: 444333.222111 BTC
// Satoshi to BTC: 444333.22211100 BTC
// Satoshi to MilliBTC: 444333222.111 mBTC
// Satoshi to MicroBTC: 444333222111 μBTC
// Satoshi to Satoshi: 44433322211100 Satoshi