1 // Package common contains various helper functions.
11 log "github.com/sirupsen/logrus"
14 func ToHex(b []byte) string {
16 // Prefer output of "0x0" instead of "0x"
23 func FromHex(s string) []byte {
38 // Returns the number in bytes with the specified base
39 func NumberToBytes(num interface{}, bits int) []byte {
40 buf := new(bytes.Buffer)
41 err := binary.Write(buf, binary.BigEndian, num)
43 log.WithField("err", err).Error("NumberToBytes failed")
46 return buf.Bytes()[buf.Len()-(bits/8):]
51 // Attempts to cast a byte slice to a unsigned integer
52 func BytesToNumber(b []byte) uint64 {
55 // Make sure the buffer is 64bits
56 data := make([]byte, 8)
57 data = append(data[:len(b)], b...)
59 buf := bytes.NewReader(data)
60 err := binary.Read(buf, binary.BigEndian, &number)
62 log.WithField("err", err).Error("BytesToNumber failed")
70 // Read a variable length number in big endian byte order
71 func ReadVarInt(buff []byte) (ret uint64) {
72 switch l := len(buff); {
74 d := LeftPadBytes(buff, 8)
75 binary.Read(bytes.NewReader(d), binary.BigEndian, &ret)
78 d := LeftPadBytes(buff, 4)
79 binary.Read(bytes.NewReader(d), binary.BigEndian, &num)
83 d := LeftPadBytes(buff, 2)
84 binary.Read(bytes.NewReader(d), binary.BigEndian, &num)
88 binary.Read(bytes.NewReader(buff), binary.BigEndian, &num)
97 // Returns an exact copy of the provided bytes
98 func CopyBytes(b []byte) (copiedBytes []byte) {
99 copiedBytes = make([]byte, len(b))
105 func HasHexPrefix(str string) bool {
107 return l >= 2 && str[0:2] == "0x"
110 func IsHex(str string) bool {
112 return l >= 4 && l%2 == 0 && str[0:2] == "0x"
115 func Bytes2Hex(d []byte) string {
116 return hex.EncodeToString(d)
119 func Hex2Bytes(str string) []byte {
120 h, _ := hex.DecodeString(str)
125 func Hex2BytesFixed(str string, flen int) []byte {
126 h, _ := hex.DecodeString(str)
131 return h[len(h)-flen : len(h)]
133 hh := make([]byte, flen)
134 copy(hh[flen-len(h):flen], h[:])
140 func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
141 if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") {
142 ret = Hex2Bytes(str[2:])
150 func FormatData(data string) []byte {
156 if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
157 return RightPadBytes([]byte(data[1:len(data)-1]), 32)
158 } else if len(data) > 1 && data[:2] == "0x" {
159 d.SetBytes(Hex2Bytes(data[2:]))
164 return BigToBytes(d, 256)
167 func ParseData(data ...interface{}) (ret []byte) {
168 for _, item := range data {
169 switch t := item.(type) {
173 str = Hex2Bytes(t[2:])
178 ret = append(ret, RightPadBytes(str, 32)...)
180 ret = append(ret, LeftPadBytes(t, 32)...)
187 func RightPadBytes(slice []byte, l int) []byte {
192 padded := make([]byte, l)
193 copy(padded[0:len(slice)], slice)
198 func LeftPadBytes(slice []byte, l int) []byte {
203 padded := make([]byte, l)
204 copy(padded[l-len(slice):], slice)
209 func LeftPadString(str string, l int) string {
214 zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
220 func RightPadString(str string, l int) string {
225 zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
231 func ToAddress(slice []byte) (addr []byte) {
233 addr = LeftPadBytes(slice, 20)
234 } else if len(slice) > 20 {
235 addr = slice[len(slice)-20:]
240 addr = CopyBytes(addr)
245 func ByteSliceToInterface(slice [][]byte) (ret []interface{}) {
246 for _, i := range slice {
253 func Unit64ToBytes(n uint64) []byte {
254 buf := make([]byte, 8)
255 binary.LittleEndian.PutUint64(buf, n)
259 func BytesToUnit64(b []byte) uint64 {
260 return binary.LittleEndian.Uint64(b)