diff --git a/core/types/json.go b/core/types/json.go
index 403e798990e9dff6c1a9183afbc9ae13058cc2b7..d2718a96d10751e9399a3c0fbe3c6510c232b34b 100644
--- a/core/types/json.go
+++ b/core/types/json.go
@@ -26,6 +26,13 @@ import (
 
 type hexBytes []byte
 
+func (b *hexBytes) MarshalJSON() ([]byte, error) {
+	if b != nil {
+		return []byte(fmt.Sprintf(`"0x%x"`, []byte(*b))), nil
+	}
+	return nil, nil
+}
+
 func (b *hexBytes) UnmarshalJSON(input []byte) error {
 	if len(input) < 2 || input[0] != '"' || input[len(input)-1] != '"' {
 		return fmt.Errorf("cannot unmarshal non-string into hexBytes")
@@ -44,6 +51,13 @@ func (b *hexBytes) UnmarshalJSON(input []byte) error {
 
 type hexBig big.Int
 
+func (b *hexBig) MarshalJSON() ([]byte, error) {
+	if b != nil {
+		return []byte(fmt.Sprintf(`"0x%x"`, (*big.Int)(b))), nil
+	}
+	return nil, nil
+}
+
 func (b *hexBig) UnmarshalJSON(input []byte) error {
 	raw, err := checkHexNumber(input)
 	if err != nil {
@@ -59,6 +73,13 @@ func (b *hexBig) UnmarshalJSON(input []byte) error {
 
 type hexUint64 uint64
 
+func (b *hexUint64) MarshalJSON() ([]byte, error) {
+	if b != nil {
+		return []byte(fmt.Sprintf(`"0x%x"`, *(*uint64)(b))), nil
+	}
+	return nil, nil
+}
+
 func (b *hexUint64) UnmarshalJSON(input []byte) error {
 	raw, err := checkHexNumber(input)
 	if err != nil {
diff --git a/core/types/json_test.go b/core/types/json_test.go
index 5f422b8732f93d8cc94ee4d6779c0c673f56e442..605c2b5648048af79687f0803c221c5e529dde0f 100644
--- a/core/types/json_test.go
+++ b/core/types/json_test.go
@@ -2,6 +2,7 @@ package types
 
 import (
 	"encoding/json"
+	"reflect"
 	"testing"
 
 	"github.com/ethereum/go-ethereum/common"
@@ -44,6 +45,31 @@ func TestUnmarshalHeader(t *testing.T) {
 	}
 }
 
+func TestMarshalHeader(t *testing.T) {
+	for name, test := range unmarshalHeaderTests {
+		if test.wantError != nil {
+			continue
+		}
+		var original *Header
+		json.Unmarshal([]byte(test.input), &original)
+
+		blob, err := json.Marshal(original)
+		if err != nil {
+			t.Errorf("test %q: failed to marshal header: %v", name, err)
+			continue
+		}
+		var proced *Header
+		if err := json.Unmarshal(blob, &proced); err != nil {
+			t.Errorf("Test %q: failed to unmarshal marhsalled header: %v", name, err)
+			continue
+		}
+		if !reflect.DeepEqual(original, proced) {
+			t.Errorf("test %q: header mismatch: have %+v, want %+v", name, proced, original)
+			continue
+		}
+	}
+}
+
 var unmarshalTransactionTests = map[string]struct {
 	input     string
 	wantHash  common.Hash
@@ -94,6 +120,32 @@ func TestUnmarshalTransaction(t *testing.T) {
 	}
 }
 
+func TestMarshalTransaction(t *testing.T) {
+	for name, test := range unmarshalTransactionTests {
+		if test.wantError != nil {
+			continue
+		}
+		var original *Transaction
+		json.Unmarshal([]byte(test.input), &original)
+
+		blob, err := json.Marshal(original)
+		if err != nil {
+			t.Errorf("test %q: failed to marshal transaction: %v", name, err)
+			continue
+		}
+		var proced *Transaction
+		if err := json.Unmarshal(blob, &proced); err != nil {
+			t.Errorf("Test %q: failed to unmarshal marhsalled transaction: %v", name, err)
+			continue
+		}
+		proced.Hash() // hack private fields to pass deep equal
+		if !reflect.DeepEqual(original, proced) {
+			t.Errorf("test %q: transaction mismatch: have %+v, want %+v", name, proced, original)
+			continue
+		}
+	}
+}
+
 var unmarshalReceiptTests = map[string]struct {
 	input     string
 	wantError error
@@ -119,6 +171,31 @@ func TestUnmarshalReceipt(t *testing.T) {
 	}
 }
 
+func TestMarshalReceipt(t *testing.T) {
+	for name, test := range unmarshalReceiptTests {
+		if test.wantError != nil {
+			continue
+		}
+		var original *Receipt
+		json.Unmarshal([]byte(test.input), &original)
+
+		blob, err := json.Marshal(original)
+		if err != nil {
+			t.Errorf("test %q: failed to marshal receipt: %v", name, err)
+			continue
+		}
+		var proced *Receipt
+		if err := json.Unmarshal(blob, &proced); err != nil {
+			t.Errorf("Test %q: failed to unmarshal marhsalled receipt: %v", name, err)
+			continue
+		}
+		if !reflect.DeepEqual(original, proced) {
+			t.Errorf("test %q: receipt mismatch: have %+v, want %+v", name, proced, original)
+			continue
+		}
+	}
+}
+
 func checkError(t *testing.T, testname string, got, want error) bool {
 	if got == nil {
 		if want != nil {
diff --git a/core/types/receipt.go b/core/types/receipt.go
index 9f820eb18add6e71500634cf42899c12a738853b..b00fdabff6f463348e047161a5ca78183fdcbdc4 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -84,6 +84,21 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
 	return nil
 }
 
+// MarshalJSON encodes receipts into the web3 RPC response block format.
+func (r *Receipt) MarshalJSON() ([]byte, error) {
+	root := common.BytesToHash(r.PostState)
+
+	return json.Marshal(&jsonReceipt{
+		PostState:         &root,
+		CumulativeGasUsed: (*hexBig)(r.CumulativeGasUsed),
+		Bloom:             &r.Bloom,
+		Logs:              &r.Logs,
+		TxHash:            &r.TxHash,
+		ContractAddress:   &r.ContractAddress,
+		GasUsed:           (*hexBig)(r.GasUsed),
+	})
+}
+
 // UnmarshalJSON decodes the web3 RPC receipt format.
 func (r *Receipt) UnmarshalJSON(input []byte) error {
 	var dec jsonReceipt
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 5bb599479b4b5307ea92b52f7f9af0bb40c65bb0..f0512ae7e7c92cada70bd699c276a11153b1f0c1 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -128,6 +128,24 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
 	return err
 }
 
+// MarshalJSON encodes transactions into the web3 RPC response block format.
+func (tx *Transaction) MarshalJSON() ([]byte, error) {
+	hash, v := tx.Hash(), uint64(tx.data.V)
+
+	return json.Marshal(&jsonTransaction{
+		Hash:         &hash,
+		AccountNonce: (*hexUint64)(&tx.data.AccountNonce),
+		Price:        (*hexBig)(tx.data.Price),
+		GasLimit:     (*hexBig)(tx.data.GasLimit),
+		Recipient:    tx.data.Recipient,
+		Amount:       (*hexBig)(tx.data.Amount),
+		Payload:      (*hexBytes)(&tx.data.Payload),
+		V:            (*hexUint64)(&v),
+		R:            (*hexBig)(tx.data.R),
+		S:            (*hexBig)(tx.data.S),
+	})
+}
+
 // UnmarshalJSON decodes the web3 RPC transaction format.
 func (tx *Transaction) UnmarshalJSON(input []byte) error {
 	var dec jsonTransaction
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 50346f6aecb851c2853a1c49e7dfef8a4419f7e8..ffa8228cc1810090f758359562c9d50ba6398297 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -227,7 +227,7 @@ func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, err
 // SubscribeNewHead subscribes to notifications about the current blockchain head
 // on the given channel.
 func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) {
-	return ec.c.EthSubscribe(ctx, ch, "newBlocks", map[string]struct{}{})
+	return ec.c.EthSubscribe(ctx, ch, "newHeads", map[string]struct{}{})
 }
 
 // State Access