github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/binary/word256.go (about) 1 // Copyright Monax Industries Limited 2 // SPDX-License-Identifier: Apache-2.0 3 4 package binary 5 6 import ( 7 "bytes" 8 "encoding/binary" 9 "fmt" 10 "math/big" 11 "sort" 12 13 "github.com/tmthrgd/go-hex" 14 ) 15 16 var ( 17 Zero256 = Word256{} 18 One256 = LeftPadWord256([]byte{1}) 19 ) 20 21 const Word256Bytes = 32 22 const Word256Bits = Word256Bytes * 8 23 24 var BigWord256Bytes = big.NewInt(Word256Bytes) 25 26 var trimCutSet = string([]byte{0}) 27 28 type Word256 [Word256Bytes]byte 29 30 func (w *Word256) UnmarshalText(hexBytes []byte) error { 31 bs, err := hex.DecodeString(string(hexBytes)) 32 if err != nil { 33 return err 34 } 35 copy(w[:], bs) 36 return nil 37 } 38 39 func (w Word256) MarshalText() ([]byte, error) { 40 return []byte(w.String()), nil 41 } 42 43 func (w Word256) String() string { 44 return hex.EncodeUpperToString(w[:]) 45 } 46 47 func (w Word256) Copy() Word256 { 48 return w 49 } 50 51 func (w Word256) Bytes() []byte { 52 return w[:] 53 } 54 55 // copied. 56 func (w Word256) Prefix(n int) []byte { 57 return w[:n] 58 } 59 60 func (w Word256) Postfix(n int) []byte { 61 return w[32-n:] 62 } 63 64 // Get a Word160 embedded a Word256 and padded on the left (as it is for account addresses in EVM) 65 func (w Word256) Word160() (w160 Word160) { 66 copy(w160[:], w[Word256Word160Delta:]) 67 return 68 } 69 70 func (w Word256) IsZero() bool { 71 accum := byte(0) 72 for _, byt := range w { 73 accum |= byt 74 } 75 return accum == 0 76 } 77 78 func (w Word256) Compare(other Word256) int { 79 return bytes.Compare(w[:], other[:]) 80 } 81 82 func (w Word256) UnpadLeft() []byte { 83 return bytes.TrimLeft(w[:], trimCutSet) 84 } 85 86 func (w Word256) UnpadRight() []byte { 87 return bytes.TrimRight(w[:], trimCutSet) 88 } 89 90 // Gogo proto support 91 func (w *Word256) Marshal() ([]byte, error) { 92 if w == nil { 93 return nil, nil 94 } 95 return w.Bytes(), nil 96 } 97 98 func (w *Word256) Unmarshal(data []byte) error { 99 if len(data) == 0 { 100 return nil 101 } 102 if len(data) != Word256Bytes { 103 return fmt.Errorf("error unmarshallling Word256 '%X' from bytes: %d bytes but should have %d bytes", 104 data, len(data), Word256Bytes) 105 } 106 copy(w[:], data) 107 return nil 108 } 109 110 func (w *Word256) MarshalTo(data []byte) (int, error) { 111 if w == nil { 112 return 0, nil 113 } 114 return copy(data, w[:]), nil 115 } 116 117 func (w Word256) Size() int { 118 return Word256Bytes 119 } 120 121 func Uint64ToWord256(i uint64) (word Word256) { 122 binary.BigEndian.PutUint64(word[24:], i) 123 return 124 } 125 126 func Uint64FromWord256(word Word256) uint64 { 127 return binary.BigEndian.Uint64(word.Postfix(8)) 128 } 129 130 func Int64ToWord256(i int64) Word256 { 131 return BigIntToWord256(SignExtend(big.NewInt(i), Word256Bits)) 132 } 133 134 func Int64FromWord256(word Word256) int64 { 135 return BigIntFromWord256(word).Int64() 136 } 137 138 func BigIntToWord256(x *big.Int) Word256 { 139 return LeftPadWord256(U256(x).Bytes()) 140 } 141 142 func BigIntFromWord256(word Word256) *big.Int { 143 return S256(new(big.Int).SetBytes(word[:])) 144 } 145 146 func RightPadWord256(bz []byte) (word Word256) { 147 copy(word[:], bz) 148 return 149 } 150 151 func LeftPadWord256(bz []byte) (word Word256) { 152 copy(word[32-len(bz):], bz) 153 return 154 } 155 156 //------------------------------------- 157 158 type Words256 []Word256 159 160 func (ws Words256) Len() int { 161 return len(ws) 162 } 163 164 func (ws Words256) Less(i, j int) bool { 165 return ws[i].Compare(ws[j]) < 0 166 } 167 168 func (ws Words256) Swap(i, j int) { 169 ws[i], ws[j] = ws[j], ws[i] 170 } 171 172 type Tuple256 struct { 173 First Word256 174 Second Word256 175 } 176 177 func (tuple Tuple256) Compare(other Tuple256) int { 178 firstCompare := tuple.First.Compare(other.First) 179 if firstCompare == 0 { 180 return tuple.Second.Compare(other.Second) 181 } else { 182 return firstCompare 183 } 184 } 185 186 func Tuple256Split(t Tuple256) (Word256, Word256) { 187 return t.First, t.Second 188 } 189 190 type Tuple256Slice []Tuple256 191 192 func (p Tuple256Slice) Len() int { return len(p) } 193 func (p Tuple256Slice) Less(i, j int) bool { 194 return p[i].Compare(p[j]) < 0 195 } 196 func (p Tuple256Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 197 func (p Tuple256Slice) Sort() { sort.Sort(p) }