diff --git a/eth/api.go b/eth/api.go
index 2cc9c843d74fcc8bc10dec8551225f84688cfed3..6010d149cc6c54afbd8513a96183ec9225c3703a 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -31,6 +31,7 @@ import (
 
 	"github.com/ethereum/ethash"
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/state"
 	"github.com/ethereum/go-ethereum/core/types"
@@ -69,8 +70,8 @@ func (s *PublicEthereumAPI) Coinbase() (common.Address, error) {
 }
 
 // Hashrate returns the POW hashrate
-func (s *PublicEthereumAPI) Hashrate() *rpc.HexNumber {
-	return rpc.NewHexNumber(s.e.Miner().HashRate())
+func (s *PublicEthereumAPI) Hashrate() hexutil.Uint64 {
+	return hexutil.Uint64(s.e.Miner().HashRate())
 }
 
 // PublicMinerAPI provides an API to control the miner.
@@ -95,8 +96,8 @@ func (s *PublicMinerAPI) Mining() bool {
 
 // SubmitWork can be used by external miner to submit their POW solution. It returns an indication if the work was
 // accepted. Note, this is not an indication if the provided work was valid!
-func (s *PublicMinerAPI) SubmitWork(nonce rpc.HexNumber, solution, digest common.Hash) bool {
-	return s.agent.SubmitWork(nonce.Uint64(), digest, solution)
+func (s *PublicMinerAPI) SubmitWork(nonce hexutil.Uint64, solution, digest common.Hash) bool {
+	return s.agent.SubmitWork(uint64(nonce), digest, solution)
 }
 
 // GetWork returns a work package for external miner. The work package consists of 3 strings
@@ -119,8 +120,8 @@ func (s *PublicMinerAPI) GetWork() (work [3]string, err error) {
 // SubmitHashrate can be used for remote miners to submit their hash rate. This enables the node to report the combined
 // hash rate of all miners which submit work through this node. It accepts the miner hash rate and an identifier which
 // must be unique between nodes.
-func (s *PublicMinerAPI) SubmitHashrate(hashrate rpc.HexNumber, id common.Hash) bool {
-	s.agent.SubmitHashrate(id, hashrate.Uint64())
+func (s *PublicMinerAPI) SubmitHashrate(hashrate hexutil.Uint64, id common.Hash) bool {
+	s.agent.SubmitHashrate(id, uint64(hashrate))
 	return true
 }
 
@@ -137,18 +138,15 @@ func NewPrivateMinerAPI(e *Ethereum) *PrivateMinerAPI {
 
 // Start the miner with the given number of threads. If threads is nil the number of
 // workers started is equal to the number of logical CPU's that are usable by this process.
-func (s *PrivateMinerAPI) Start(threads *rpc.HexNumber) (bool, error) {
+func (s *PrivateMinerAPI) Start(threads *hexutil.Uint) (bool, error) {
 	s.e.StartAutoDAG()
-
+	var err error
 	if threads == nil {
-		threads = rpc.NewHexNumber(runtime.NumCPU())
-	}
-
-	err := s.e.StartMining(threads.Int())
-	if err == nil {
-		return true, nil
+		err = s.e.StartMining(runtime.NumCPU())
+	} else {
+		err = s.e.StartMining(int(*threads))
 	}
-	return false, err
+	return err == nil, err
 }
 
 // Stop the miner
@@ -166,8 +164,8 @@ func (s *PrivateMinerAPI) SetExtra(extra string) (bool, error) {
 }
 
 // SetGasPrice sets the minimum accepted gas price for the miner.
-func (s *PrivateMinerAPI) SetGasPrice(gasPrice rpc.HexNumber) bool {
-	s.e.Miner().SetGasPrice(gasPrice.BigInt())
+func (s *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
+	s.e.Miner().SetGasPrice((*big.Int)(&gasPrice))
 	return true
 }
 
diff --git a/eth/bind.go b/eth/bind.go
index 747965d37038e8d765e94c6113cf427c8936bd10..6f7aee4f75f9a6ccc732b7806602a2cab8e4dae8 100644
--- a/eth/bind.go
+++ b/eth/bind.go
@@ -21,6 +21,7 @@ import (
 
 	"github.com/ethereum/go-ethereum"
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/internal/ethapi"
 	"github.com/ethereum/go-ethereum/rlp"
@@ -86,13 +87,13 @@ func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs {
 		Data: common.ToHex(msg.Data),
 	}
 	if msg.Gas != nil {
-		args.Gas = *rpc.NewHexNumber(msg.Gas)
+		args.Gas = hexutil.Big(*msg.Gas)
 	}
 	if msg.GasPrice != nil {
-		args.GasPrice = *rpc.NewHexNumber(msg.GasPrice)
+		args.GasPrice = hexutil.Big(*msg.GasPrice)
 	}
 	if msg.Value != nil {
-		args.Value = *rpc.NewHexNumber(msg.Value)
+		args.Value = hexutil.Big(*msg.Value)
 	}
 	return args
 }
@@ -106,9 +107,12 @@ func toBlockNumber(num *big.Int) rpc.BlockNumber {
 
 // PendingAccountNonce implements bind.ContractTransactor retrieving the current
 // pending nonce associated with an account.
-func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
+func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Address) (nonce uint64, err error) {
 	out, err := b.txapi.GetTransactionCount(ctx, account, rpc.PendingBlockNumber)
-	return out.Uint64(), err
+	if out != nil {
+		nonce = uint64(*out)
+	}
+	return nonce, err
 }
 
 // SuggestGasPrice implements bind.ContractTransactor retrieving the currently
@@ -124,7 +128,7 @@ func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error)
 // should provide a basis for setting a reasonable default.
 func (b *ContractBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (*big.Int, error) {
 	out, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg))
-	return out.BigInt(), err
+	return out.ToInt(), err
 }
 
 // SendTransaction implements bind.ContractTransactor injects the transaction
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 85e37d31ef5a5b70de9cd12fe3cbc03aee97a52e..cd6beedd98f83d80ead48be92bfc73717d4976b5 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -19,7 +19,6 @@ package ethapi
 import (
 	"bytes"
 	"encoding/hex"
-	"encoding/json"
 	"fmt"
 	"math/big"
 	"strings"
@@ -44,7 +43,7 @@ import (
 	"golang.org/x/net/context"
 )
 
-const defaultGas = uint64(90000)
+const defaultGas = 90000
 
 // PublicEthereumAPI provides an API to access Ethereum related information.
 // It offers only methods that operate on public data that is freely available to anyone.
@@ -63,8 +62,8 @@ func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*big.Int, error) {
 }
 
 // ProtocolVersion returns the current Ethereum protocol version this node supports
-func (s *PublicEthereumAPI) ProtocolVersion() *rpc.HexNumber {
-	return rpc.NewHexNumber(s.b.ProtocolVersion())
+func (s *PublicEthereumAPI) ProtocolVersion() hexutil.Uint {
+	return hexutil.Uint(s.b.ProtocolVersion())
 }
 
 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not
@@ -83,11 +82,11 @@ func (s *PublicEthereumAPI) Syncing() (interface{}, error) {
 	}
 	// Otherwise gather the block sync stats
 	return map[string]interface{}{
-		"startingBlock": rpc.NewHexNumber(progress.StartingBlock),
-		"currentBlock":  rpc.NewHexNumber(progress.CurrentBlock),
-		"highestBlock":  rpc.NewHexNumber(progress.HighestBlock),
-		"pulledStates":  rpc.NewHexNumber(progress.PulledStates),
-		"knownStates":   rpc.NewHexNumber(progress.KnownStates),
+		"startingBlock": hexutil.Uint64(progress.StartingBlock),
+		"currentBlock":  hexutil.Uint64(progress.CurrentBlock),
+		"highestBlock":  hexutil.Uint64(progress.HighestBlock),
+		"pulledStates":  hexutil.Uint64(progress.PulledStates),
+		"knownStates":   hexutil.Uint64(progress.KnownStates),
 	}, nil
 }
 
@@ -129,11 +128,11 @@ func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransac
 }
 
 // Status returns the number of pending and queued transaction in the pool.
-func (s *PublicTxPoolAPI) Status() map[string]*rpc.HexNumber {
+func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint {
 	pending, queue := s.b.Stats()
-	return map[string]*rpc.HexNumber{
-		"pending": rpc.NewHexNumber(pending),
-		"queued":  rpc.NewHexNumber(queue),
+	return map[string]hexutil.Uint{
+		"pending": hexutil.Uint(pending),
+		"queued":  hexutil.Uint(queue),
 	}
 }
 
@@ -238,13 +237,14 @@ func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (commo
 // UnlockAccount will unlock the account associated with the given address with
 // the given password for duration seconds. If duration is nil it will use a
 // default of 300 seconds. It returns an indication if the account was unlocked.
-func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *rpc.HexNumber) (bool, error) {
+func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *hexutil.Uint) (bool, error) {
+	var d time.Duration
 	if duration == nil {
-		duration = rpc.NewHexNumber(300)
+		d = 300 * time.Second
+	} else {
+		d = time.Duration(*duration) * time.Second
 	}
-	a := accounts.Account{Address: addr}
-	d := time.Duration(duration.Int64()) * time.Second
-	if err := s.am.TimedUnlock(a, password, d); err != nil {
+	if err := s.am.TimedUnlock(accounts.Account{Address: addr}, password, d); err != nil {
 		return false, err
 	}
 	return true, nil
@@ -259,27 +259,10 @@ func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool {
 // tries to sign it with the key associated with args.To. If the given passwd isn't
 // able to decrypt the key it fails.
 func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
-	var err error
-	args, err = prepareSendTxArgs(ctx, args, s.b)
-	if err != nil {
+	if err := args.setDefaults(ctx, s.b); err != nil {
 		return common.Hash{}, err
 	}
-
-	if args.Nonce == nil {
-		nonce, err := s.b.GetPoolNonce(ctx, args.From)
-		if err != nil {
-			return common.Hash{}, err
-		}
-		args.Nonce = rpc.NewHexNumber(nonce)
-	}
-
-	var tx *types.Transaction
-	if args.To == nil {
-		tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
-	} else {
-		tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
-	}
-
+	tx := args.toTransaction()
 	signer := types.MakeSigner(s.b.ChainConfig(), s.b.CurrentBlock().Number())
 	signature, err := s.am.SignWithPassphrase(args.From, passwd, signer.Hash(tx).Bytes())
 	if err != nil {
@@ -399,15 +382,15 @@ func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash comm
 
 // GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true
 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
-func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (map[string]interface{}, error) {
+func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) {
 	block, err := s.b.BlockByNumber(ctx, blockNr)
 	if block != nil {
 		uncles := block.Uncles()
-		if index.Int() < 0 || index.Int() >= len(uncles) {
-			glog.V(logger.Debug).Infof("uncle block on index %d not found for block #%d", index.Int(), blockNr)
+		if index >= hexutil.Uint(len(uncles)) {
+			glog.V(logger.Debug).Infof("uncle block on index %d not found for block #%d", index, blockNr)
 			return nil, nil
 		}
-		block = types.NewBlockWithHeader(uncles[index.Int()])
+		block = types.NewBlockWithHeader(uncles[index])
 		return s.rpcOutputBlock(block, false, false)
 	}
 	return nil, err
@@ -415,32 +398,34 @@ func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context,
 
 // GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true
 // all transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
-func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (map[string]interface{}, error) {
+func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) {
 	block, err := s.b.GetBlock(ctx, blockHash)
 	if block != nil {
 		uncles := block.Uncles()
-		if index.Int() < 0 || index.Int() >= len(uncles) {
-			glog.V(logger.Debug).Infof("uncle block on index %d not found for block %s", index.Int(), blockHash.Hex())
+		if index >= hexutil.Uint(len(uncles)) {
+			glog.V(logger.Debug).Infof("uncle block on index %d not found for block %s", index, blockHash.Hex())
 			return nil, nil
 		}
-		block = types.NewBlockWithHeader(uncles[index.Int()])
+		block = types.NewBlockWithHeader(uncles[index])
 		return s.rpcOutputBlock(block, false, false)
 	}
 	return nil, err
 }
 
 // GetUncleCountByBlockNumber returns number of uncles in the block for the given block number
-func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *rpc.HexNumber {
+func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
 	if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
-		return rpc.NewHexNumber(len(block.Uncles()))
+		n := hexutil.Uint(len(block.Uncles()))
+		return &n
 	}
 	return nil
 }
 
 // GetUncleCountByBlockHash returns number of uncles in the block for the given block hash
-func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *rpc.HexNumber {
+func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
 	if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
-		return rpc.NewHexNumber(len(block.Uncles()))
+		n := hexutil.Uint(len(block.Uncles()))
+		return &n
 	}
 	return nil
 }
@@ -497,9 +482,9 @@ func (m callmsg) Data() []byte                          { return m.data }
 type CallArgs struct {
 	From     common.Address  `json:"from"`
 	To       *common.Address `json:"to"`
-	Gas      rpc.HexNumber   `json:"gas"`
-	GasPrice rpc.HexNumber   `json:"gasPrice"`
-	Value    rpc.HexNumber   `json:"value"`
+	Gas      hexutil.Big     `json:"gas"`
+	GasPrice hexutil.Big     `json:"gasPrice"`
+	Value    hexutil.Big     `json:"value"`
 	Data     string          `json:"data"`
 }
 
@@ -525,14 +510,14 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
 	}
 
 	// Assemble the CALL invocation
-	gas, gasPrice := args.Gas.BigInt(), args.GasPrice.BigInt()
+	gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt()
 	if gas.Cmp(common.Big0) == 0 {
 		gas = big.NewInt(50000000)
 	}
 	if gasPrice.Cmp(common.Big0) == 0 {
 		gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon)
 	}
-	msg := types.NewMessage(addr, args.To, 0, args.Value.BigInt(), gas, gasPrice, common.FromHex(args.Data), false)
+	msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, common.FromHex(args.Data), false)
 
 	// Execute the call and return
 	vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header)
@@ -558,9 +543,9 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr r
 }
 
 // EstimateGas returns an estimate of the amount of gas needed to execute the given transaction.
-func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*rpc.HexNumber, error) {
+func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*hexutil.Big, error) {
 	_, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber)
-	return rpc.NewHexNumber(gas), err
+	return (*hexutil.Big)(gas), err
 }
 
 // ExecutionResult groups all structured logs emitted by the EVM
@@ -622,7 +607,7 @@ func FormatLogs(structLogs []vm.StructLog) []StructLogRes {
 func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
 	head := b.Header() // copies the header once
 	fields := map[string]interface{}{
-		"number":           rpc.NewHexNumber(head.Number),
+		"number":           (*hexutil.Big)(head.Number),
 		"hash":             b.Hash(),
 		"parentHash":       head.ParentHash,
 		"nonce":            head.Nonce,
@@ -631,13 +616,13 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
 		"logsBloom":        head.Bloom,
 		"stateRoot":        head.Root,
 		"miner":            head.Coinbase,
-		"difficulty":       rpc.NewHexNumber(head.Difficulty),
-		"totalDifficulty":  rpc.NewHexNumber(s.b.GetTd(b.Hash())),
+		"difficulty":       (*hexutil.Big)(head.Difficulty),
+		"totalDifficulty":  (*hexutil.Big)(s.b.GetTd(b.Hash())),
 		"extraData":        hexutil.Bytes(head.Extra),
-		"size":             rpc.NewHexNumber(b.Size().Int64()),
-		"gasLimit":         rpc.NewHexNumber(head.GasLimit),
-		"gasUsed":          rpc.NewHexNumber(head.GasUsed),
-		"timestamp":        rpc.NewHexNumber(head.Time),
+		"size":             hexutil.Uint64(uint64(b.Size().Int64())),
+		"gasLimit":         (*hexutil.Big)(head.GasLimit),
+		"gasUsed":          (*hexutil.Big)(head.GasUsed),
+		"timestamp":        (*hexutil.Big)(head.Time),
 		"transactionsRoot": head.TxHash,
 		"receiptsRoot":     head.ReceiptHash,
 	}
@@ -677,19 +662,19 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
 type RPCTransaction struct {
 	BlockHash        common.Hash     `json:"blockHash"`
-	BlockNumber      *rpc.HexNumber  `json:"blockNumber"`
+	BlockNumber      *hexutil.Big    `json:"blockNumber"`
 	From             common.Address  `json:"from"`
-	Gas              *rpc.HexNumber  `json:"gas"`
-	GasPrice         *rpc.HexNumber  `json:"gasPrice"`
+	Gas              *hexutil.Big    `json:"gas"`
+	GasPrice         *hexutil.Big    `json:"gasPrice"`
 	Hash             common.Hash     `json:"hash"`
 	Input            hexutil.Bytes   `json:"input"`
-	Nonce            *rpc.HexNumber  `json:"nonce"`
+	Nonce            hexutil.Uint64  `json:"nonce"`
 	To               *common.Address `json:"to"`
-	TransactionIndex *rpc.HexNumber  `json:"transactionIndex"`
-	Value            *rpc.HexNumber  `json:"value"`
-	V                *rpc.HexNumber  `json:"v"`
-	R                *rpc.HexNumber  `json:"r"`
-	S                *rpc.HexNumber  `json:"s"`
+	TransactionIndex hexutil.Uint    `json:"transactionIndex"`
+	Value            *hexutil.Big    `json:"value"`
+	V                *hexutil.Big    `json:"v"`
+	R                *hexutil.Big    `json:"r"`
+	S                *hexutil.Big    `json:"s"`
 }
 
 // newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
@@ -699,25 +684,25 @@ func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction {
 		signer = types.NewEIP155Signer(tx.ChainId())
 	}
 	from, _ := types.Sender(signer, tx)
-	v, r, s := types.SignatureValues(signer, tx)
+	v, r, s := tx.RawSignatureValues()
 	return &RPCTransaction{
 		From:     from,
-		Gas:      rpc.NewHexNumber(tx.Gas()),
-		GasPrice: rpc.NewHexNumber(tx.GasPrice()),
+		Gas:      (*hexutil.Big)(tx.Gas()),
+		GasPrice: (*hexutil.Big)(tx.GasPrice()),
 		Hash:     tx.Hash(),
 		Input:    hexutil.Bytes(tx.Data()),
-		Nonce:    rpc.NewHexNumber(tx.Nonce()),
+		Nonce:    hexutil.Uint64(tx.Nonce()),
 		To:       tx.To(),
-		Value:    rpc.NewHexNumber(tx.Value()),
-		V:        rpc.NewHexNumber(v),
-		R:        rpc.NewHexNumber(r),
-		S:        rpc.NewHexNumber(s),
+		Value:    (*hexutil.Big)(tx.Value()),
+		V:        (*hexutil.Big)(v),
+		R:        (*hexutil.Big)(r),
+		S:        (*hexutil.Big)(s),
 	}
 }
 
 // newRPCTransaction returns a transaction that will serialize to the RPC representation.
-func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransaction, error) {
-	if txIndex >= 0 && txIndex < len(b.Transactions()) {
+func newRPCTransactionFromBlockIndex(b *types.Block, txIndex uint) (*RPCTransaction, error) {
+	if txIndex < uint(len(b.Transactions())) {
 		tx := b.Transactions()[txIndex]
 		var signer types.Signer = types.FrontierSigner{}
 		if tx.Protected() {
@@ -727,19 +712,19 @@ func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransacti
 		v, r, s := tx.RawSignatureValues()
 		return &RPCTransaction{
 			BlockHash:        b.Hash(),
-			BlockNumber:      rpc.NewHexNumber(b.Number()),
+			BlockNumber:      (*hexutil.Big)(b.Number()),
 			From:             from,
-			Gas:              rpc.NewHexNumber(tx.Gas()),
-			GasPrice:         rpc.NewHexNumber(tx.GasPrice()),
+			Gas:              (*hexutil.Big)(tx.Gas()),
+			GasPrice:         (*hexutil.Big)(tx.GasPrice()),
 			Hash:             tx.Hash(),
 			Input:            hexutil.Bytes(tx.Data()),
-			Nonce:            rpc.NewHexNumber(tx.Nonce()),
+			Nonce:            hexutil.Uint64(tx.Nonce()),
 			To:               tx.To(),
-			TransactionIndex: rpc.NewHexNumber(txIndex),
-			Value:            rpc.NewHexNumber(tx.Value()),
-			V:                rpc.NewHexNumber(v),
-			R:                rpc.NewHexNumber(r),
-			S:                rpc.NewHexNumber(s),
+			TransactionIndex: hexutil.Uint(txIndex),
+			Value:            (*hexutil.Big)(tx.Value()),
+			V:                (*hexutil.Big)(v),
+			R:                (*hexutil.Big)(r),
+			S:                (*hexutil.Big)(s),
 		}, nil
 	}
 
@@ -747,8 +732,8 @@ func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransacti
 }
 
 // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index.
-func newRPCRawTransactionFromBlockIndex(b *types.Block, txIndex int) (hexutil.Bytes, error) {
-	if txIndex >= 0 && txIndex < len(b.Transactions()) {
+func newRPCRawTransactionFromBlockIndex(b *types.Block, txIndex uint) (hexutil.Bytes, error) {
+	if txIndex < uint(len(b.Transactions())) {
 		tx := b.Transactions()[txIndex]
 		return rlp.EncodeToBytes(tx)
 	}
@@ -760,7 +745,7 @@ func newRPCRawTransactionFromBlockIndex(b *types.Block, txIndex int) (hexutil.By
 func newRPCTransaction(b *types.Block, txHash common.Hash) (*RPCTransaction, error) {
 	for idx, tx := range b.Transactions() {
 		if tx.Hash() == txHash {
-			return newRPCTransactionFromBlockIndex(b, idx)
+			return newRPCTransactionFromBlockIndex(b, uint(idx))
 		}
 	}
 
@@ -796,55 +781,57 @@ func getTransaction(chainDb ethdb.Database, b Backend, txHash common.Hash) (*typ
 }
 
 // GetBlockTransactionCountByNumber returns the number of transactions in the block with the given block number.
-func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *rpc.HexNumber {
+func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint {
 	if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
-		return rpc.NewHexNumber(len(block.Transactions()))
+		n := hexutil.Uint(len(block.Transactions()))
+		return &n
 	}
 	return nil
 }
 
 // GetBlockTransactionCountByHash returns the number of transactions in the block with the given hash.
-func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *rpc.HexNumber {
+func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint {
 	if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
-		return rpc.NewHexNumber(len(block.Transactions()))
+		n := hexutil.Uint(len(block.Transactions()))
+		return &n
 	}
 	return nil
 }
 
 // GetTransactionByBlockNumberAndIndex returns the transaction for the given block number and index.
-func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (*RPCTransaction, error) {
+func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (*RPCTransaction, error) {
 	if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
-		return newRPCTransactionFromBlockIndex(block, index.Int())
+		return newRPCTransactionFromBlockIndex(block, uint(index))
 	}
 	return nil, nil
 }
 
 // GetTransactionByBlockHashAndIndex returns the transaction for the given block hash and index.
-func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (*RPCTransaction, error) {
+func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (*RPCTransaction, error) {
 	if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
-		return newRPCTransactionFromBlockIndex(block, index.Int())
+		return newRPCTransactionFromBlockIndex(block, uint(index))
 	}
 	return nil, nil
 }
 
 // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index.
-func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index rpc.HexNumber) (hexutil.Bytes, error) {
+func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutil.Bytes, error) {
 	if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil {
-		return newRPCRawTransactionFromBlockIndex(block, index.Int())
+		return newRPCRawTransactionFromBlockIndex(block, uint(index))
 	}
 	return nil, nil
 }
 
 // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index.
-func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index rpc.HexNumber) (hexutil.Bytes, error) {
+func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutil.Bytes, error) {
 	if block, _ := s.b.GetBlock(ctx, blockHash); block != nil {
-		return newRPCRawTransactionFromBlockIndex(block, index.Int())
+		return newRPCRawTransactionFromBlockIndex(block, uint(index))
 	}
 	return nil, nil
 }
 
 // GetTransactionCount returns the number of transactions the given address has sent for the given block number
-func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*rpc.HexNumber, error) {
+func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) {
 	state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
 	if state == nil || err != nil {
 		return nil, err
@@ -853,7 +840,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
 	if err != nil {
 		return nil, err
 	}
-	return rpc.NewHexNumber(nonce), nil
+	return (*hexutil.Uint64)(&nonce), nil
 }
 
 // getTransactionBlockData fetches the meta data for the given transaction from the chain database. This is useful to
@@ -952,13 +939,13 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (ma
 	fields := map[string]interface{}{
 		"root":              hexutil.Bytes(receipt.PostState),
 		"blockHash":         txBlock,
-		"blockNumber":       rpc.NewHexNumber(blockIndex),
+		"blockNumber":       hexutil.Uint64(blockIndex),
 		"transactionHash":   txHash,
-		"transactionIndex":  rpc.NewHexNumber(index),
+		"transactionIndex":  hexutil.Uint64(index),
 		"from":              from,
 		"to":                tx.To(),
-		"gasUsed":           rpc.NewHexNumber(receipt.GasUsed),
-		"cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed),
+		"gasUsed":           (*hexutil.Big)(receipt.GasUsed),
+		"cumulativeGasUsed": (*hexutil.Big)(receipt.CumulativeGasUsed),
 		"contractAddress":   nil,
 		"logs":              receipt.Logs,
 		"logsBloom":         receipt.Bloom,
@@ -988,32 +975,46 @@ func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transacti
 type SendTxArgs struct {
 	From     common.Address  `json:"from"`
 	To       *common.Address `json:"to"`
-	Gas      *rpc.HexNumber  `json:"gas"`
-	GasPrice *rpc.HexNumber  `json:"gasPrice"`
-	Value    *rpc.HexNumber  `json:"value"`
-	Data     string          `json:"data"`
-	Nonce    *rpc.HexNumber  `json:"nonce"`
+	Gas      *hexutil.Big    `json:"gas"`
+	GasPrice *hexutil.Big    `json:"gasPrice"`
+	Value    *hexutil.Big    `json:"value"`
+	Data     hexutil.Bytes   `json:"data"`
+	Nonce    *hexutil.Uint64 `json:"nonce"`
 }
 
 // prepareSendTxArgs is a helper function that fills in default values for unspecified tx fields.
-func prepareSendTxArgs(ctx context.Context, args SendTxArgs, b Backend) (SendTxArgs, error) {
+func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error {
 	if args.Gas == nil {
-		args.Gas = rpc.NewHexNumber(defaultGas)
+		args.Gas = (*hexutil.Big)(big.NewInt(defaultGas))
 	}
 	if args.GasPrice == nil {
 		price, err := b.SuggestPrice(ctx)
 		if err != nil {
-			return args, err
+			return err
 		}
-		args.GasPrice = rpc.NewHexNumber(price)
+		args.GasPrice = (*hexutil.Big)(price)
 	}
 	if args.Value == nil {
-		args.Value = rpc.NewHexNumber(0)
+		args.Value = new(hexutil.Big)
+	}
+	if args.Nonce == nil {
+		nonce, err := b.GetPoolNonce(ctx, args.From)
+		if err != nil {
+			return err
+		}
+		args.Nonce = (*hexutil.Uint64)(&nonce)
+	}
+	return nil
+}
+
+func (args *SendTxArgs) toTransaction() *types.Transaction {
+	if args.To == nil {
+		return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), args.Data)
 	}
-	return args, nil
+	return types.NewTransaction(uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), (*big.Int)(args.Gas), (*big.Int)(args.GasPrice), args.Data)
 }
 
-// submitTransaction is a helper function that submits tx to txPool and creates a log entry.
+// submitTransaction is a helper function that submits tx to txPool and logs a message.
 func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, signature []byte) (common.Hash, error) {
 	signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number())
 
@@ -1040,27 +1041,10 @@ func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, si
 // SendTransaction creates a transaction for the given argument, sign it and submit it to the
 // transaction pool.
 func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
-	var err error
-	args, err = prepareSendTxArgs(ctx, args, s.b)
-	if err != nil {
+	if err := args.setDefaults(ctx, s.b); err != nil {
 		return common.Hash{}, err
 	}
-
-	if args.Nonce == nil {
-		nonce, err := s.b.GetPoolNonce(ctx, args.From)
-		if err != nil {
-			return common.Hash{}, err
-		}
-		args.Nonce = rpc.NewHexNumber(nonce)
-	}
-
-	var tx *types.Transaction
-	if args.To == nil {
-		tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
-	} else {
-		tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
-	}
-
+	tx := args.toTransaction()
 	signer := types.MakeSigner(s.b.ChainConfig(), s.b.CurrentBlock().Number())
 	signature, err := s.b.AccountManager().SignEthereum(args.From, signer.Hash(tx).Bytes())
 	if err != nil {
@@ -1107,153 +1091,28 @@ func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes)
 	return s.b.AccountManager().SignEthereum(addr, signHash(data))
 }
 
-// SignTransactionArgs represents the arguments to sign a transaction.
-type SignTransactionArgs struct {
-	From     common.Address
-	To       *common.Address
-	Nonce    *rpc.HexNumber
-	Value    *rpc.HexNumber
-	Gas      *rpc.HexNumber
-	GasPrice *rpc.HexNumber
-	Data     string
-
-	BlockNumber int64
-}
-
-// Tx is a helper object for argument and return values
-type Tx struct {
-	tx *types.Transaction
-
-	To       *common.Address `json:"to"`
-	From     common.Address  `json:"from"`
-	Nonce    *rpc.HexNumber  `json:"nonce"`
-	Value    *rpc.HexNumber  `json:"value"`
-	Data     string          `json:"data"`
-	GasLimit *rpc.HexNumber  `json:"gas"`
-	GasPrice *rpc.HexNumber  `json:"gasPrice"`
-	Hash     common.Hash     `json:"hash"`
-}
-
-// UnmarshalJSON parses JSON data into tx.
-func (tx *Tx) UnmarshalJSON(b []byte) (err error) {
-	req := struct {
-		To       *common.Address `json:"to"`
-		From     common.Address  `json:"from"`
-		Nonce    *rpc.HexNumber  `json:"nonce"`
-		Value    *rpc.HexNumber  `json:"value"`
-		Data     string          `json:"data"`
-		GasLimit *rpc.HexNumber  `json:"gas"`
-		GasPrice *rpc.HexNumber  `json:"gasPrice"`
-		Hash     common.Hash     `json:"hash"`
-	}{}
-
-	if err := json.Unmarshal(b, &req); err != nil {
-		return err
-	}
-
-	tx.To = req.To
-	tx.From = req.From
-	tx.Nonce = req.Nonce
-	tx.Value = req.Value
-	tx.Data = req.Data
-	tx.GasLimit = req.GasLimit
-	tx.GasPrice = req.GasPrice
-	tx.Hash = req.Hash
-
-	data := common.Hex2Bytes(tx.Data)
-
-	if tx.Nonce == nil {
-		return fmt.Errorf("need nonce")
-	}
-	if tx.Value == nil {
-		tx.Value = rpc.NewHexNumber(0)
-	}
-	if tx.GasLimit == nil {
-		tx.GasLimit = rpc.NewHexNumber(0)
-	}
-	if tx.GasPrice == nil {
-		tx.GasPrice = rpc.NewHexNumber(int64(50000000000))
-	}
-
-	if req.To == nil {
-		tx.tx = types.NewContractCreation(tx.Nonce.Uint64(), tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data)
-	} else {
-		tx.tx = types.NewTransaction(tx.Nonce.Uint64(), *tx.To, tx.Value.BigInt(), tx.GasLimit.BigInt(), tx.GasPrice.BigInt(), data)
-	}
-
-	return nil
-}
-
 // SignTransactionResult represents a RLP encoded signed transaction.
 type SignTransactionResult struct {
-	Raw string `json:"raw"`
-	Tx  *Tx    `json:"tx"`
-}
-
-func newTx(t *types.Transaction) *Tx {
-	var signer types.Signer = types.HomesteadSigner{}
-	if t.Protected() {
-		signer = types.NewEIP155Signer(t.ChainId())
-	}
-
-	from, _ := types.Sender(signer, t)
-	return &Tx{
-		tx:       t,
-		To:       t.To(),
-		From:     from,
-		Value:    rpc.NewHexNumber(t.Value()),
-		Nonce:    rpc.NewHexNumber(t.Nonce()),
-		Data:     "0x" + common.Bytes2Hex(t.Data()),
-		GasLimit: rpc.NewHexNumber(t.Gas()),
-		GasPrice: rpc.NewHexNumber(t.GasPrice()),
-		Hash:     t.Hash(),
-	}
+	Raw hexutil.Bytes      `json:"raw"`
+	Tx  *types.Transaction `json:"tx"`
 }
 
 // SignTransaction will sign the given transaction with the from account.
 // The node needs to have the private key of the account corresponding with
 // the given from address and it needs to be unlocked.
-func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SignTransactionArgs) (*SignTransactionResult, error) {
-	if args.Gas == nil {
-		args.Gas = rpc.NewHexNumber(defaultGas)
-	}
-	if args.GasPrice == nil {
-		price, err := s.b.SuggestPrice(ctx)
-		if err != nil {
-			return nil, err
-		}
-		args.GasPrice = rpc.NewHexNumber(price)
-	}
-	if args.Value == nil {
-		args.Value = rpc.NewHexNumber(0)
-	}
-
-	if args.Nonce == nil {
-		nonce, err := s.b.GetPoolNonce(ctx, args.From)
-		if err != nil {
-			return nil, err
-		}
-		args.Nonce = rpc.NewHexNumber(nonce)
-	}
-
-	var tx *types.Transaction
-	if args.To == nil {
-		tx = types.NewContractCreation(args.Nonce.Uint64(), args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
-	} else {
-		tx = types.NewTransaction(args.Nonce.Uint64(), *args.To, args.Value.BigInt(), args.Gas.BigInt(), args.GasPrice.BigInt(), common.FromHex(args.Data))
+func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) {
+	if err := args.setDefaults(ctx, s.b); err != nil {
+		return nil, err
 	}
-
-	signedTx, err := s.sign(args.From, tx)
+	tx, err := s.sign(args.From, args.toTransaction())
 	if err != nil {
 		return nil, err
 	}
-
-	data, err := rlp.EncodeToBytes(signedTx)
+	data, err := rlp.EncodeToBytes(tx)
 	if err != nil {
 		return nil, err
 	}
-
-	return &SignTransactionResult{"0x" + common.Bytes2Hex(data), newTx(signedTx)}, nil
+	return &SignTransactionResult{data, tx}, nil
 }
 
 // PendingTransactions returns the transactions that are in the transaction pool and have a from address that is one of
@@ -1278,9 +1137,16 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
 	return transactions, nil
 }
 
-// Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the
-// pool and reinsert it with the new gas price and limit.
-func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) {
+// Resend accepts an existing transaction and a new gas price and limit. It will remove
+// the given transaction from the pool and reinsert it with the new gas price and limit.
+func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice, gasLimit *hexutil.Big) (common.Hash, error) {
+	if sendArgs.Nonce == nil {
+		return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec")
+	}
+	if err := sendArgs.setDefaults(ctx, s.b); err != nil {
+		return common.Hash{}, err
+	}
+	matchTx := sendArgs.toTransaction()
 	pending, err := s.b.GetPoolTransactions()
 	if err != nil {
 		return common.Hash{}, err
@@ -1291,37 +1157,29 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx Tx, gasPrice,
 		if p.Protected() {
 			signer = types.NewEIP155Signer(p.ChainId())
 		}
+		wantSigHash := signer.Hash(matchTx)
 
-		if pFrom, err := types.Sender(signer, p); err == nil && pFrom == tx.From && signer.Hash(p) == signer.Hash(tx.tx) {
-			if gasPrice == nil {
-				gasPrice = rpc.NewHexNumber(tx.tx.GasPrice())
-			}
-			if gasLimit == nil {
-				gasLimit = rpc.NewHexNumber(tx.tx.Gas())
+		if pFrom, err := types.Sender(signer, p); err == nil && pFrom == sendArgs.From && signer.Hash(p) == wantSigHash {
+			// Match. Re-sign and send the transaction.
+			if gasPrice != nil {
+				sendArgs.GasPrice = gasPrice
 			}
-
-			var newTx *types.Transaction
-			if tx.tx.To() == nil {
-				newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
-			} else {
-				newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data())
+			if gasLimit != nil {
+				sendArgs.Gas = gasLimit
 			}
-
-			signedTx, err := s.sign(tx.From, newTx)
+			signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction())
 			if err != nil {
 				return common.Hash{}, err
 			}
-
-			s.b.RemoveTx(tx.Hash)
+			s.b.RemoveTx(p.Hash())
 			if err = s.b.SendTx(ctx, signedTx); err != nil {
 				return common.Hash{}, err
 			}
-
 			return signedTx.Hash(), nil
 		}
 	}
 
-	return common.Hash{}, fmt.Errorf("Transaction %#x not found", tx.Hash)
+	return common.Hash{}, fmt.Errorf("Transaction %#x not found", matchTx.Hash())
 }
 
 // PublicDebugAPI is the collection of Etheruem APIs exposed over the public
@@ -1418,8 +1276,8 @@ func (api *PrivateDebugAPI) ChaindbCompact() error {
 }
 
 // SetHead rewinds the head of the blockchain to a previous block.
-func (api *PrivateDebugAPI) SetHead(number rpc.HexNumber) {
-	api.b.SetHead(uint64(number.Int64()))
+func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) {
+	api.b.SetHead(uint64(number))
 }
 
 // PublicNetAPI offers network related RPC methods
@@ -1439,8 +1297,8 @@ func (s *PublicNetAPI) Listening() bool {
 }
 
 // PeerCount returns the number of connected peers
-func (s *PublicNetAPI) PeerCount() *rpc.HexNumber {
-	return rpc.NewHexNumber(s.net.PeerCount())
+func (s *PublicNetAPI) PeerCount() hexutil.Uint {
+	return hexutil.Uint(s.net.PeerCount())
 }
 
 // Version returns the current ethereum protocol version.
diff --git a/les/backend.go b/les/backend.go
index 72666422734e42c71e80580ab5f9389f19188e03..d21d5a98cfe6fef223174fa1c224c8a351b7dac3 100644
--- a/les/backend.go
+++ b/les/backend.go
@@ -26,6 +26,7 @@ import (
 	"github.com/ethereum/go-ethereum/accounts"
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/common/compiler"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/core"
 	"github.com/ethereum/go-ethereum/core/types"
 	"github.com/ethereum/go-ethereum/eth"
@@ -135,8 +136,8 @@ func (s *LightDummyAPI) Coinbase() (common.Address, error) {
 }
 
 // Hashrate returns the POW hashrate
-func (s *LightDummyAPI) Hashrate() *rpc.HexNumber {
-	return rpc.NewHexNumber(0)
+func (s *LightDummyAPI) Hashrate() hexutil.Uint {
+	return 0
 }
 
 // Mining returns an indication if this node is currently mining.
diff --git a/node/api.go b/node/api.go
index 7c9ad601a41e2484b02c0a989e34ca9abd981875..988eff3798fd7e7bfc5884f1a3154da876f12e73 100644
--- a/node/api.go
+++ b/node/api.go
@@ -25,7 +25,6 @@ import (
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/ethereum/go-ethereum/p2p"
 	"github.com/ethereum/go-ethereum/p2p/discover"
-	"github.com/ethereum/go-ethereum/rpc"
 	"github.com/rcrowley/go-metrics"
 )
 
@@ -75,7 +74,7 @@ func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
 }
 
 // StartRPC starts the HTTP RPC API server.
-func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *string, apis *string) (bool, error) {
+func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis *string) (bool, error) {
 	api.node.lock.Lock()
 	defer api.node.lock.Unlock()
 
@@ -91,7 +90,7 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *st
 		host = &h
 	}
 	if port == nil {
-		port = rpc.NewHexNumber(api.node.config.HTTPPort)
+		port = &api.node.config.HTTPPort
 	}
 	if cors == nil {
 		cors = &api.node.config.HTTPCors
@@ -105,7 +104,7 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *st
 		}
 	}
 
-	if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, port.Int()), api.node.rpcAPIs, modules, *cors); err != nil {
+	if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, port), api.node.rpcAPIs, modules, *cors); err != nil {
 		return false, err
 	}
 	return true, nil
@@ -124,7 +123,7 @@ func (api *PrivateAdminAPI) StopRPC() (bool, error) {
 }
 
 // StartWS starts the websocket RPC API server.
-func (api *PrivateAdminAPI) StartWS(host *string, port *rpc.HexNumber, allowedOrigins *string, apis *string) (bool, error) {
+func (api *PrivateAdminAPI) StartWS(host *string, port *int, allowedOrigins *string, apis *string) (bool, error) {
 	api.node.lock.Lock()
 	defer api.node.lock.Unlock()
 
@@ -140,7 +139,7 @@ func (api *PrivateAdminAPI) StartWS(host *string, port *rpc.HexNumber, allowedOr
 		host = &h
 	}
 	if port == nil {
-		port = rpc.NewHexNumber(api.node.config.WSPort)
+		port = &api.node.config.WSPort
 	}
 	if allowedOrigins == nil {
 		allowedOrigins = &api.node.config.WSOrigins
@@ -154,7 +153,7 @@ func (api *PrivateAdminAPI) StartWS(host *string, port *rpc.HexNumber, allowedOr
 		}
 	}
 
-	if err := api.node.startWS(fmt.Sprintf("%s:%d", *host, port.Int()), api.node.rpcAPIs, modules, *allowedOrigins); err != nil {
+	if err := api.node.startWS(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, *allowedOrigins); err != nil {
 		return false, err
 	}
 	return true, nil
diff --git a/rpc/json.go b/rpc/json.go
index 5a89c1a69f3532b456453c4448509d4758d359de..ac5a4acd325c9f014fc15e42cc08d828b0cd2d33 100644
--- a/rpc/json.go
+++ b/rpc/json.go
@@ -257,8 +257,8 @@ func parseBatchRequest(incomingMsg json.RawMessage) ([]rpcRequest, bool, Error)
 	return requests, true, nil
 }
 
-// ParseRequestArguments tries to parse the given params (json.RawMessage) with the given types. It returns the parsed
-// values or an error when the parsing failed.
+// ParseRequestArguments tries to parse the given params (json.RawMessage) with the given
+// types. It returns the parsed values or an error when the parsing failed.
 func (c *jsonCodec) ParseRequestArguments(argTypes []reflect.Type, params interface{}) ([]reflect.Value, Error) {
 	if args, ok := params.(json.RawMessage); !ok {
 		return nil, &invalidParamsError{"Invalid params supplied"}
diff --git a/rpc/types.go b/rpc/types.go
index 89c5b5bc9b850d953bc7cfc01630d8246c8ebd0d..01b95a170d873d27bb2b374163bf9e8e15377f7d 100644
--- a/rpc/types.go
+++ b/rpc/types.go
@@ -121,91 +121,6 @@ type ServerCodec interface {
 	Closed() <-chan interface{}
 }
 
-// HexNumber serializes a number to hex format using the "%#x" format
-type HexNumber big.Int
-
-// NewHexNumber creates a new hex number instance which will serialize the given val with `%#x` on marshal.
-func NewHexNumber(val interface{}) *HexNumber {
-	if val == nil {
-		return nil // note, this doesn't catch nil pointers, only passing nil directly!
-	}
-
-	if v, ok := val.(*big.Int); ok {
-		if v != nil {
-			return (*HexNumber)(new(big.Int).Set(v))
-		}
-		return nil
-	}
-
-	rval := reflect.ValueOf(val)
-
-	var unsigned uint64
-	utype := reflect.TypeOf(unsigned)
-	if t := rval.Type(); t.ConvertibleTo(utype) {
-		hn := new(big.Int).SetUint64(rval.Convert(utype).Uint())
-		return (*HexNumber)(hn)
-	}
-
-	var signed int64
-	stype := reflect.TypeOf(signed)
-	if t := rval.Type(); t.ConvertibleTo(stype) {
-		hn := new(big.Int).SetInt64(rval.Convert(stype).Int())
-		return (*HexNumber)(hn)
-	}
-
-	return nil
-}
-
-func (h *HexNumber) UnmarshalJSON(input []byte) error {
-	length := len(input)
-	if length >= 2 && input[0] == '"' && input[length-1] == '"' {
-		input = input[1 : length-1]
-	}
-
-	hn := (*big.Int)(h)
-	if _, ok := hn.SetString(string(input), 0); ok {
-		return nil
-	}
-
-	return fmt.Errorf("Unable to parse number")
-}
-
-// 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 nil, nil
-}
-
-func (h *HexNumber) Int() int {
-	hn := (*big.Int)(h)
-	return int(hn.Int64())
-}
-
-func (h *HexNumber) Int64() int64 {
-	hn := (*big.Int)(h)
-	return hn.Int64()
-}
-
-func (h *HexNumber) Uint() uint {
-	hn := (*big.Int)(h)
-	return uint(hn.Uint64())
-}
-
-func (h *HexNumber) Uint64() uint64 {
-	hn := (*big.Int)(h)
-	return hn.Uint64()
-}
-
-func (h *HexNumber) BigInt() *big.Int {
-	return (*big.Int)(h)
-}
-
 var (
 	pendingBlockNumber  = big.NewInt(-2)
 	latestBlockNumber   = big.NewInt(-1)
diff --git a/rpc/types_test.go b/rpc/types_test.go
deleted file mode 100644
index c2c5c6db6c44f6d5f42fbd74fbd2d84733f37ad5..0000000000000000000000000000000000000000
--- a/rpc/types_test.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// 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.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package rpc
-
-import (
-	"bytes"
-	"encoding/json"
-	"math/big"
-	"testing"
-)
-
-func TestNewHexNumber(t *testing.T) {
-	tests := []interface{}{big.NewInt(123), int64(123), uint64(123), int8(123), uint8(123)}
-
-	for i, v := range tests {
-		hn := NewHexNumber(v)
-		if hn == nil {
-			t.Fatalf("Unable to create hex number instance for tests[%d]", i)
-		}
-		if hn.Int64() != 123 {
-			t.Fatalf("expected %d, got %d on value tests[%d]", 123, hn.Int64(), i)
-		}
-	}
-
-	failures := []interface{}{"", nil, []byte{1, 2, 3, 4}}
-	for i, v := range failures {
-		hn := NewHexNumber(v)
-		if hn != nil {
-			t.Fatalf("Creating a nex number instance of %T should fail (failures[%d])", failures[i], i)
-		}
-	}
-}
-
-func TestHexNumberUnmarshalJSON(t *testing.T) {
-	tests := []string{`"0x4d2"`, "1234", `"1234"`}
-	for i, v := range tests {
-		var hn HexNumber
-		if err := json.Unmarshal([]byte(v), &hn); err != nil {
-			t.Fatalf("Test %d failed - %s", i, err)
-		}
-
-		if hn.Int64() != 1234 {
-			t.Fatalf("Expected %d, got %d for test[%d]", 1234, hn.Int64(), i)
-		}
-	}
-}
-
-func TestHexNumberMarshalJSON(t *testing.T) {
-	hn := NewHexNumber(1234567890)
-	got, err := json.Marshal(hn)
-	if err != nil {
-		t.Fatalf("Unable to marshal hex number - %s", err)
-	}
-
-	exp := []byte(`"0x499602d2"`)
-	if bytes.Compare(exp, got) != 0 {
-		t.Fatalf("Invalid json.Marshal, expected '%s', got '%s'", exp, got)
-	}
-}
diff --git a/whisper/shhapi/api.go b/whisper/shhapi/api.go
index 8a0bd92144d735b8115845b27dc64270a59be726..24d54b6533de90a136a8d4fa4e74e61aadc6d22a 100644
--- a/whisper/shhapi/api.go
+++ b/whisper/shhapi/api.go
@@ -73,11 +73,11 @@ func (api *PublicWhisperAPI) Stop() error {
 }
 
 // Version returns the Whisper version this node offers.
-func (api *PublicWhisperAPI) Version() (*rpc.HexNumber, error) {
+func (api *PublicWhisperAPI) Version() (hexutil.Uint, error) {
 	if api.whisper == nil {
-		return rpc.NewHexNumber(0), whisperOffLineErr
+		return 0, whisperOffLineErr
 	}
-	return rpc.NewHexNumber(api.whisper.Version()), nil
+	return hexutil.Uint(api.whisper.Version()), nil
 }
 
 // MarkPeerTrusted marks specific peer trusted, which will allow it
diff --git a/whisper/shhapi/api_test.go b/whisper/shhapi/api_test.go
index a10e2e47602c6fac41b92d8b3c740dc43b6c00a6..d2890a9a3a366bde6cc52d4013143bf41ab7d8a0 100644
--- a/whisper/shhapi/api_test.go
+++ b/whisper/shhapi/api_test.go
@@ -39,8 +39,8 @@ func TestBasic(t *testing.T) {
 		t.Fatalf("failed generateFilter: %s.", err)
 	}
 
-	if ver.Uint64() != whisperv5.ProtocolVersion {
-		t.Fatalf("wrong version: %d.", ver.Uint64())
+	if uint64(ver) != whisperv5.ProtocolVersion {
+		t.Fatalf("wrong version: %d.", ver)
 	}
 
 	mail := api.GetFilterChanges(1)
diff --git a/whisper/whisperv2/api.go b/whisper/whisperv2/api.go
index 9c9c6a84c396533f3ad4c226e28fdaae0565e9a3..0509453ba55b2fa50522dc2ff625380001c01143 100644
--- a/whisper/whisperv2/api.go
+++ b/whisper/whisperv2/api.go
@@ -23,8 +23,8 @@ import (
 	"time"
 
 	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/common/hexutil"
 	"github.com/ethereum/go-ethereum/crypto"
-	"github.com/ethereum/go-ethereum/rpc"
 )
 
 // PublicWhisperAPI provides the whisper RPC service.
@@ -32,7 +32,7 @@ type PublicWhisperAPI struct {
 	w *Whisper
 
 	messagesMu sync.RWMutex
-	messages   map[int]*whisperFilter
+	messages   map[hexutil.Uint]*whisperFilter
 }
 
 type whisperOfflineError struct{}
@@ -46,15 +46,15 @@ var whisperOffLineErr = new(whisperOfflineError)
 
 // NewPublicWhisperAPI create a new RPC whisper service.
 func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI {
-	return &PublicWhisperAPI{w: w, messages: make(map[int]*whisperFilter)}
+	return &PublicWhisperAPI{w: w, messages: make(map[hexutil.Uint]*whisperFilter)}
 }
 
 // Version returns the Whisper version this node offers.
-func (s *PublicWhisperAPI) Version() (*rpc.HexNumber, error) {
+func (s *PublicWhisperAPI) Version() (hexutil.Uint, error) {
 	if s.w == nil {
-		return rpc.NewHexNumber(0), whisperOffLineErr
+		return 0, whisperOffLineErr
 	}
-	return rpc.NewHexNumber(s.w.Version()), nil
+	return hexutil.Uint(s.w.Version()), nil
 }
 
 // HasIdentity checks if the the whisper node is configured with the private key
@@ -84,12 +84,12 @@ type NewFilterArgs struct {
 }
 
 // NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages.
-func (s *PublicWhisperAPI) NewFilter(args NewFilterArgs) (*rpc.HexNumber, error) {
+func (s *PublicWhisperAPI) NewFilter(args NewFilterArgs) (hexutil.Uint, error) {
 	if s.w == nil {
-		return nil, whisperOffLineErr
+		return 0, whisperOffLineErr
 	}
 
-	var id int
+	var id hexutil.Uint
 	filter := Filter{
 		To:     crypto.ToECDSAPub(common.FromHex(args.To)),
 		From:   crypto.ToECDSAPub(common.FromHex(args.From)),
@@ -103,23 +103,22 @@ func (s *PublicWhisperAPI) NewFilter(args NewFilterArgs) (*rpc.HexNumber, error)
 			}
 		},
 	}
-
-	id = s.w.Watch(filter)
+	id = hexutil.Uint(s.w.Watch(filter))
 
 	s.messagesMu.Lock()
 	s.messages[id] = newWhisperFilter(id, s.w)
 	s.messagesMu.Unlock()
 
-	return rpc.NewHexNumber(id), nil
+	return id, nil
 }
 
 // GetFilterChanges retrieves all the new messages matched by a filter since the last retrieval.
-func (s *PublicWhisperAPI) GetFilterChanges(filterId rpc.HexNumber) []WhisperMessage {
+func (s *PublicWhisperAPI) GetFilterChanges(filterId hexutil.Uint) []WhisperMessage {
 	s.messagesMu.RLock()
 	defer s.messagesMu.RUnlock()
 
-	if s.messages[filterId.Int()] != nil {
-		if changes := s.messages[filterId.Int()].retrieve(); changes != nil {
+	if s.messages[filterId] != nil {
+		if changes := s.messages[filterId].retrieve(); changes != nil {
 			return changes
 		}
 	}
@@ -127,26 +126,26 @@ func (s *PublicWhisperAPI) GetFilterChanges(filterId rpc.HexNumber) []WhisperMes
 }
 
 // UninstallFilter disables and removes an existing filter.
-func (s *PublicWhisperAPI) UninstallFilter(filterId rpc.HexNumber) bool {
+func (s *PublicWhisperAPI) UninstallFilter(filterId hexutil.Uint) bool {
 	s.messagesMu.Lock()
 	defer s.messagesMu.Unlock()
 
-	if _, ok := s.messages[filterId.Int()]; ok {
-		delete(s.messages, filterId.Int())
+	if _, ok := s.messages[filterId]; ok {
+		delete(s.messages, filterId)
 		return true
 	}
 	return false
 }
 
 // GetMessages retrieves all the known messages that match a specific filter.
-func (s *PublicWhisperAPI) GetMessages(filterId rpc.HexNumber) []WhisperMessage {
+func (s *PublicWhisperAPI) GetMessages(filterId hexutil.Uint) []WhisperMessage {
 	// Retrieve all the cached messages matching a specific, existing filter
 	s.messagesMu.RLock()
 	defer s.messagesMu.RUnlock()
 
 	var messages []*Message
-	if s.messages[filterId.Int()] != nil {
-		messages = s.messages[filterId.Int()].messages()
+	if s.messages[filterId] != nil {
+		messages = s.messages[filterId].messages()
 	}
 
 	return returnWhisperMessages(messages)
@@ -217,12 +216,12 @@ type WhisperMessage struct {
 
 func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
 	var obj struct {
-		From     string        `json:"from"`
-		To       string        `json:"to"`
-		Topics   []string      `json:"topics"`
-		Payload  string        `json:"payload"`
-		Priority rpc.HexNumber `json:"priority"`
-		TTL      rpc.HexNumber `json:"ttl"`
+		From     string         `json:"from"`
+		To       string         `json:"to"`
+		Topics   []string       `json:"topics"`
+		Payload  string         `json:"payload"`
+		Priority hexutil.Uint64 `json:"priority"`
+		TTL      hexutil.Uint64 `json:"ttl"`
 	}
 
 	if err := json.Unmarshal(data, &obj); err != nil {
@@ -232,8 +231,8 @@ func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
 	args.From = obj.From
 	args.To = obj.To
 	args.Payload = obj.Payload
-	args.Priority = obj.Priority.Int64()
-	args.TTL = obj.TTL.Int64()
+	args.Priority = int64(obj.Priority) // TODO(gluk256): handle overflow
+	args.TTL = int64(obj.TTL)           // ... here too ...
 
 	// decode topic strings
 	args.Topics = make([][]byte, len(obj.Topics))
@@ -328,8 +327,8 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
 // whisperFilter is the message cache matching a specific filter, accumulating
 // inbound messages until the are requested by the client.
 type whisperFilter struct {
-	id  int      // Filter identifier for old message retrieval
-	ref *Whisper // Whisper reference for old message retrieval
+	id  hexutil.Uint // Filter identifier for old message retrieval
+	ref *Whisper     // Whisper reference for old message retrieval
 
 	cache  []WhisperMessage         // Cache of messages not yet polled
 	skip   map[common.Hash]struct{} // List of retrieved messages to avoid duplication
@@ -348,7 +347,7 @@ func (w *whisperFilter) messages() []*Message {
 	w.update = time.Now()
 
 	w.skip = make(map[common.Hash]struct{})
-	messages := w.ref.Messages(w.id)
+	messages := w.ref.Messages(int(w.id))
 	for _, message := range messages {
 		w.skip[message.Hash] = struct{}{}
 	}
@@ -388,11 +387,10 @@ func (w *whisperFilter) activity() time.Time {
 }
 
 // newWhisperFilter creates a new serialized, poll based whisper topic filter.
-func newWhisperFilter(id int, ref *Whisper) *whisperFilter {
+func newWhisperFilter(id hexutil.Uint, ref *Whisper) *whisperFilter {
 	return &whisperFilter{
-		id:  id,
-		ref: ref,
-
+		id:     id,
+		ref:    ref,
 		update: time.Now(),
 		skip:   make(map[common.Hash]struct{}),
 	}