Skip to content

Commit

Permalink
btcutil: format BTC amounts with trailing zeroes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
C-Otto committed Jun 18, 2023
1 parent 9c16d23 commit 48cdfb8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
18 changes: 16 additions & 2 deletions btcutil/amount.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"math"
"strconv"
"strings"
)

// AmountUnit describes a method of converting an Amount to something
Expand Down Expand Up @@ -101,11 +102,24 @@ 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
bitcoin := a.ToUnit(u)
formatted := strconv.FormatFloat(bitcoin, '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 {
decimalPoint := "."
before, after, containsDecimalPoint := strings.Cut(formatted, decimalPoint)
if containsDecimalPoint {
trailingZeroes := strings.Repeat("0", 8-len(after))
return before + decimalPoint + after + trailingZeroes + units
}
}
return formatted + units
}

// String is the equivalent of calling Format with AmountBTC.
Expand Down
18 changes: 16 additions & 2 deletions btcutil/amount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,22 @@ 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: "mBTC",
Expand Down
4 changes: 2 additions & 2 deletions btcutil/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 48cdfb8

Please sign in to comment.