github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/util/uint256.go (about) 1 package util 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "encoding/json" 7 "fmt" 8 "strings" 9 10 "github.com/nspcc-dev/neo-go/pkg/io" 11 "github.com/nspcc-dev/neo-go/pkg/util/slice" 12 ) 13 14 // Uint256Size is the size of Uint256 in bytes. 15 const Uint256Size = 32 16 17 // Uint256 is a 32 byte long unsigned integer. 18 type Uint256 [Uint256Size]uint8 19 20 // Uint256DecodeStringLE attempts to decode the given string (in LE representation) into a Uint256. 21 func Uint256DecodeStringLE(s string) (u Uint256, err error) { 22 if len(s) != Uint256Size*2 { 23 return u, fmt.Errorf("expected string size of %d got %d", Uint256Size*2, len(s)) 24 } 25 b, err := hex.DecodeString(s) 26 if err != nil { 27 return u, err 28 } 29 slice.Reverse(b) 30 return Uint256DecodeBytesBE(b) 31 } 32 33 // Uint256DecodeStringBE attempts to decode the given string (in BE representation) 34 // into a Uint256. 35 func Uint256DecodeStringBE(s string) (u Uint256, err error) { 36 if len(s) != Uint256Size*2 { 37 return u, fmt.Errorf("expected string size of %d got %d", Uint256Size*2, len(s)) 38 } 39 40 b, err := hex.DecodeString(s) 41 if err != nil { 42 return u, err 43 } 44 45 return Uint256DecodeBytesBE(b) 46 } 47 48 // Uint256DecodeBytesBE attempts to decode the given string (in BE representation) into a Uint256. 49 func Uint256DecodeBytesBE(b []byte) (u Uint256, err error) { 50 if len(b) != Uint256Size { 51 return u, fmt.Errorf("expected []byte of size %d got %d", Uint256Size, len(b)) 52 } 53 copy(u[:], b) 54 return u, nil 55 } 56 57 // Uint256DecodeBytesLE attempts to decode the given string (in LE representation) into a Uint256. 58 func Uint256DecodeBytesLE(b []byte) (u Uint256, err error) { 59 b = slice.CopyReverse(b) 60 return Uint256DecodeBytesBE(b) 61 } 62 63 // BytesBE returns a byte slice representation of u. 64 func (u Uint256) BytesBE() []byte { 65 return u[:] 66 } 67 68 // Reverse reverses the Uint256 object. 69 func (u Uint256) Reverse() Uint256 { 70 res, _ := Uint256DecodeBytesLE(u.BytesBE()) 71 return res 72 } 73 74 // BytesLE return a little-endian byte representation of u. 75 func (u Uint256) BytesLE() []byte { 76 return slice.CopyReverse(u.BytesBE()) 77 } 78 79 // Equals returns true if both Uint256 values are the same. 80 func (u Uint256) Equals(other Uint256) bool { 81 return u == other 82 } 83 84 // String implements the stringer interface. 85 func (u Uint256) String() string { 86 return u.StringBE() 87 } 88 89 // StringBE produces string representation of Uint256 with BE byte order. 90 func (u Uint256) StringBE() string { 91 return hex.EncodeToString(u.BytesBE()) 92 } 93 94 // StringLE produces string representation of Uint256 with LE byte order. 95 func (u Uint256) StringLE() string { 96 return hex.EncodeToString(u.BytesLE()) 97 } 98 99 // UnmarshalJSON implements the json unmarshaller interface. 100 func (u *Uint256) UnmarshalJSON(data []byte) (err error) { 101 var js string 102 if err = json.Unmarshal(data, &js); err != nil { 103 return err 104 } 105 js = strings.TrimPrefix(js, "0x") 106 *u, err = Uint256DecodeStringLE(js) 107 return err 108 } 109 110 // MarshalJSON implements the json marshaller interface. 111 func (u Uint256) MarshalJSON() ([]byte, error) { 112 r := make([]byte, 3+Uint256Size*2+1) 113 copy(r, `"0x`) 114 r[len(r)-1] = '"' 115 slice.Reverse(u[:]) // u is a copy, so we can mangle it in any way. 116 hex.Encode(r[3:], u[:]) 117 return r, nil 118 } 119 120 // CompareTo compares two Uint256 with each other. Possible output: 1, -1, 0 121 // 122 // 1 implies u > other. 123 // -1 implies u < other. 124 // 0 implies u = other. 125 func (u Uint256) CompareTo(other Uint256) int { return bytes.Compare(u[:], other[:]) } 126 127 // EncodeBinary implements the io.Serializable interface. 128 func (u *Uint256) EncodeBinary(w *io.BinWriter) { 129 w.WriteBytes(u[:]) 130 } 131 132 // DecodeBinary implements the io.Serializable interface. 133 func (u *Uint256) DecodeBinary(r *io.BinReader) { 134 r.ReadBytes(u[:]) 135 }