mirror of
https://github.com/luxfi/utils.git
synced 2026-10-30 15:13:57 +00:00
The set was Uint8/16/32/64 and Float32/64 — everything the P- and X-chains need and nothing the EVM does. A wei value, a token balance or a supply does not fit in 64 bits; an 18-decimal balance passes 2^64 at about 18.4 tokens. Every field of that shape reaching this boundary had to become a bare string or a hand-rolled big.Int at each site. uint256.Int rather than big.Int: a fixed-size value cannot be nil, so the zero Uint256 is zero rather than a panic, and it does not allocate. The module was already in the graph. It marshals as a quoted decimal like every type beside it, which is the point of this package — a JSON number is a float64, so even a uint64 above 2^53 does not survive one unquoted. The test asserts Uint64 REFUSES a value Uint256 accepts, which is the failure this type exists to prevent, and covers 2^256-1, null, and garbage.
42 lines
1.2 KiB
Go
42 lines
1.2 KiB
Go
// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package json
|
|
|
|
import "github.com/holiman/uint256"
|
|
|
|
// Uint256 is a 256-bit unsigned integer that marshals/unmarshals as a JSON
|
|
// string, like the narrower widths beside it.
|
|
//
|
|
// This is the width the EVM carries. A wei value, a token balance or a supply
|
|
// does not fit in 64 bits — an 18-decimal balance passes 2^64 at about 18.4
|
|
// tokens — so a field of that shape reaching this boundary previously had to
|
|
// be a bare string or a hand-rolled big.Int at every site.
|
|
//
|
|
// uint256.Int rather than big.Int: a fixed-size value cannot be nil, so a
|
|
// zero Uint256 is zero rather than a panic, and it does not allocate.
|
|
type Uint256 uint256.Int
|
|
|
|
func (u Uint256) MarshalJSON() ([]byte, error) {
|
|
v := uint256.Int(u)
|
|
return []byte(`"` + v.Dec() + `"`), nil
|
|
}
|
|
|
|
func (u *Uint256) UnmarshalJSON(b []byte) error {
|
|
str := string(b)
|
|
if str == Null {
|
|
return nil
|
|
}
|
|
if len(str) >= 2 {
|
|
if lastIndex := len(str) - 1; str[0] == '"' && str[lastIndex] == '"' {
|
|
str = str[1:lastIndex]
|
|
}
|
|
}
|
|
v, err := uint256.FromDecimal(str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*u = Uint256(*v)
|
|
return nil
|
|
}
|