From e5748e3ed324f9df7920284b0fee612c2fab1159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 1 Mar 2016 12:00:27 +0200 Subject: [PATCH] common, all: polish a lot of hex handling code --- cmd/geth/js_test.go | 2 +- common/bytes.go | 87 +++++++++++++++--------------- common/bytes_test.go | 51 +++++++++++++++--- common/natspec/natspec.go | 3 +- common/path.go | 4 +- common/registrar/ethreg/api.go | 4 +- common/registrar/registrar.go | 19 +++---- common/registrar/registrar_test.go | 2 +- common/types.go | 10 ++-- common/types_test.go | 35 ++++++++++++ core/bad_block.go | 4 +- core/state/dump.go | 9 ++-- core/tx_pool.go | 5 +- eth/api.go | 17 ++---- eth/filters/api.go | 2 +- logger/log.go | 8 +-- node/api.go | 2 +- rpc/types.go | 7 +-- rpc/utils.go | 4 +- tests/block_test_util.go | 2 +- whisper/api.go | 10 ++-- 21 files changed, 177 insertions(+), 110 deletions(-) diff --git a/cmd/geth/js_test.go b/cmd/geth/js_test.go index af435e68ce..5154e86af9 100644 --- a/cmd/geth/js_test.go +++ b/cmd/geth/js_test.go @@ -396,7 +396,7 @@ multiply7 = Multiply7.at(contractaddress); if sol != nil && solcVersion != sol.Version() { modContractInfo := versionRE.ReplaceAll(contractInfo, []byte(`"compilerVersion":"`+sol.Version()+`"`)) fmt.Printf("modified contractinfo:\n%s\n", modContractInfo) - contentHash = `"` + common.ToHex(crypto.Keccak256([]byte(modContractInfo))) + `"` + contentHash = `"` + common.BytesToHex(crypto.Keccak256([]byte(modContractInfo))) + `"` } if checkEvalJSON(t, repl, `filename = "/tmp/info.json"`, `"/tmp/info.json"`) != nil { return diff --git a/common/bytes.go b/common/bytes.go index 4fb016a976..7b1f74727b 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -23,29 +23,38 @@ import ( "encoding/hex" "fmt" "math/big" + "regexp" "strings" + + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/logger/glog" ) -func ToHex(b []byte) string { - hex := Bytes2Hex(b) - // Prefer output of "0x0" instead of "0x" - if len(hex) == 0 { - hex = "0" - } - return "0x" + hex +// BytesToHex converts a byte slice to hexadecimal notation, prefixed with 0x. +func BytesToHex(blob []byte) string { + return "0x" + hex.EncodeToString(blob) } -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) +// NumberToHex converts a byte slice to hexadecimal notation, prefixed with 0x, +// with the added rule that the empty slice is encoded as the zero value. +func NumberToHex(blob []byte) string { + if len(blob) == 0 { + return "0x0" } - return nil + return "0x" + hex.EncodeToString(blob) +} + +// FromHex parses a hex string into a byte slice. +func FromHex(s string) []byte { + // Cut off and optional 0x or 0X prefix + if len(s) > 2 && (s[:2] == "0x" || s[:2] == "0X") { + s = s[2:] + } + // Pad odd length strings to even ones + if len(s)%2 == 1 { + s = "0" + s + } + return Hex2Bytes(s) } // Number to bytes @@ -117,28 +126,29 @@ func CopyBytes(b []byte) (copiedBytes []byte) { return } -func HasHexPrefix(str string) bool { - l := len(str) - return l >= 2 && str[0:2] == "0x" -} +// isHexPattern is a regular expression to verify whether a string represents an +// abirarilly long hex number with or without the "0x" prefix. +var isHexPattern = regexp.MustCompile("^0(x|X)([0-9a-fA-F]{2})+$") +// IsHex checks whether a string is a valid hexadecimal number, consisting of +// only hex digits and prefixed with 0x or 0X. func IsHex(str string) bool { - l := len(str) - return l >= 4 && l%2 == 0 && str[0:2] == "0x" -} - -func Bytes2Hex(d []byte) string { - return hex.EncodeToString(d) + return isHexPattern.MatchString(str) } func Hex2Bytes(str string) []byte { - h, _ := hex.DecodeString(str) - + h, err := hex.DecodeString(str) + if err != nil { + glog.V(logger.Error).Infof("Invalid hex string to decode: %s: %v", str, err) + } return h } func Hex2BytesFixed(str string, flen int) []byte { - h, _ := hex.DecodeString(str) + h, err := hex.DecodeString(str) + if err != nil { + glog.V(logger.Error).Infof("Invalid hex string to decode: %s: %v", str, err) + } if len(h) == flen { return h } else { @@ -153,7 +163,7 @@ func Hex2BytesFixed(str string, flen int) []byte { } func StringToByteFunc(str string, cb func(str string) []byte) (ret []byte) { - if len(str) > 1 && str[0:2] == "0x" && !strings.Contains(str, "\n") { + if len(str) > 1 && (str[:2] == "0x" || str[:2] == "0X") && !strings.Contains(str, "\n") { ret = Hex2Bytes(str[2:]) } else { ret = cb(str) @@ -170,12 +180,11 @@ func FormatData(data string) []byte { d := new(big.Int) if data[0:1] == "\"" && data[len(data)-1:] == "\"" { return RightPadBytes([]byte(data[1:len(data)-1]), 32) - } else if len(data) > 1 && data[:2] == "0x" { + } else if len(data) > 1 && (data[:2] == "0x" || data[:2] == "0X") { d.SetBytes(Hex2Bytes(data[2:])) } else { d.SetString(data, 0) } - return BigToBytes(d, 256) } @@ -225,22 +234,14 @@ func LeftPadString(str string, l int) string { if l < len(str) { return str } - - zeros := Bytes2Hex(make([]byte, (l-len(str))/2)) - - return zeros + str - + return hex.EncodeToString(make([]byte, (l-len(str))/2)) + 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 - + return str + hex.EncodeToString(make([]byte, (l-len(str))/2)) } func ToAddress(slice []byte) (addr []byte) { diff --git a/common/bytes_test.go b/common/bytes_test.go index 2e52084777..fec8765338 100644 --- a/common/bytes_test.go +++ b/common/bytes_test.go @@ -83,16 +83,51 @@ func (s *BytesSuite) TestCopyBytes(c *checker.C) { } func (s *BytesSuite) TestIsHex(c *checker.C) { - data1 := "a9e67e" - exp1 := false - res1 := IsHex(data1) - c.Assert(res1, checker.DeepEquals, exp1) + tests := []struct { + data string + hex bool + }{ + // Ensure minimum length requirements pass + {"", false}, + {"0", false}, + {"00", false}, + {"0x", false}, + {"0x0", false}, + {"0x00", true}, - data2 := "0xa9e67e00" - exp2 := true - res2 := IsHex(data2) - c.Assert(res2, checker.DeepEquals, exp2) + // Ensure prefix is enforced + {"1234", false}, + {"abcdef", false}, + {"0_1234", false}, + {"0_abcdef", false}, + {"0x1234", true}, + {"0xabcdef", true}, + // Ensure even number of digits + {"0x333", false}, + {"0x4444", true}, + {"0x55555", false}, + {"0x666666", true}, + + // Ensure bad digits are caught + {"0xhi", false}, + {"0xhelloworld", false}, + {"0x0x00", false}, + + // Ensure both lower as well as upper case are accepted + {"0X1234", true}, + {"0Xabcdef", true}, + {"0xaCcDeF", true}, + {"0XaCcDeF", true}, + + // Random tests from previous suite + {"a9e67e", false}, + {"0xa9e67e00", true}, + } + + for _, tt := range tests { + c.Assert(IsHex(tt.data), checker.DeepEquals, tt.hex) + } } func (s *BytesSuite) TestParseDataString(c *checker.C) { diff --git a/common/natspec/natspec.go b/common/natspec/natspec.go index 8197018cf4..bc81075099 100644 --- a/common/natspec/natspec.go +++ b/common/natspec/natspec.go @@ -111,11 +111,12 @@ func FetchDocsForContract(contractAddress string, xeth *xeth.XEth, client *httpc codehex := xeth.CodeAt(contractAddress) codeb := xeth.CodeAtBytes(contractAddress) - if codehex == "0x" { + if codehex == "0x" || codehex == "0X" { err = fmt.Errorf("contract (%v) not found", contractAddress) return } codehash := common.BytesToHash(crypto.Keccak256(codeb)) + // set up nameresolver with natspecreg + urlhint contract addresses reg := registrar.New(xeth) diff --git a/common/path.go b/common/path.go index 75a8c1a3e0..32fcda1243 100644 --- a/common/path.go +++ b/common/path.go @@ -56,11 +56,11 @@ func FileExist(filePath string) bool { return true } -func AbsolutePath(Datadir string, filename string) string { +func AbsolutePath(datadir string, filename string) string { if filepath.IsAbs(filename) { return filename } - return filepath.Join(Datadir, filename) + return filepath.Join(datadir, filename) } func HomeDir() string { diff --git a/common/registrar/ethreg/api.go b/common/registrar/ethreg/api.go index 79a6c2191e..f8825ae580 100644 --- a/common/registrar/ethreg/api.go +++ b/common/registrar/ethreg/api.go @@ -183,7 +183,7 @@ func (be *registryAPIBackend) Call(fromStr, toStr, valueStr, gasStr, gasPriceStr gp := new(core.GasPool).AddGas(common.MaxBig) res, gas, err := core.ApplyMessage(vmenv, msg, gp) - return common.ToHex(res), gas.String(), err + return common.NumberToHex(res), gas.String(), err } // StorageAt returns the data stores in the state for the given address and location. @@ -199,7 +199,7 @@ func (be *registryAPIBackend) StorageAt(addr string, storageAddr string) string // Transact forms a transaction from the given arguments and submits it to the // transactio pool for execution. func (be *registryAPIBackend) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) { - if len(toStr) > 0 && toStr != "0x" && !common.IsHexAddress(toStr) { + if len(toStr) > 0 && toStr != "0x" && toStr != "0X" && !common.IsHexAddress(toStr) { return "", errors.New("invalid address") } diff --git a/common/registrar/registrar.go b/common/registrar/registrar.go index 0606f6985f..c52d28c462 100644 --- a/common/registrar/registrar.go +++ b/common/registrar/registrar.go @@ -18,6 +18,7 @@ package registrar import ( "encoding/binary" + "encoding/hex" "fmt" "math/big" "regexp" @@ -68,7 +69,7 @@ const ( ) func abiSignature(s string) string { - return common.ToHex(crypto.Keccak256([]byte(s))[:4]) + return common.BytesToHex(crypto.Keccak256([]byte(s))[:4]) } var ( @@ -282,8 +283,8 @@ func (self *Registrar) SetHashToHash(address common.Address, codehash, dochash c if err != nil { return } - codehex := common.Bytes2Hex(codehash[:]) - dochex := common.Bytes2Hex(dochash[:]) + codehex := hex.EncodeToString(codehash[:]) + dochex := hex.EncodeToString(dochash[:]) data := registerContentHashAbi + codehex + dochex glog.V(logger.Detail).Infof("SetHashToHash data: %s sent to %v\n", data, HashRegAddr) @@ -305,7 +306,7 @@ func (self *Registrar) SetUrlToHash(address common.Address, hash common.Hash, ur return "", fmt.Errorf("UrlHint address is not set") } - hashHex := common.Bytes2Hex(hash[:]) + hashHex := hex.EncodeToString(hash[:]) var urlHex string urlb := []byte(url) var cnt byte @@ -315,15 +316,15 @@ func (self *Registrar) SetUrlToHash(address common.Address, hash common.Hash, ur if n > 32 { n = 32 } - urlHex = common.Bytes2Hex(urlb[:n]) + urlHex = hex.EncodeToString(urlb[:n]) urlb = urlb[n:] n = len(urlb) bcnt := make([]byte, 32) bcnt[31] = cnt data := registerUrlAbi + hashHex + - common.Bytes2Hex(bcnt) + - common.Bytes2Hex(common.Hex2BytesFixed(urlHex, 32)) + hex.EncodeToString(bcnt) + + hex.EncodeToString(common.Hex2BytesFixed(urlHex, 32)) txh, err = self.backend.Transact( address.Hex(), UrlHintAddr, @@ -420,7 +421,7 @@ func storageFixedArray(addr, idx []byte) []byte { } func storageAddress(addr []byte) string { - return common.ToHex(addr) + return common.BytesToHex(addr) } func encodeAddress(address common.Address) string { @@ -428,7 +429,7 @@ func encodeAddress(address common.Address) string { } func encodeName(name string, index uint8) (string, string) { - extra := common.Bytes2Hex([]byte(name)) + extra := hex.EncodeToString([]byte(name)) if len(name) > 32 { return fmt.Sprintf("%064x", index), extra } diff --git a/common/registrar/registrar_test.go b/common/registrar/registrar_test.go index b2287803c2..e905f8ab9c 100644 --- a/common/registrar/registrar_test.go +++ b/common/registrar/registrar_test.go @@ -52,7 +52,7 @@ func (self *testBackend) initUrlHint() { mapaddr := storageMapping(storageIdx2Addr(1), hash[:]) key := storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(0))) - self.contracts[UrlHintAddr[2:]][key] = common.ToHex([]byte(url)) + self.contracts[UrlHintAddr[2:]][key] = common.NumberToHex([]byte(url)) key = storageAddress(storageFixedArray(mapaddr, storageIdx2Addr(1))) self.contracts[UrlHintAddr[2:]][key] = "0x0" } diff --git a/common/types.go b/common/types.go index b1666d7338..a92b5fd654 100644 --- a/common/types.go +++ b/common/types.go @@ -50,7 +50,7 @@ func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } func (h Hash) Str() string { return string(h[:]) } func (h Hash) Bytes() []byte { return h[:] } func (h Hash) Big() *big.Int { return Bytes2Big(h[:]) } -func (h Hash) Hex() string { return "0x" + Bytes2Hex(h[:]) } +func (h Hash) Hex() string { return BytesToHex(h[:]) } // UnmarshalJSON parses a hash in its hex from to a hash. func (h *Hash) UnmarshalJSON(input []byte) error { @@ -110,7 +110,8 @@ func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } // IsHexAddress verifies whether a string can represent a valid hex-encoded -// Ethereum address or not. +// Ethereum address or not. The accepted format is a 40 hex-character string, +// optionally prefixed by 0x or 0X. func IsHexAddress(s string) bool { if len(s) == 2+2*AddressLength && IsHex(s) { return true @@ -126,7 +127,7 @@ func (a Address) Str() string { return string(a[:]) } func (a Address) Bytes() []byte { return a[:] } func (a Address) Big() *big.Int { return Bytes2Big(a[:]) } func (a Address) Hash() Hash { return BytesToHash(a[:]) } -func (a Address) Hex() string { return "0x" + Bytes2Hex(a[:]) } +func (a Address) Hex() string { return BytesToHex(a[:]) } // Sets the address to the value of b. If b is larger than len(a) it will panic func (a *Address) SetBytes(b []byte) { @@ -182,8 +183,7 @@ func (a *Address) UnmarshalJSON(data []byte) error { // hex(value[:4])...(hex[len(value)-4:]) func PP(value []byte) string { if len(value) <= 8 { - return Bytes2Hex(value) + return hex.EncodeToString(value) } - return fmt.Sprintf("%x...%x", value[:4], value[len(value)-4]) } diff --git a/common/types_test.go b/common/types_test.go index edf8d4d142..f890759cf2 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -29,3 +29,38 @@ func TestBytesConversion(t *testing.T) { t.Errorf("expected %x got %x", exp, hash) } } + +// Tests whether addresses are correctly matched against allowed form and data +// content. +func TestIsHexAddress(t *testing.T) { + tests := []struct { + address string + valid bool + }{ + {"", false}, // Empty, without optional 0x prefix + {"0x", false}, // Empty, with optional 0x prefix + {"00", false}, // Too short, without optional 0x prefix + {"0x00", false}, // Too short, with optional 0x prefix + {"00000000000000000000000000000000000000", false}, // Too short (even), without optional 0x prefix + {"0x00000000000000000000000000000000000000", false}, // Too short (even), with optional 0x prefix + {"000000000000000000000000000000000000000", false}, // Too short (odd), without optional 0x prefix + {"0x000000000000000000000000000000000000000", false}, // Too short (odd), with optional 0x prefix + {"0000000000000000000000000000000000000000", true}, // Valid, without optional 0x prefix + {"0x0000000000000000000000000000000000000000", true}, // Valid, with optional 0x prefix + {"0x00000000000000000000000000000000000000", false}, // Length / prefix combo invalidity + {"00x0000000000000000000000000000000000000", false}, // Invalid content, without optional 0x prefix + {"0x0x00000000000000000000000000000000000000", false}, // Invalid content, with optional 0x prefix + {"abcdefghijklmnopqrstuvwxyz0123456789xxxx", false}, // Invalid content, without optional 0x prefix + {"0xabcdefghijklmnopqrstuvwxyz0123456789xxxx", false}, // Invalid content, with optional 0x prefix + {"00000000000000000000000000000000000000000", false}, // Too long (odd), without optional 0x prefix + {"0x00000000000000000000000000000000000000000", false}, // Too long (odd), with optional 0x prefix + {"000000000000000000000000000000000000000000", false}, // Too long (even), without optional 0x prefix + {"0x000000000000000000000000000000000000000000", false}, // Too long (even), with optional 0x prefix + } + + for i, tt := range tests { + if valid := IsHexAddress(tt.address); valid != tt.valid { + t.Errorf("test %d: address validity mismatch: have %v, want %v", i, valid, tt.valid) + } + } +} diff --git a/core/bad_block.go b/core/bad_block.go index cd3fb575a8..a52e433ea2 100644 --- a/core/bad_block.go +++ b/core/bad_block.go @@ -18,11 +18,11 @@ package core import ( "bytes" + "encoding/hex" "encoding/json" "io/ioutil" "net/http" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger/glog" @@ -43,7 +43,7 @@ func ReportBlock(block *types.Block, err error) { blockRlp, _ := rlp.EncodeToBytes(block) data := map[string]interface{}{ - "block": common.Bytes2Hex(blockRlp), + "block": hex.EncodeToString(blockRlp), "errortype": err.Error(), "hints": map[string]interface{}{ "receipts": "NYI", diff --git a/core/state/dump.go b/core/state/dump.go index 8eb03e8e44..663b2e588d 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -17,6 +17,7 @@ package state import ( + "encoding/hex" "encoding/json" "fmt" @@ -39,7 +40,7 @@ type World struct { func (self *StateDB) RawDump() World { world := World{ - Root: common.Bytes2Hex(self.trie.Root()), + Root: hex.EncodeToString(self.trie.Root()), Accounts: make(map[string]Account), } @@ -48,14 +49,14 @@ func (self *StateDB) RawDump() World { addr := self.trie.GetKey(it.Key) stateObject, _ := DecodeObject(common.BytesToAddress(addr), self.db, it.Value) - account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: common.Bytes2Hex(stateObject.Root()), CodeHash: common.Bytes2Hex(stateObject.codeHash), Code: common.Bytes2Hex(stateObject.Code())} + account := Account{Balance: stateObject.balance.String(), Nonce: stateObject.nonce, Root: hex.EncodeToString(stateObject.Root()), CodeHash: hex.EncodeToString(stateObject.codeHash), Code: hex.EncodeToString(stateObject.Code())} account.Storage = make(map[string]string) storageIt := stateObject.trie.Iterator() for storageIt.Next() { - account.Storage[common.Bytes2Hex(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(storageIt.Value) + account.Storage[hex.EncodeToString(self.trie.GetKey(storageIt.Key))] = hex.EncodeToString(storageIt.Value) } - world.Accounts[common.Bytes2Hex(addr)] = account + world.Accounts[hex.EncodeToString(addr)] = account } return world } diff --git a/core/tx_pool.go b/core/tx_pool.go index b8fb4cd357..6f78144566 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -17,6 +17,7 @@ package core import ( + "encoding/hex" "errors" "fmt" "math/big" @@ -288,14 +289,14 @@ func (self *TxPool) add(tx *types.Transaction) error { if glog.V(logger.Debug) { var toname string if to := tx.To(); to != nil { - toname = common.Bytes2Hex(to[:4]) + toname = hex.EncodeToString(to[:4]) } else { toname = "[NEW_CONTRACT]" } // we can ignore the error here because From is // verified in ValidateTransaction. f, _ := tx.From() - from := common.Bytes2Hex(f[:4]) + from := hex.EncodeToString(f[:4]) glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, hash) } diff --git a/eth/api.go b/eth/api.go index 38b67a07a8..8e568070ae 100644 --- a/eth/api.go +++ b/eth/api.go @@ -582,11 +582,7 @@ func (s *PublicBlockChainAPI) GetCode(address common.Address, blockNr rpc.BlockN if state == nil || err != nil { return "", err } - res := state.GetCode(address) - if len(res) == 0 { // backwards compatibility - return "0x", nil - } - return common.ToHex(res), nil + return common.BytesToHex(state.GetCode(address)), nil } // GetStorageAt returns the storage from the state at the given address, key and @@ -671,10 +667,7 @@ func (s *PublicBlockChainAPI) doCall(args CallArgs, blockNr rpc.BlockNumber) (st gp := new(core.GasPool).AddGas(common.MaxBig) res, gas, err := core.ApplyMessage(vmenv, msg, gp) - if len(res) == 0 { // backwards compatibility - return "0x", gas, err - } - return common.ToHex(res), gas, err + return common.BytesToHex(res), gas, err } // Call executes the given transaction on the state for the given block number. @@ -1102,7 +1095,7 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(encodedTx string) (string, // be unlocked. func (s *PublicTransactionPoolAPI) Sign(address common.Address, data string) (string, error) { signature, error := s.am.Sign(accounts.Account{Address: address}, common.HexToHash(data).Bytes()) - return common.ToHex(signature), error + return common.BytesToHex(signature), error } type SignTransactionArgs struct { @@ -1194,7 +1187,7 @@ func newTx(t *types.Transaction) *Tx { From: from, Value: rpc.NewHexNumber(t.Value()), Nonce: rpc.NewHexNumber(t.Nonce()), - Data: "0x" + common.Bytes2Hex(t.Data()), + Data: common.BytesToHex(t.Data()), GasLimit: rpc.NewHexNumber(t.Gas()), GasPrice: rpc.NewHexNumber(t.GasPrice()), Hash: t.Hash(), @@ -1241,7 +1234,7 @@ func (s *PublicTransactionPoolAPI) SignTransaction(args *SignTransactionArgs) (* return nil, err } - return &SignTransactionResult{"0x" + common.Bytes2Hex(data), newTx(tx)}, nil + return &SignTransactionResult{common.BytesToHex(data), newTx(tx)}, nil } // PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of diff --git a/eth/filters/api.go b/eth/filters/api.go index 6cd184b808..b7f04a6481 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -573,7 +573,7 @@ func newFilterId() (string, error) { if n != 16 { return "", errors.New("Unable to generate filter id") } - return "0x" + hex.EncodeToString(subid[:]), nil + return common.BytesToHex(subid[:]), nil } // toRPCLogs is a helper that will convert a vm.Logs array to an structure which diff --git a/logger/log.go b/logger/log.go index 38a6ce1391..dba9987f4d 100644 --- a/logger/log.go +++ b/logger/log.go @@ -21,12 +21,14 @@ import ( "io" "log" "os" - - "github.com/ethereum/go-ethereum/common" + "path/filepath" ) func openLogFile(datadir string, filename string) *os.File { - path := common.AbsolutePath(datadir, filename) + path := filename + if !filepath.IsAbs(path) { + path = filepath.Join(datadir, filename) + } file, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) if err != nil { panic(fmt.Sprintf("error opening log file '%s': %v", filename, err)) diff --git a/node/api.go b/node/api.go index 8a25784104..567199eae5 100644 --- a/node/api.go +++ b/node/api.go @@ -269,5 +269,5 @@ func (s *PublicWeb3API) ClientVersion() string { // Sha3 applies the ethereum sha3 implementation on the input. // It assumes the input is hex encoded. func (s *PublicWeb3API) Sha3(input string) string { - return common.ToHex(crypto.Keccak256(common.FromHex(input))) + return common.BytesToHex(crypto.Keccak256(common.FromHex(input))) } diff --git a/rpc/types.go b/rpc/types.go index f268d84db2..069d93168f 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -24,6 +24,7 @@ import ( "strings" "sync" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" "gopkg.in/fatih/set.v0" ) @@ -220,11 +221,7 @@ func (h *HexNumber) UnmarshalJSON(input []byte) error { // MarshalJSON serialize the hex number instance to a hex representation. func (h *HexNumber) MarshalJSON() ([]byte, error) { if h != nil { - hn := (*big.Int)(h) - if hn.BitLen() == 0 { - return []byte(`"0x0"`), nil - } - return []byte(fmt.Sprintf(`"0x%x"`, hn)), nil + return []byte(`"` + common.NumberToHex((*big.Int)(h).Bytes()) + `"`), nil } return nil, nil } diff --git a/rpc/utils.go b/rpc/utils.go index fa114284dd..45ef3dd219 100644 --- a/rpc/utils.go +++ b/rpc/utils.go @@ -18,7 +18,6 @@ package rpc import ( "crypto/rand" - "encoding/hex" "errors" "fmt" "math/big" @@ -26,6 +25,7 @@ import ( "unicode" "unicode/utf8" + "github.com/ethereum/go-ethereum/common" "golang.org/x/net/context" ) @@ -211,7 +211,7 @@ func newSubscriptionId() (string, error) { if n != 16 { return "", errors.New("Unable to generate subscription id") } - return "0x" + hex.EncodeToString(subid[:]), nil + return common.BytesToHex(subid[:]), nil } // SupportedModules returns the collection of API's that the RPC server offers diff --git a/tests/block_test_util.go b/tests/block_test_util.go index f517eddd1d..954e7ef1ae 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -437,7 +437,7 @@ func (test *BlockTest) ValidateImportedHeaders(cm *core.BlockChain, validBlocks // all blocks have been processed by ChainManager, as they may not // be part of the longest chain until last block is imported. for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlock(b.Header().ParentHash) { - bHash := common.Bytes2Hex(b.Hash().Bytes()) // hex without 0x prefix + bHash := hex.EncodeToString(b.Hash().Bytes()) // hex without 0x prefix if err := validateHeader(bmap[bHash].BlockHeader, b.Header()); err != nil { return fmt.Errorf("Imported block header validation failed: %v", err) } diff --git a/whisper/api.go b/whisper/api.go index 575b9bc894..be2f52e196 100644 --- a/whisper/api.go +++ b/whisper/api.go @@ -74,7 +74,7 @@ func (s *PublicWhisperAPI) NewIdentity() (string, error) { } identity := s.w.NewIdentity() - return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil + return common.BytesToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil } type NewFilterArgs struct { @@ -403,11 +403,11 @@ func NewWhisperMessage(message *Message) WhisperMessage { return WhisperMessage{ ref: message, - Payload: common.ToHex(message.Payload), - From: common.ToHex(crypto.FromECDSAPub(message.Recover())), - To: common.ToHex(crypto.FromECDSAPub(message.To)), + Payload: common.BytesToHex(message.Payload), + From: common.BytesToHex(crypto.FromECDSAPub(message.Recover())), + To: common.BytesToHex(crypto.FromECDSAPub(message.To)), Sent: message.Sent.Unix(), TTL: int64(message.TTL / time.Second), - Hash: common.ToHex(message.Hash.Bytes()), + Hash: common.BytesToHex(message.Hash.Bytes()), } }