| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-07 05:08:16 +02:00
										 |  |  | // Package common contains various helper functions. | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | package common | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"encoding/binary" | 
					
						
							| 
									
										
										
										
											2014-06-29 15:56:40 +01:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2014-05-28 23:16:54 +02:00
										 |  |  | 	"math/big" | 
					
						
							| 
									
										
										
										
											2014-06-18 11:55:05 +02:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-22 13:32:52 +01:00
										 |  |  | func ToHex(b []byte) string { | 
					
						
							|  |  |  | 	hex := Bytes2Hex(b) | 
					
						
							|  |  |  | 	// Prefer output of "0x0" instead of "0x" | 
					
						
							|  |  |  | 	if len(hex) == 0 { | 
					
						
							|  |  |  | 		hex = "0" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return "0x" + hex | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func FromHex(s string) []byte { | 
					
						
							|  |  |  | 	if len(s) > 1 { | 
					
						
							|  |  |  | 		if s[0:2] == "0x" { | 
					
						
							|  |  |  | 			s = s[2:] | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if len(s)%2 == 1 { | 
					
						
							|  |  |  | 			s = "0" + s | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return Hex2Bytes(s) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | type Bytes []byte | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (self Bytes) String() string { | 
					
						
							|  |  |  | 	return string(self) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func DeleteFromByteSlice(s [][]byte, hash []byte) [][]byte { | 
					
						
							|  |  |  | 	for i, h := range s { | 
					
						
							|  |  |  | 		if bytes.Compare(h, hash) == 0 { | 
					
						
							| 
									
										
										
										
											2014-10-02 17:03:36 +02:00
										 |  |  | 			return append(s[:i:i], s[i+1:]...) | 
					
						
							| 
									
										
										
										
											2014-09-15 15:42:12 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return s | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 17:15:44 +02:00
										 |  |  | // Number to bytes | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Returns the number in bytes with the specified base | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | func NumberToBytes(num interface{}, bits int) []byte { | 
					
						
							|  |  |  | 	buf := new(bytes.Buffer) | 
					
						
							|  |  |  | 	err := binary.Write(buf, binary.BigEndian, num) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("NumberToBytes failed:", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return buf.Bytes()[buf.Len()-(bits/8):] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 17:15:44 +02:00
										 |  |  | // Bytes to number | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Attempts to cast a byte slice to a unsigned integer | 
					
						
							| 
									
										
										
										
											2014-02-14 23:56:09 +01:00
										 |  |  | func BytesToNumber(b []byte) uint64 { | 
					
						
							|  |  |  | 	var number uint64 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Make sure the buffer is 64bits | 
					
						
							|  |  |  | 	data := make([]byte, 8) | 
					
						
							|  |  |  | 	data = append(data[:len(b)], b...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf := bytes.NewReader(data) | 
					
						
							|  |  |  | 	err := binary.Read(buf, binary.BigEndian, &number) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		fmt.Println("BytesToNumber failed:", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return number | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 17:15:44 +02:00
										 |  |  | // Read variable int | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Read a variable length number in big endian byte order | 
					
						
							| 
									
										
										
										
											2014-07-29 23:33:18 +02:00
										 |  |  | func ReadVarInt(buff []byte) (ret uint64) { | 
					
						
							|  |  |  | 	switch l := len(buff); { | 
					
						
							|  |  |  | 	case l > 4: | 
					
						
							|  |  |  | 		d := LeftPadBytes(buff, 8) | 
					
						
							|  |  |  | 		binary.Read(bytes.NewReader(d), binary.BigEndian, &ret) | 
					
						
							|  |  |  | 	case l > 2: | 
					
						
							|  |  |  | 		var num uint32 | 
					
						
							|  |  |  | 		d := LeftPadBytes(buff, 4) | 
					
						
							|  |  |  | 		binary.Read(bytes.NewReader(d), binary.BigEndian, &num) | 
					
						
							|  |  |  | 		ret = uint64(num) | 
					
						
							|  |  |  | 	case l > 1: | 
					
						
							|  |  |  | 		var num uint16 | 
					
						
							|  |  |  | 		d := LeftPadBytes(buff, 2) | 
					
						
							|  |  |  | 		binary.Read(bytes.NewReader(d), binary.BigEndian, &num) | 
					
						
							|  |  |  | 		ret = uint64(num) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		var num uint8 | 
					
						
							|  |  |  | 		binary.Read(bytes.NewReader(buff), binary.BigEndian, &num) | 
					
						
							|  |  |  | 		ret = uint64(num) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-29 12:36:27 +02:00
										 |  |  | // Copy bytes | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Returns an exact copy of the provided bytes | 
					
						
							|  |  |  | func CopyBytes(b []byte) (copiedBytes []byte) { | 
					
						
							|  |  |  | 	copiedBytes = make([]byte, len(b)) | 
					
						
							|  |  |  | 	copy(copiedBytes, b) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-05 15:48:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-02 15:53:04 +02:00
										 |  |  | func HasHexPrefix(str string) bool { | 
					
						
							|  |  |  | 	l := len(str) | 
					
						
							|  |  |  | 	return l >= 2 && str[0:2] == "0x" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-05 15:48:17 +02:00
										 |  |  | func IsHex(str string) bool { | 
					
						
							|  |  |  | 	l := len(str) | 
					
						
							|  |  |  | 	return l >= 4 && l%2 == 0 && str[0:2] == "0x" | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-28 13:14:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 15:56:40 +01:00
										 |  |  | func Bytes2Hex(d []byte) string { | 
					
						
							|  |  |  | 	return hex.EncodeToString(d) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Hex2Bytes(str string) []byte { | 
					
						
							|  |  |  | 	h, _ := hex.DecodeString(str) | 
					
						
							| 
									
										
										
										
											2014-07-26 11:24:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 15:56:40 +01:00
										 |  |  | 	return h | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-03 17:37:59 +02:00
										 |  |  | func Hex2BytesFixed(str string, flen int) []byte { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	h, _ := hex.DecodeString(str) | 
					
						
							|  |  |  | 	if len(h) == flen { | 
					
						
							|  |  |  | 		return h | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if len(h) > flen { | 
					
						
							|  |  |  | 			return h[len(h)-flen : len(h)] | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			hh := make([]byte, flen) | 
					
						
							|  |  |  | 			copy(hh[flen-len(h):flen], h[:]) | 
					
						
							|  |  |  | 			return hh | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-28 13:14:56 +02:00
										 |  |  | func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) { | 
					
						
							| 
									
										
										
										
											2014-06-18 11:55:05 +02:00
										 |  |  | 	if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") { | 
					
						
							| 
									
										
										
										
											2014-06-29 15:56:40 +01:00
										 |  |  | 		ret = Hex2Bytes(str[2:]) | 
					
						
							| 
									
										
										
										
											2014-05-28 13:14:56 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		ret = cb(str) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-05-28 23:16:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func FormatData(data string) []byte { | 
					
						
							|  |  |  | 	if len(data) == 0 { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Simple stupid | 
					
						
							|  |  |  | 	d := new(big.Int) | 
					
						
							|  |  |  | 	if data[0:1] == "\"" && data[len(data)-1:] == "\"" { | 
					
						
							| 
									
										
										
										
											2014-07-17 17:11:00 +02:00
										 |  |  | 		return RightPadBytes([]byte(data[1:len(data)-1]), 32) | 
					
						
							| 
									
										
										
										
											2014-05-28 23:16:54 +02:00
										 |  |  | 	} else if len(data) > 1 && data[:2] == "0x" { | 
					
						
							| 
									
										
										
										
											2014-06-29 15:56:40 +01:00
										 |  |  | 		d.SetBytes(Hex2Bytes(data[2:])) | 
					
						
							| 
									
										
										
										
											2014-05-28 23:16:54 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		d.SetString(data, 0) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return BigToBytes(d, 256) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-01 20:08:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 13:06:59 +02:00
										 |  |  | func ParseData(data ...interface{}) (ret []byte) { | 
					
						
							|  |  |  | 	for _, item := range data { | 
					
						
							|  |  |  | 		switch t := item.(type) { | 
					
						
							|  |  |  | 		case string: | 
					
						
							|  |  |  | 			var str []byte | 
					
						
							|  |  |  | 			if IsHex(t) { | 
					
						
							|  |  |  | 				str = Hex2Bytes(t[2:]) | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				str = []byte(t) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ret = append(ret, RightPadBytes(str, 32)...) | 
					
						
							|  |  |  | 		case []byte: | 
					
						
							|  |  |  | 			ret = append(ret, LeftPadBytes(t, 32)...) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 23:59:37 +02:00
										 |  |  | func RightPadBytes(slice []byte, l int) []byte { | 
					
						
							| 
									
										
										
										
											2014-07-02 00:06:21 +02:00
										 |  |  | 	if l < len(slice) { | 
					
						
							| 
									
										
										
										
											2014-07-01 20:08:48 +02:00
										 |  |  | 		return slice | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	padded := make([]byte, l) | 
					
						
							|  |  |  | 	copy(padded[0:len(slice)], slice) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return padded | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 23:59:37 +02:00
										 |  |  | func LeftPadBytes(slice []byte, l int) []byte { | 
					
						
							| 
									
										
										
										
											2014-07-02 00:06:21 +02:00
										 |  |  | 	if l < len(slice) { | 
					
						
							| 
									
										
										
										
											2014-07-01 20:08:48 +02:00
										 |  |  | 		return slice | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	padded := make([]byte, l) | 
					
						
							|  |  |  | 	copy(padded[l-len(slice):], slice) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return padded | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-16 13:20:57 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 13:05:26 +02:00
										 |  |  | func LeftPadString(str string, l int) string { | 
					
						
							|  |  |  | 	if l < len(str) { | 
					
						
							|  |  |  | 		return str | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return zeros + str | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func RightPadString(str string, l int) string { | 
					
						
							|  |  |  | 	if l < len(str) { | 
					
						
							|  |  |  | 		return str | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return str + zeros | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:59:52 +01:00
										 |  |  | func ToAddress(slice []byte) (addr []byte) { | 
					
						
							| 
									
										
										
										
											2014-07-16 13:20:57 +02:00
										 |  |  | 	if len(slice) < 20 { | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 		addr = LeftPadBytes(slice, 20) | 
					
						
							| 
									
										
										
										
											2014-07-16 13:20:57 +02:00
										 |  |  | 	} else if len(slice) > 20 { | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 		addr = slice[len(slice)-20:] | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		addr = slice | 
					
						
							| 
									
										
										
										
											2014-07-16 13:20:57 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-17 11:21:18 +02:00
										 |  |  | 	addr = CopyBytes(addr) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							| 
									
										
										
										
											2014-07-16 13:20:57 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-08-21 14:47:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | func ByteSliceToInterface(slice [][]byte) (ret []interface{}) { | 
					
						
							|  |  |  | 	for _, i := range slice { | 
					
						
							|  |  |  | 		ret = append(ret, i) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } |