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)
124 func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) {
125 if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") {
126 ret = Hex2Bytes(str[2:])
134 func FormatData(data string) []byte {
140 if data[0:1] == "\"" && data[len(data)-1:] == "\"" {
141 return RightPadBytes([]byte(data[1:len(data)-1]), 32)
142 } else if len(data) > 1 && data[:2] == "0x" {
143 d.SetBytes(Hex2Bytes(data[2:]))
148 return BigToBytes(d, 256)
151 func ParseData(data ...interface{}) (ret []byte) {
152 for _, item := range data {
153 switch t := item.(type) {
157 str = Hex2Bytes(t[2:])
162 ret = append(ret, RightPadBytes(str, 32)...)
164 ret = append(ret, LeftPadBytes(t, 32)...)
171 func RightPadBytes(slice []byte, l int) []byte {
176 padded := make([]byte, l)
177 copy(padded[0:len(slice)], slice)
182 func LeftPadBytes(slice []byte, l int) []byte {
187 padded := make([]byte, l)
188 copy(padded[l-len(slice):], slice)
193 func LeftPadString(str string, l int) string {
198 zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
204 func RightPadString(str string, l int) string {
209 zeros := Bytes2Hex(make([]byte, (l-len(str))/2))
214 func ByteSliceToInterface(slice [][]byte) (ret []interface{}) {
215 for _, i := range slice {
222 func Unit64ToBytes(n uint64) []byte {
223 buf := make([]byte, 8)
224 binary.LittleEndian.PutUint64(buf, n)
228 func BytesToUnit64(b []byte) uint64 {
229 return binary.LittleEndian.Uint64(b)